วิธีหลีกเลี่ยงการซ้อนความเร็วในการเคลื่อนไหวเมื่อกดปุ่มหลาย ๆ ปุ่ม?


17

ฉันได้เริ่มเกมใหม่ที่ไม่ต้องใช้เม้าส์ ฉันพยายามรวม 8 ทิศทาง; ขึ้น, ซ้าย, ขวา, ขึ้น - ขวาเป็นต้น อย่างไรก็ตามเมื่อฉันกดปุ่มลูกศรมากกว่าหนึ่งปุ่มความเร็วในการเคลื่อนที่จะซ้อนกัน ( http://gfycat.com/CircularBewitchedBarebirdbat ) ฉันจะต่อต้านสิ่งนี้ได้อย่างไร

นี่คือส่วนที่เกี่ยวข้องของรหัสของฉัน:

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
แทนเจนต์: รอยเว้าในโค้ดของคุณยุ่งเล็กน้อยดังนั้นฉันจึงไม่ได้สังเกตในตอนแรก แต่เงื่อนไขในโค้ดของคุณจะป้องกันไม่ให้ส่วนใหญ่ทำงานได้ เช่นถ้า (UpArrow) หากอื่น (UpArrow && RightArrow) จะไม่เปิดสาขา 'else'
jhocking

คำตอบ:


13

แยกรหัสการเลือกทิศทางของคุณออกจากรหัสการเคลื่อนไหวจริง

  1. เลือกDirectionโดยตรวจสอบว่ากดคีย์ใด เก็บไว้เป็นเวกเตอร์หน่วย (ปกติ)
  2. คูณของคุณDirectionด้วยและSpeedDeltaTime
  3. ใช้การแปลงผลลัพธ์กับวัตถุ / กล้องของคุณ

27

คุณจำเป็นต้องหาผลรวมของทิศทางทำให้เป็นมาตรฐานแล้วคูณด้วยความเร็ว

ฉันตอบคำถามนี้เป็นส่วนหนึ่งของการตอบสนองต่อการป้องกันการเคลื่อนไหวในแนวทแยง

โดยเฉพาะ:

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
เฮ้ Larry จะภูมิใจ! c2.com/cgi/wiki?LazinessImpatienceHubris
jzx

3
โปรดทราบว่า Unity มีวิธีการในการรับขนาดและกำลังสองของเวกเตอร์
Selali Adobor

1
สิ่งนี้จะสร้าง NaN หากไม่มีการกดคีย์
CodesInChaos

1
@jzx แน่นอนเรามุ่งมั่นที่จะเป็นฮอบบิทที่โกหก youtube.com/watch?v=G49RUPv5-NU
Pharap

11

"เวกเตอร์ทิศทางปกติ" เป็นวิธีการที่งานนี้มักจะเข้าใกล้และวิธีที่ฉันมักจะทำ แต่เมื่อเร็ว ๆ นี้ฉันเพิ่งได้รับการยึดเวกเตอร์การเคลื่อนไหวที่เกิดขึ้น โดยปกติแล้วจะได้ผลลัพธ์ที่เหมือนกันและรหัสนั้นง่ายกว่ามาก:

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

รหัสที่เรียบง่ายนั้นดีกว่า: E


มันClampMagnitudeทำอะไรไม่ได้รหัสเดียวกับที่Normalize * Constantไม่ได้ทำ?
Kromster กล่าวว่าสนับสนุน Monica

2
ไม่มาก "การหนีบ" ค่าทำให้แน่ใจว่ามันอยู่ในช่วง / ต่ำกว่าค่าสูงสุดในขณะที่การทำให้ค่ามาตรฐานเป็นค่าคงที่ ด้วย Unity อย่างน้อย GetAxis () จะคืนค่าการเร่งความเร็วเล็กน้อยเพื่อให้คุณเคลื่อนไหวได้ราบรื่นขึ้น การทำให้เวกเตอร์แทนที่ความเร่งที่ปกติในขณะที่การหนีบช่วยให้การเร่งความเร็วเกิดขึ้น มันบอบบาง แต่ก็ดูดีกว่า ผลสุดท้ายก็เหมือนกันมาก
jhocking

1
+1 สำหรับการเป็นคำตอบเดียวที่เขียนโดยตรงในบริบทของความสามัคคี API นำเสนอวิธีการทางคณิตศาสตร์ที่มีประโยชน์ทุกประเภทโดยคำนึงถึงสถานการณ์เช่นนี้โดยไม่มีเหตุผลที่จะทำให้คุณมีปัญหา
Selali Adobor

ฉันยึด 1 และมีเพียงคูณด้วยหลังจากที่หนีบและอาจจะรวมกับการคูณโดยmoveSpeed deltaTime
CodesInChaos

การเปลี่ยนแปลงนั้นได้รับมากกว่าเพียงแค่ลบการดำเนินการคูณเดียวหรือไม่? เช่นเดียวกับที่หนีบ 1 ทำงานแตกต่างจากที่หนีบ 6 หรือไม่? สงสัยว่าสิ่งที่เปลี่ยนแปลงไม่ ...
jhocking
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.