Jak dokonać opóźnionego wprowadzania myszy?

11

Mam grę samochodową i pomysł polega na tym, że gracz jest pijany. Chcę mieć opóźnione wejście z myszy, gdzie przesuwasz mysz na boki, aby się obrócić.

Jak ustawić stałe opóźnienie między danymi wejściowymi podawanymi przez użytkownika a liczbą obrotów samochodu?

Teraz mam to:

h = Mathf.Lerp(h, (((Input.mousePosition.x / Screen.width) * 2) - 1), Time.deltaTime * 2);

Co się dzieje, zwrot jest opóźniony, ale jest bardzo wolny, innymi słowy, jeśli poruszę myszką bardzo szybko, samochód obraca się bardzo powoli, ale jeśli zwiększę mnożnik Time.deltaTime, samochód obraca się szybciej, ale efekt opóźnienia jest zminimalizowany .

Jak inaczej mogę to zrobić?

mr-matt
źródło

Odpowiedzi:

31

Aby zasymulować opóźnienie czasowe, użyj okrągłego bufora do przechowywania pozycji myszy w ostatnich N klatkach. Zapisz bieżącą pozycję myszy w każdej klatce. W obliczeniach kontrolnych używaj najstarszej pozycji myszy z bufora zamiast bieżącej pozycji myszy.

Buster
źródło
1
Właściwie to rozwiązałem, po prostu użyłem coroutine z funkcją waitforseconds. Byłbym zaniepokojony wydajnością tej techniki, jeśli masz naprawdę szybkie urządzenie, miałoby ono znacznie krótszy czas opóźnienia niż coś takiego jak telefon komórkowy.
mr-matt
2
Zauważ, że opóźnienie wejścia takie jak to zmieni wynik w zależności od częstotliwości odpytywania.
Joey
6
Matthew, jestem trochę oszołomiony ... czy naprawdę masz na myśli występ? Spadek wydajności związany z zapisem kilku bajtów do pamięci na ramkę jest całkowicie znikomy, a pozycja myszy jest wolna z każdą wiadomością (przynajmniej w systemie Windows). Jak myślisz, jak dokładnie działa twoje coroutine? Kto śledzi, ile timerów istnieje, kiedy wygasają i jaki kod wykonać? Brzmi dość ciężko.
Buster
O nie, nie mam na myśli wykonania rzeczywistego zadania opóźnienia, mam na myśli ogólną wydajność. Na przykład, jeśli wezmę pozycję myszy z ostatnich 10 klatek i uruchomię to na telefonie i uzyskam 20 fps, opóźnienie wyniesie 0,5 sekundy. Jeśli jednak uruchomię to na pulpicie i uzyskam 200 fps, opóźnienie wyniesie tylko 0,05 sekundy. Rozumuiesz, co mam na myśli?
mr-matt
Wybrałbyś N, aby tego uniknąć, ale większym problemem jest to, że odpytywanie raz na klatkę w ten sposób wyrzuca wiele danych. Lepiej poradzić sobie z każdym zdarzeniem myszy (wygląda na to, że robi to Twoja odpowiedź).
Buster
3

Skończyło się na tym, że użyłem coroutine, ponieważ (z tego co rozumiem) opóźnienie będzie stałe bez względu na wydajność urządzenia z uruchomioną grą.

To jest mój kod:

private IEnumerator DelayedInput()
{
    Vector3 a = Input.acceleration;
    Vector2 m = Input.mousePosition;

    yield return new WaitForSeconds(delay);

    accelerometer = Vector3.Lerp(accelerometer, a, Time.deltaTime * turnSpeed);
    mouse = Vector2.Lerp(mouse, m, Time.deltaTime * turnSpeed);
}
mr-matt
źródło
Ma to tę zaletę, że odpowiada na wszystkie dane wejściowe (nie tak jak mój pomysł odpytywania każdej klatki). Nie znam C #, ale wydaje mi się, że ktoś gdzieś ma dużo do zrobienia dla tych wszystkich liczników czasu. Ale jeśli działa OK i ma ochotę, którą chcesz, to mi się podoba.
Buster
Myślę, że jest to lepszy sposób, aby to zrobić, nie sądzę, że liczniki czasu wpłyną na twoją grę, oczywiście możesz wrócić do tego pytania z wynikami swojego doświadczenia z wydajnością (do wglądu w przyszłości). W każdym razie powinieneś wybrać to jako odpowiedź (to tylko przypomnienie).
John Hamilton