Come evitare l'impilamento della velocità di movimento quando si premono più tasti?


16

Ho iniziato un nuovo gioco che non richiede mouse, lasciando così il movimento sulla tastiera. Ho cercato di incorporare 8 direzioni; su, sinistra, destra, su-destra e così via. Tuttavia, quando premo più di un tasto freccia, la velocità di movimento aumenta ( http://gfycat.com/CircularBewitchedBarebirdbat ). Come ho potuto contrastare questo?

Ecco una parte rilevante del mio codice:

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);
    }
}

3
tangente: il rientro nel tuo codice era un po 'incasinato, quindi all'inizio non me ne sono accorto, ma le condizioni nel tuo codice ne impediranno l'esecuzione. Ad esempio, se (UpArrow) else if (UpArrow && RightArrow) non eseguirà mai il ramo 'else'.
jhocking

Risposte:


13

Separare il codice di selezione della direzione dal codice di movimento effettivo.

  1. Scegliere Directioncontrollando quali tasti sono premuti. Conservarlo come vettore unitario (normalizzato).
  2. Moltiplica il tuo Directioncon Speede con DeltaTime.
  3. Applica la trasformazione risultante al tuo oggetto / videocamera.

27

Devi prendere la somma delle direzioni, normalizzarla, quindi moltiplicare per la velocità.

Ho risposto tangenzialmente a questo come parte della mia risposta alla prevenzione del movimento diagonale

In particolare:

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;

3
Heheh, Larry sarebbe orgoglioso! c2.com/cgi/wiki?LazinessImpatienceHubris
jzx

3
Si noti che Unity fornisce già metodi per ottenere la grandezza e la grandezza quadrata di un vettore.
Selali Adobor,

1
Questo produce NaN se non viene premuto alcun tasto
CodesInChaos

1
@jzx In effetti, ci sforziamo di essere come i favolosi Hobbit. youtube.com/watch?v=G49RUPv5-NU
Pharap

11

Il "vettore di direzione normalizzato" è il modo in cui questo compito viene generalmente affrontato e il modo in cui lo faccio spesso, ma ultimamente ho semplicemente bloccato il vettore di movimento risultante. Di solito ottiene lo stesso risultato finale e il codice è molto più semplice:

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);
}

Il codice più semplice è quasi sempre migliore: E


Che cosa ClampMagnitudefa, non è lo stesso codice Normalize * Constantdi inquise?
Kromster dice di sostenere Monica il

2
Non proprio. "Bloccando" un valore si assicura che rimanga entro un intervallo / inferiore al massimo, mentre la normalizzazione imposta il valore su una costante. Almeno con Unity, GetAxis () restituisce valori leggermente accelerati, offrendo un movimento più fluido. La normalizzazione del vettore annulla tale accelerazione, mentre il bloccaggio consente l'accelerazione. È sottile ma sembra più bello. L'effetto finale è praticamente lo stesso però.
jhocking

1
+1 per essere l'unica risposta scritta direttamente nel contesto di Unity. L'API fornisce tutti i tipi di utili metodi matematici Vector / Quaternion con questo tipo di situazione in mente, nessun motivo per andare avanti.
Selali Adobor,

Bloccerei a 1 e moltiplicerei solo con moveSpeeddopo il serraggio e possibilmente lo fonderei con la moltiplicazione per deltaTime.
Codici A Caos il

Quel cambiamento guadagna più della semplice rimozione di un'operazione di moltiplicazione? Ad esempio, il bloccaggio 1 funziona in modo diverso dal bloccaggio 6? chiedendomi cosa fa il tuo cambiamento ...
jhocking
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.