การหมุน 2 ครั้งด้วย Transformer.Rotate() และ Transformer.localEulerAngles() ไม่ทำงาน

ฉันกำลังพยายามสร้างเครื่องจำลองรถแบบง่ายๆ และเมื่อฉันใช้การTransform.Rotate() เพื่อหมุนคำนำของล้อ (แกน x) และการใช้การTransform.localEulerAngles() เพื่อหมุนในทิศทางการหมุน (แกน y) เท่านั้น localEulerAngles() ใช้งานได้ เมื่อฉันใช้วิธีเดียว การหมุนคำนำวงล้อ (แกน x) ก็ใช้ได้ แต่ฉันไม่สามารถทำให้ทั้งสองวิธีทำงานได้ คุณมีแนวคิดในการทำให้พวกเขาทำงานร่วมกันได้อย่างไร?

float ro = 20f; // 20 degrees turn
//to preserve the x and z values of rotation
Vector3 rot = wheel.gameObject.transform.rotation.eulerAngles;
//rotates the wheels angle
wheel.gameObject.transform.localEulerAngles = new Vector3(rot.x, ro, rot.z);

float vel = wheel.rpm * 2 * Mathf.PI / 60 * Time.deltaTime * Mathf.Rad2Deg;
//rotates the wheels forward
wheel.gameObject.transform.Rotate(vel, 0, 0);

person hallelshohat    schedule 04.08.2019    source แหล่งที่มา


คำตอบ (2)


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

public class WheelTurning : MonoBehaviour

{

float rpm=10f;
// Start is called before the first frame update
void Start()
{

}

// Update is called once per frame
void Update()
{
    if (Input.GetKeyDown(KeyCode.A))
    {
        turn(direction.left);
    }
    if (Input.GetKeyDown(KeyCode.D))
    {
        turn(direction.right);
    }
    float vel = this.rpm * 2 * Mathf.PI / 60 * Time.deltaTime * Mathf.Rad2Deg;
    rotate(vel);
}
enum direction
{
    left,
    right
}
void turn(direction dir)
{
    Vector3 rot = this.gameObject.transform.rotation.eulerAngles;
    //rotates the wheels angle
    float rotation = dir == direction.left ? 20f : -20f;
    gameObject.transform.Rotate(new Vector3(0, rotation, 0), Space.World);
}
void rotate (float speed)
{

    gameObject.transform.Rotate(0, speed, 0);
}

}

รูปภาพอ้างอิงแกน

อย่างไรก็ตาม การใช้ควอเทอร์เนียนจะได้ผลมากกว่ามาก ลองตรวจสอบดู หวังว่าจะช่วยได้!

person rustyBucketBay    schedule 04.08.2019
comment
ลองอันนี้แล้ว แต่ปัญหาคือฉันต้องการค่าสัมบูรณ์สำหรับทิศทางการหมุน (เพื่อตั้งค่าการหมุนเป็น 20 และไม่เพิ่ม 20 เข้าไป) ดังนั้นมันจึงเริ่มหมุน แต่พวกเขาทั้งสองทำงาน - person hallelshohat; 04.08.2019
comment
ฉันไม่เข้าใจประเด็นของคุณ หากคุณต้องการหมุนวงล้อ มันก็จะเป็นไปตามตำแหน่งการหมุนก่อนหน้าเสมอ ด้วยการอ้างอิงนั้น คุณสามารถเลือกค่าที่คุณต้องการในเวกเตอร์การหมุน Vector3(0, การหมุน, 0) หากคุณต้องการการอ้างอิงแบบสัมบูรณ์ คุณสามารถสร้างออบเจ็กต์หลักและหมุนสิ่งนี้ได้ วัตถุมีแกนโลกเหมือนกัน และเมื่อหมุนหรือเปลี่ยนรูป ลูกๆ จะประสบกับการเปลี่ยนแปลงแบบเดียวกัน คุณต้องแน่ใจว่าตำแหน่งในลูกคือ 0,0,0 เนื่องจากนี่คือระยะห่างที่สัมพันธ์กับตำแหน่งแม่ที่จะเป็นจุดหมุน - person rustyBucketBay; 05.08.2019

ฉันไม่เข้าใจประเด็นของคุณ หากคุณต้องการหมุนวงล้อ มันก็จะเป็นไปตามตำแหน่งการหมุนก่อนหน้าเสมอ ด้วยการอ้างอิงนั้น คุณสามารถเลือกค่าที่คุณต้องการในเวกเตอร์การหมุน Vector3(0, การหมุน, 0) หากคุณต้องการการอ้างอิงแบบสัมบูรณ์ คุณสามารถสร้างออบเจ็กต์หลักและหมุนสิ่งนี้ได้ วัตถุมีแกนโลกเหมือนกัน และเมื่อหมุนหรือเปลี่ยนรูป เด็กๆ จะ "ทนทุกข์" ในการเปลี่ยนแปลงแบบเดียวกัน คุณต้องแน่ใจว่าตำแหน่งในลูกคือ 0,0,0 เนื่องจากนี่คือระยะห่างที่สัมพันธ์กับตำแหน่งแม่ที่จะเป็นจุดหมุน

 void setRotation()
{
    Vector3 rot = this.gameObject.transform.rotation.eulerAngles;
    GameObject wheelParent = gameObject.transform.parent.gameObject;
    Vector3 rotationVector = new Vector3(0, 30, 0);//absolute turn set
    Quaternion rotation = Quaternion.Euler(rotationVector);
    wheelParent.transform.localRotation = rotation;
}

หวังว่าจะช่วยได้

person rustyBucketBay    schedule 05.08.2019