유니티 에디터에서 어느 오브젝트의 인스펙터에서 트랜스폼을 보면
Position과 Rotation이 있다.
기본적으로 이 표시되는 두 값은 부모와의 상대적인 값들이며 부모에 영향을 받는다.
여러 테스트를 해보며 Position과 Rotation의 연산에 큰 차이가 있다는 걸 알았다.
부모 오브젝트의 앞을 z축, 위를 y축 오른쪽을 x축으로 하는 좌표계에서 부모 오브젝트를 원점으로 하여 상대 위치
좌표계(O) + 상대적 양(위치)
부모 오브젝트의 회전에 상대적 회전
좌표계(X) + 상대적 양(회전). 좌표계에 대한 얘기가 없음
object.localPosition += Vector3.forward; 와
object.position += Vector3.forward; 는 명백히 직관적으로 다르다는 걸 알 수 있다
Vector3.forward 값이 어느 좌표 계인지에 따라 World Space로 변환했을 때 값이 달라진다
하지만 회전에서는 그렇지 않다.
object.localRotation *= rotation; 와
object.rotation *= rotation; 는 결과적으로 같다
하나의 좌표계로만 연산되는 것 같다.(아마도 그 오브젝트의 forward, up, right를 축으로 하는 것 같다)
생각해보면 child.rotation = parent.rotation * child.localRotation; 이니까.
rotation에 직접 적용하나거나 localRotation에 적용하고 rotation에 간접적으로 적용되거나 결과적으로 같음
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class AngleAxisTest : MonoBehaviour
{
// Start is called before the first frame update
public float angle;
//public Transform parent;
public Transform child;
public Quaternion childInitRotation;
public Quaternion childInitLocalRotation;
//public bool isWorld;
public Vector3 axisVector;
public Vector3 axisVectorLocal;
public Transform axisObject;
//public Quaternion initRotation;
void Awake()
{
childInitLocalRotation = child.localRotation;
childInitRotation = child.rotation;
axisVector = axisObject.up;
axisVectorLocal = child.InverseTransformDirection(axisVector);
}
void Start()
{
}
// Update is called once per frame
void Update()
{
Debug.DrawRay(child.position, axisVector, Color.red, 0.1f, true);
Quaternion localRotation = Quaternion.AngleAxis(angle, axisVectorLocal);
child.rotation = childInitRotation * localRotation;
Debug.Log("1. child.rotation " + child.rotation);
Debug.Log("1. child.localRotation " + child.localRotation);
child.localRotation = childInitLocalRotation * localRotation;
Debug.Log("2. child.rotation " + child.rotation);
Debug.Log("2. child.localRotation " + child.localRotation);
}
}
Rotation 에 필요한 회전이 있다면 좌표계 신경 쓸 필요 없이 rotation 이던 localRotation에 바로 적용시키면 된다.