Jak uniknąć ustawiania szybkości ruchu po naciśnięciu wielu klawiszy?

17

Rozpocząłem nową grę, która nie wymaga myszy, pozostawiając ruch do klawiatury. Próbowałem włączyć 8 kierunków; w górę, w lewo, w prawo, w górę w prawo i tak dalej. Jednak po naciśnięciu więcej niż jednego klawisza strzałki prędkość ruchu kumuluje się ( http://gfycat.com/CircularBewitchedBarebirdbat ). Jak mogę temu przeciwdziałać?

Oto odpowiednia część mojego kodu:

var speed : int = 5;

function Update () {
    if (Input.GetKey(KeyCode.UpArrow)) {
        transform.Translate(Vector3.forward * speed * Time.deltaTime);
    } else if (Input.GetKey(KeyCode.UpArrow) && Input.GetKey(KeyCode.RightArrow)) {
        transform.Translate(Vector3.forward * speed * Time.deltaTime);
    } else if (Input.GetKey(KeyCode.UpArrow) && Input.GetKey(KeyCode.LeftArrow)) {
        transform.rotation = Quaternion.AngleAxis(315, Vector3.up);
    }
    if (Input.GetKey(KeyCode.DownArrow)) {
        transform.Translate(Vector3.forward * speed * Time.deltaTime);
    }
}
eren_tetik
źródło
3
tangens: Wcięcie w kodzie było trochę pomieszane, więc na początku nie zauważyłem, ale warunki w kodzie uniemożliwiają uruchomienie większości z nich. Na przykład, jeśli (UpArrow) else if (UpArrow && RightArrow) nigdy nie uruchomi gałęzi „else”.
jhocking

Odpowiedzi:

13

Oddziel kod wyboru kierunku od rzeczywistego kodu ruchu.

  1. Wybierz Direction, sprawdzając, które klawisze są naciskane. Zapisz go jako wektor jednostkowy (znormalizowany).
  2. Pomnóż swój Directionprzez Speedi z DeltaTime.
  3. Zastosuj wynikową transformację do swojego obiektu / kamery.
Kromster mówi, że popiera Monikę
źródło
27

Musisz wziąć sumę wskazówek, znormalizować to, a następnie pomnożyć przez prędkość.

Stycznie odpowiedziałem na to jako część mojej odpowiedzi na Zapobieganie ruchom diagonalnym

Konkretnie:

velX = 0;
velY = 0;

if(keyLeft) velX += -1;
if(keyRight) velX += 1;
if(keyUp) velY += -1;
if(keyDown) velY += 1;

// Normalize to prevent high speed diagonals
length = sqrt((velX * velX ) + (velY * velY ));
if (length != 0)
{
    velX /= length;
    velY /= length;
}

velX *= speed;
velY *= speed;
jzx
źródło
3
Heheh, Larry byłby dumny! c2.com/cgi/wiki?LazinessImpatienceHubris
jzx
3
Zauważ, że Unity już zapewnia metody uzyskiwania wielkości i kwadratu wielkości wektora.
Selali Adobor
1
Daje to NaN, jeśli nie zostanie naciśnięty żaden klawisz
CodesInChaos
1
@ jzx Rzeczywiście, staramy się być jak legendarni hobbici. youtube.com/watch?v=G49RUPv5-NU
Pharap
11

„Znormalizowany wektor kierunku” to sposób, w jaki zwykle wykonuje się to zadanie i jak często to robię, ale ostatnio po prostu zaciskam wynikowy wektor ruchu. Zwykle osiąga ten sam efekt końcowy, a kod jest o wiele prostszy:

var moveSpeed = 6.0f;
function Update() {
  var movement = Vector3.zero;
  movement.x = Input.GetAxis("Horizontal") * moveSpeed;
  movement.z = Input.GetAxis("Vertical") * moveSpeed;
  movement = Vector3.ClampMagnitude(movement, moveSpeed);
  movement *= Time.deltaTime;
  transform.Translate(movement);
}

Prostszy kod jest prawie zawsze lepszy: E

jhocking
źródło
Co robi ClampMagnitude, czy nie jest to ten sam kod, co Normalize * Constantw dyskursie?
Kromster mówi o wsparciu Moniki
2
Nie do końca. „Clamping” wartość zapewnia, że ​​pozostaje w zakresie / poniżej maksimum, podczas gdy normalizacja ustala wartość na stałą. Przy pomocy Unity GetAxis () zwraca nieznacznie przyspieszające wartości, zapewniając płynniejszy ruch. Normalizacja wektora zastępuje to przyspieszenie, a zaciskanie umożliwia przyspieszenie. Jest subtelny, ale wygląda ładniej. Efekt końcowy jest jednak prawie taki sam.
jhocking
1
+1 za bycie jedyną odpowiedzią napisaną bezpośrednio w kontekście Jedności. Interfejs API zapewnia wszelkiego rodzaju użyteczne metody matematyczne Vector / Quaternion, mając na uwadze tego rodzaju sytuację, nie ma powodu, aby stosować własne.
Selali Adobor
Skasowałbym do 1 i moveSpeedpomnożyłbym tylko po zaciśnięciu i ewentualnie scaliłbym to przez pomnożenie przez deltaTime.
CodesInChaos
Czy ta zmiana zyskuje więcej niż tylko usunięcie jednej operacji mnożenia? Na przykład, czy zacisk 1 działa inaczej niż zacisk 6? zastanawiam się, co robi twoja zmiana ...
jhocking