Jak ręcznie zmienić przesuwaną kulkę w toczącą się kulkę w Unity 3D?

Aug 16 2020

Jestem w tym trochę nowy, więc każda pomoc będzie mile widziana.


Kontekst: Tworzę symulowaną grę bilardową VR i staram się, aby fizyka była jak najbardziej realistyczna. Mam bilę uderzaną kijem po powierzchni z dokładnymi wartościami tarcia obliczonymi z rzeczywistych prób.


Problem: Bila bila ślizga się dłużej niż to, co by się ślizgało w prawdziwym świecie. Realistycznie, gdy prędkość osiągnie 5/7 (~ 71%) swojej prędkości początkowej, piłka przechodzi ze ślizgu w toczenie. Jednak w Unity przejście następuje znacznie później, przy około 20-10% prędkości początkowej. (wynika to z tego, jak Unity oblicza fizykę interakcji jako punkt kontaktu, a nie obszar kontaktu)


Pytanie: Chcę to zakodować na sztywno, aby gdy bila biała straciła 5/7 swojej prędkości początkowej (przy 71% * prędkości początkowej), prędkość ślizgu jest ustawiona na 0, a bila rozgrywająca toczy się dalej od swojej prędkości kątowej. Czy teoretycznie jest to możliwe? czy też zmiana prędkości / prędkości na zero natychmiast zatrzyma ruch piłki na swoim miejscu? A jak mam to zrobić? Z góry dziękuję.

Odpowiedzi

1 Kevin Aug 18 2020 at 00:34

Wygląda na to, że powinno być możliwe, chociaż nigdy tego nie próbowałem. Poniższy kod powinien Ci tam dotrzeć. Następnie, poprzez eksperymenty, można określić, jak dostosować prędkość i prędkość kątową, aby uzyskać pożądany efekt.

private Rigidbody body;

void Start() {
    body = GetComponent<Rigidbody>();
}

void OnCollisionEnter(Collision collision) {
    StartCoroutine(SlideThenRoll());
}

IEnumerator SlideThenRoll() {
    yield return null; //wait a frame to make sure our velocity updates
    float initialSpeed = body.velocity.magnitude;
    float targetSpeed = .71 * initialSpeed;
    yield return new WaitUntil(() => body.velocity.magnitude <= targetSpeed);

    //you'll need to fill in this part
    body.velocity = //??
    body.angularVelocity = //??
}
```