Come far scivolare uniformemente il giocatore contro il terreno


11

diagramma

Sto realizzando un gioco isometrico. Quando il giocatore cerca di camminare in diagonale contro un muro, voglio che scivolino dolcemente attraverso di esso, quindi viene utilizzata qualunque parte del movimento sia legale e qualsiasi cosa nella direzione del normale viene gettata via. Le pareti possono avere qualsiasi angolo, non solo verticale o orizzontale, e il giocatore ha un movimento a 360 °.

Mi sento quasi arrivato, ma non riesco a mettere a posto l'ultimo pezzo.

Aggiornamento: grandi novità a tutti! Ho funzionato. Ma ... sono un po 'confuso su cosa dovrei normalizzare e cosa no. Il normale deve solo essere un vettore unitario, giusto? ma poi lo sto mescolando con il mio input, quindi lo sto normalizzando - sbaglio?

A proposito, ho anche scoperto che devo spingere il giocatore di 1 pixel nella direzione del normale, in modo che non rimangano bloccati sulle cose - funziona bene.

Risposte:


13

Proiettate semplicemente il vostro vettore di movimento sul piano normale e quindi sottraggete il risultato dal vostro vettore di movimento.

Vector undesiredMotion = normal * (dotProduct(input, normal));
Vector desiredMotion = input - undesiredMotion;

Qualcosa del genere comunque. Anche se nel tuo bel diagramma l'ingresso sembra essere lontano dal muro, quindi sono leggermente confuso.


mi dispiace che dovrebbe essere di fronte a un muro verticale lì. disegno terribile
Iain,

1
Sono un po 'confuso sul prodotto dot. Il prodotto dot non è uno scalare?
Iain,

1
Sì, ma lo moltiplichi per il normale (un vettore) per ottenere il vettore del tuo movimento indesiderato. Un vettore (x, y, z) moltiplicato per lo scalare s ti dà il vettore (sx, sy, sz).
Chris Howe,

Fatto, ho cambiato le variabili per far combaciare il diagramma. :)
Chris Howe,

@Iain Sto davvero cercando di capire come usare questa risposta ma non riesco a coglierla. Quando creo questo codice esatto ottengo desiredMotionrisultati davvero strani . L'hai mai fatto funzionare?
prova il

1

Mentre è semplice rimuovere semplicemente il componente del movimento che è nella direzione del normale, può invece adattarsi al tuo gameplay per ruotare il vettore di movimento. Ad esempio, in un gioco d'azione in terza persona, potrebbe essere facile rimanere leggermente appesi alle pareti e ad altri confini, in modo da poter fare delle ipotesi su ciò che il giocatore intende.

// assume that 'normal' is unit length
Vector GetDesired(Vector input, Vector normal) {
   // tune this to get where you stop when you're running into the wall,
   // vs. bouncing off of it
   static float k_runningIntoWallThreshold = cos(DEG2RAD(45));

   // tune this to "fudge" the "push away" from the wall
   static float k_bounceFudge = 1.1f;

   // normalize input, but keep track of original size
   float inputLength = input.GetLength();
   input.Scale(1.0f / inputLength);

   float dot = DotProduct(input, normal);

   if (dot < 0)
   {
      // we're not running into the wall
      return input;
   }
   else if (dot < k_runningIntoWallThreshold)
   {
      Vector intoWall = normal.Scale(dot);
      intoWall.Scale(k_bounceFudge);

      Vector alongWall = (input - intoWall).Normalize();
      alongWall.Scale(inputLength);

      return alongWall;
   }
   else
   {
      // we ran "straight into the wall"
      return Vector(0, 0, 0);
   }
}

Bello. Ma se si scala in base a un fattore di sfumatura, ciò ti fa urtare lungo il muro invece di scivolarvi lungo, o è solo un caso per modificarlo?
Chris Howe,

Il mio pensiero è che lo modifichi per sembrare ok; certamente se è troppo grande sembrerà che tu rimbalzi ma se è abbastanza sottile ti impedirà di rimanere appeso a lievi curve in superficie.
dash-tom-bang,
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.