วิธีใช้ Input.GetAxis (“ Mouse X / Y”) เพื่อหมุนกล้อง


13

ฉันต้องการสร้างกล้องคนแรกที่หมุนด้วยเมาส์

ฉันดูที่หน้าInput.GetAxis Scripting API และพบรหัสตัวอย่างซึ่งฉันได้รวมไว้ที่ด้านล่างของโพสต์ของฉัน เมื่อลองใช้งานฉันรู้ว่าแม้ว่ามันจะมีฟังก์ชั่นพื้นฐานแบบเดียวกับที่ฉันหวังไว้ แต่ก็ไม่ได้ทำให้กล้องขนานกับระนาบ xz โดยเฉพาะเมื่อเลื่อนเมาส์เป็นวงกลม หลังจากนั้นไม่นานกล้องก็จะทำมุมแปลก ๆ และผู้เล่นจะไม่ถูกรวบรวมอย่างสมบูรณ์!

มีการแก้ไขอย่างรวดเร็วของรหัสนี้ที่จะ จำกัด การเคลื่อนไหวของกล้องอย่างใดหรือมีวิธีที่ดีกว่าในการหมุนกล้อง?

 using UnityEngine;
 using System.Collections;

     public class ExampleClass : MonoBehaviour {
         public float horizontalSpeed = 2.0F;
         public float verticalSpeed = 2.0F;
         void Update() {
             float h = horizontalSpeed * Input.GetAxis("Mouse X");
             float v = verticalSpeed * Input.GetAxis("Mouse Y");
             transform.Rotate(v, h, 0);
         }
     }

สิ่งที่คุณกำลังประสบกับเสียงเช่นล็อก gimbal มันเกิดขึ้นเมื่อคุณใช้มุมออยเลอร์สำหรับการหมุน ฉันต้องทำการทดสอบเพื่อเสนอทางออก โดยทั่วไปคุณต้องใช้ quaternions พวกเขาไม่ต้องทนทุกข์ทรมานจากการล็อก gimbal
Fuzzy Logic

ฉันจะใช้ quaternion เพื่อหมุนได้อย่างไร ฉันลอง transform.rotation = Quaternion.Slerp (-Input.GetAxis ("Mouse X"), Input.GetAxis ("Mouse X"), Time.deltaTime * freeLookTurningSpeed); แต่นั่นทำให้ฉันมีข้อผิดพลาด
กลับชาติมาเกิดของแลกเปลี่ยนที่

ตกลงฉันทำแบบทดสอบ โชคดีที่มันไม่ได้ล็อคด้วยระบบ gimbal ฉันจะโพสต์โซลูชันเป็นคำตอบสำหรับคุณ
Fuzzy Logic

คำตอบ:


18

ปัญหาคือคุณกำลังอัปเดตการหมุนเวียนที่มีอยู่แทนที่จะติดตามด้วยตัวคุณเองและแทนที่การอัพเดทแต่ละครั้ง

เมื่อคุณอัปเดตการหมุนมันจะรวมการหมุนใหม่ของคุณเข้ากับการหมุนเก่าซึ่งนำไปสู่พฤติกรรมที่ไม่คาดคิด

วิธีแก้ไขคือการติดตามการหมุนเวียนสะสมของคุณและรีเซ็ตการหมุนเวียนทั้งหมดในการอัปเดตด้วยค่าใหม่ของคุณ

เครดิตที่ถึงกำหนดฉันพบคำตอบได้ที่นี่: Unity Answers: วิธีล็อคหรือตั้งค่ากล้อง -z-rotation-to-zero

รหัสการทำงาน:

using UnityEngine;
using System.Collections;

public class FirstPersonCam : MonoBehaviour {

    public float speedH = 2.0f;
    public float speedV = 2.0f;

    private float yaw = 0.0f;
    private float pitch = 0.0f;

    void Update () {
        yaw += speedH * Input.GetAxis("Mouse X");
        pitch -= speedV * Input.GetAxis("Mouse Y");

        transform.eulerAngles = new Vector3(pitch, yaw, 0.0f);
    }
}

ความแตกต่างที่สำคัญ:

  • จัดเก็บ yaw และ pitch ในฐานะสมาชิกคลาสแทนที่จะเป็นตัวแปรวิธีโลคอลเพื่อให้คุณสามารถติดตามค่าสะสม
  • ใช้ + = และ / หรือ - = เพื่อรวบรวมการอัปเดตแต่ละรายการ
  • ใช้ eulerAngles (เพื่อเขียนทับค่าการหมุนแต่ละการอัปเดต) แทนการหมุน (ซึ่งใช้การหมุนใหม่ของคุณไปยังอันเก่า)

ยินดีต้อนรับ. หากวิธีนี้ฉันโพสต์แก้ไขปัญหาเดิมที่คุณมีคุณควรยอมรับว่ามันเป็นคำตอบ หากคุณต้องการรับความช่วยเหลือเกี่ยวกับปัญหาใหม่ของคุณคุณควรโพสต์คำถามใหม่เพื่อให้สิ่งต่าง ๆ เป็นระเบียบและมีแนวโน้มมากขึ้นที่คนอื่นจะสามารถช่วยคุณหรือค้นหาคำถามของคุณหากพวกเขามีปัญหาที่คล้ายกัน พื้นที่แสดงความคิดเห็นไม่ได้มีไว้สำหรับโต้ตอบแบบขยาย ไชโย
Fuzzy Logic

0

จะทำอย่างไรถ้าคุณทำให้เด็กเป็นกล้องเกมเปล่า จากนั้นด้วยสคริปต์หนึ่งตัวคุณจะจัดการการหมุน gameobject ว่าง ๆ ที่สัมพันธ์กับ UP vector (MouseX) ด้วยสคริปต์อื่นที่แนบกับ gameobject ของกล้องคุณจะจัดการการหมุนเมื่อเทียบกับ Right vector (MouseY)

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