절차적 애니메이션은 필수 요소는 아니지만 꼭 익히고 싶은 기술이기도 하고, 현재 프로젝트의 퀄리티 향상에도 도움이 될 것이라고 생각한다.
오늘은 정말 조금만 했다.
void HeadTrackingUpdate()
{
Quaternion currentLocalRotation = headBone.localRotation;
headBone.rotation = Quaternion.identity;
Vector3 targetWorldLookDir = target.position - headBone.position; // 머리에서 타겟 방향
Vector3 targetLocalLookDir = headBone.InverseTransformDirection(targetWorldLookDir); // 로컬 회전 방향 구하기
// 회전 방향을 최대 회전 각도로 제한시켜서 다시 구하기
targetLocalLookDir = Vector3.RotateTowards(
Vector3.forward,
targetLocalLookDir,
Mathf.Deg2Rad * headMaxTurnAngle,
0
);
Quaternion targetLocalRotation = Quaternion.LookRotation(targetLocalLookDir, Vector3.up);
headBone.localRotation = Quaternion.Slerp(
currentLocalRotation,
targetLocalRotation,
1 - Mathf.Exp(-headTrackingSpeed * Time.deltaTime)
);
}
도마뱀의 머리를 제한된 각도 내에서 회전시킨다.
회전 속도는 구면 선형 보간을 사용했다.
headBone.localRotation = Quaternion.Slerp(
currentLocalRotation,
targetLocalRotation,
1 - Mathf.Exp(-headTrackingSpeed * Time.deltaTime)
);
특이한 점이 있다면 머리 회전속도에서, Mathf.Exp
와 처음 보는 형식의 파라미터를 가지고 프레임과 독립된 움직임 가지게 한 것이다.
수학은..음음 어렵다.
InverseTransformDirection
: 이 메서드도 처음 봤는데, 월드 좌표계 상의 방향을 가져다가 로컬의 목표 회전 방향을 가져다 준 것 같다. (그래픽스 이론 공부의 필요성 처절히 느낀다.)
처음에는 네비 매쉬 에이전트로 목표물까지의 코너 정보를 얻어와서 힘을 가하여 움직이고자 하였음
그런데 네비 매쉬 에이전트 자체의 충돌체,강체와 겹치는 문제가 많았고, 해결하는 방법도 떠오르지 않았다.
검색해보니 애초에 사람들이 구체와 네비매쉬는 생각도 안하고있음.
그냥 다 필요 없고 일직선으로 굴리는 것만 있어도 되지 않나 싶었지만, 장애물 존재의 가능성도 고려하고 싶었다.
네비 매쉬 문제를 해결하는 것보다 A* 알고리즘을 익혀서 적용하는 것이 더 빠르다고 판단하였다...(이거 잘못 선택한거면 정말 큰일이다.ㅋㅋㅋ)
A* 알고리즘은 많은 내용은 하지 못했고, 구조물(피해가야 하는 부분)과 겹치는 노드를 갈 수 없는 노드로 표시하는 정도까지는 했다.