Local and global coordinate system.

huangapple go评论65阅读模式
英文:

Local and global coordinate system

问题

Translation from local to global coordinate system using transform.TransformDirection(movement) means converting a movement vector from the local space of the object (in this case, your character) to the global space of the game. In Unity, objects have their own local coordinate systems based on their rotation, position, and scale. When you move an object using local space, the movement is relative to the object's own orientation.

In your provided code, when you use transform.TransformDirection(movement), you are converting the movement vector from the object's local space to the global space. This is important because other game objects or systems usually operate in the global space. It ensures that the movement is applied in the global direction, regardless of the object's rotation or orientation.

Regarding mouse rotation, the code you provided handles both local and global rotation depending on the context. For example, in the MouseX case, the rotation is applied around the global Y-axis (transform.Rotate(0, Input.GetAxis("Mouse X") * sensitivityHor, 0)), while in the MouseY and default cases, the rotation is applied locally around the object's X-axis, and then the object is rotated globally around the Y-axis.

In summary, translating from local to global coordinates ensures that movements are consistent and meaningful in the game world, regardless of the object's orientation. Mouse rotation can be handled both locally and globally based on the specific axis of rotation you want to achieve.

I hope this clarifies your doubts! Let me know if you need further assistance.

英文:

I've started to learn Unity and I'm not sure how local and global coordinates work. I have two scripts.

First (responsible for character movement (A,W,S,D)):

public class Move : MonoBehaviour
{ 
    // Start is called before the first frame update public float speed = 6.0f; private CharacterController _charController; public float gravity = -9.8f;
    // Update is called once per frame

    void Start()
    {
        _charController = GetComponent<CharacterController>();
    }

    void Update()
    {
        float deltaX = Input.GetAxis("Horizontal") * speed;
        float deltaZ = Input.GetAxis("Vertical") * speed;
        Vector3 movement = new Vector3(deltaX, 0, deltaZ);
        movement = Vector3.ClampMagnitude(movement, speed);
        movement.y = gravity;
        movement *= Time.deltaTime;
        //movement = transform.TransformDirection(movement);
        _charController.Move(movement);
    } 
}

And second (mouse rotation):

public class MouseLook : MonoBehaviour
{ 
    public enum RotationAxes {MouseXAndY = 0, MouseX = 1, MouseY = 2 }    

    public RotationAxes axes = RotationAxes.MouseXAndY; 

    public float sensitivityHor = 9.0f; 
    public float sensitivityVert = 9.0f; 

    private float _rotationX = 0; 

    public float minimumVert = -900f; 
    public float maximumVert = 900f;

    void Start()
    {
        Rigidbody body = GetComponent<Rigidbody>();

        if (body != null)  
            body.freezeRotation = true;
    }

    void Update()
    {
        if (axes == RotationAxes.MouseX)
        {
            transform.Rotate(0, Input.GetAxis("Mouse X") * sensitivityHor, 0);
        }
        else if (axes == RotationAxes.MouseY)
        {
            _rotationX -= Input.GetAxis("Mouse Y") * sensitivityVert;
            _rotationX = Mathf.Clamp(_rotationX, minimumVert, maximumVert);
            float rotationY = transform.localEulerAngles.y;
            transform.localEulerAngles = new Vector3(_rotationX, rotationY, 0);
        }
        else
        {
            _rotationX  -= Input.GetAxis("Mouse Y") * sensitivityVert;
            _rotationX = Mathf.Clamp(_rotationX, minimumVert, maximumVert);
            float delta = Input.GetAxis("Mouse X") * sensitivityHor;  
            float rotationY = transform.localEulerAngles.y + delta;  
            transform.localEulerAngles = new Vector3(_rotationX, rotationY, 0);
        }
    }
}

It is not clear to me exactly how the local and global coordinate systems work and interact here. What exactly happens when we translate from local to global coordinate system

movement = transform.TransformDirection(movement);

How my mouse rotation works here is also not entirely clear. As I see it, it's in local coordinate system, so how does the code work so that when you turn the mouse, you will move straight ahead depending on where you turn it?

In summary, I don't understand how translation from the local to global coordinate system works here, how these coordinate systems work by themselves, and why translate from one to the other at all? And how dependency works: which way you turn the mouse, that's where you go straight.

The book I'm reading now doesn't seem to have explained it very well, so I'm hoping for some help.

答案1

得分: 1

本地计算是相对于正在计算的对象的,而全局(或“世界”)计算始终固定在世界上。例如,假设您是游戏中的角色;您站在海滩上,面向东方,朝着大海。您自己的Z轴正向将面向东方,但世界的Z轴正向始终朝向北方,无论您面向哪个方向,就像一个指南针。所以:世界 = 固定常数,本地 = 相对于您。您根据需要使用它们 - 例如,如果您要编写一个使汽车前进的脚本,您可能会使用本地 transform.forward,因为您希望汽车朝着汽车面朝的方向前进。如果您希望某物指向北方,您可能会使用世界 Vector3(0, 0, 1),因为它是一个固定点。

从您的脚本中很难确定您需要哪个,但您几乎肯定应避免直接分配旋转,例如 localEulerAngles =,而应使用内置方法,例如 transform.rotation =(https://docs.unity3d.com/ScriptReference/Transform.html)。

英文:

Local calculations are relative to the object they're being calculated for, while global (or world) calcs are always fixed to the world. For example, lets say you were a character in your game; you're on a beach and facing east, towards the sea. Your own Z forward would face east, but the world's Z forward always faces north, regardless of what direction you're facing, like a compass. So: world = fixed constant, local = relative to you. You use these as required - for example if you were scripting a car to go forward you'd probably use local transform.forward because you want to go in whatever the direction the car is facing. If you wanted something to point north you'd probably use world Vector3(0, 0, 1) because it's a fixed point.

It's hard to tell from your script which you need but you should almost certainly avoid assigning rotations directly e.g. localEulerAngles = in favour of the built in methods e.g. transform.rotation = (https://docs.unity3d.com/ScriptReference/Transform.html).

huangapple
  • 本文由 发表于 2023年5月18日 03:11:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/76275485.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定