Cara membuat pemain meluncur dengan lancar ke medan

11

diagram

Saya membuat game isometrik. Ketika pemain mencoba berjalan secara diagonal ke dinding, saya ingin mereka meluncur dengan mulus di atasnya, jadi bagian mana pun dari gerakan yang legal akan digunakan, dan segala sesuatu ke arah yang normal dibuang. Dinding bisa berupa sudut apa saja, bukan hanya vertikal atau horizontal, dan pemain memiliki 360 gerakan.

Aku merasa seperti hampir sampai di sana, tetapi aku tidak bisa menempatkan potongan terakhir pada tempatnya.

Perbarui: semua orang berita hebat! Saya membuatnya bekerja. Tapi ... Saya agak bingung apa yang harus saya normalkan dan apa yang tidak. Normal hanya perlu vektor satuan, bukan? tapi kemudian saya mencampurnya dengan input saya jadi saya menormalkan itu - apakah saya salah?

By the way, saya juga menemukan bahwa saya perlu mendorong pemain 1 pixel ke arah normal, sehingga mereka tidak terjebak pada hal-hal - berfungsi dengan baik.

Iain
sumber

Jawaban:

13

Proyeksikan vektor gerak Anda ke bidang normal dan kemudian kurangi hasilnya dari vektor gerakan Anda.

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

Sesuatu seperti itu. Meskipun dalam diagram Anda yang cantik, inputnya nampaknya jauh dari dinding jadi saya sedikit bingung.

Chris Howe
sumber
maaf dia seharusnya di depan dinding vertikal di sana. gambar mengerikan
Iain
1
Saya agak bingung tentang produk titik. Bukankah dot produk skalar?
Iain
1
Ya, tetapi Anda kalikan dengan normal (vektor) untuk mendapatkan vektor gerakan yang tidak diinginkan. Vektor (x, y, z) dikalikan dengan skalar memberi Anda vektor (sx, sy, sz).
Chris Howe
Selesai, ubah variabel agar mudah-mudahan cocok dengan diagram. :)
Chris Howe
@ Ya, saya benar-benar mencoba memahami bagaimana menggunakan jawaban ini, tetapi sepertinya saya tidak dapat memahaminya. Ketika saya membuat kode persis ini saya mendapatkan desiredMotionhasil yang sangat aneh . Apakah Anda pernah berhasil ini?
Tes
1

Meskipun lurus ke depan untuk hanya menghapus komponen gerakan yang ada di arah normal, itu mungkin cocok dengan gameplay Anda untuk memutar vektor gerakan. Misalnya, dalam game aksi orang ketiga, mungkin mudah untuk sedikit menggantung di dinding dan batas lainnya, sehingga Anda bisa menebak apa yang diinginkan pemain.

// 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);
   }
}
dash-tom-bang
sumber
Bagus. Tetapi jika Anda mengukur dengan faktor fudge apakah itu membuat Anda menabrak dinding vs meluncur di sepanjang itu, atau itu hanya kasus tweaker?
Chris Howe
Pikir saya adalah bahwa Anda mengubahnya agar terlihat ok; tentu saja jika terlalu besar itu akan terlihat seperti Anda memantul tetapi jika itu cukup halus itu hanya akan membuat Anda tidak terpaku pada sedikit lengkungan di permukaan.
dash-tom-bang