[Unity]IK basic-2

Connected Brain·2025년 1월 24일

IK_practice

목록 보기
2/3

Inverse Kinematic animation 만들기

  • 지난 학기 수업에서 개념만 간단하게 배웠던 Inverse Kinematic 시스템을 Unity에서 직접 만들어 보고 어떤 요소를 고려해야할 지 고민한 부분을 기록하고자 한다.

참고 영상
https://youtu.be/hbgDqyy8bIw?si=Td_2GO6HdAuv7Swe

  • 해당 영상을 따라해보며 영상에 나온 내용을 Unity에 적용하고자 하였다. 본질적인 부분은 크게 다르지 않기때문에 실제 화면상에 표현하는 부분에서만 Unity에 적합하도록 바꾸었다.

개발일지 #2

3. 마우스 위치를 향하도록 회전

mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
//mousePos로 향하는 벡터
dir = mousePos - point;

// dir의 크기가 0이 아닌지 확인
if (dir.magnitude > 0)
{
    angle = Mathf.Acos((mousePos.x - point.x) / dir.magnitude) * (180 / Mathf.PI);

    if (mousePos.y < point.y)
    {
        angle *= -1;
    }
}
  • 마우스 커서가 위치한 방향으로 회전하는 것을 확인하기 위한 코드이다.

  • 먼저 카메라로부터 마우스의 월드에서의 위치를 받아와 point에서 마우스로 향하는 벡터를 구해준다.

    Vector A - VectorB를 통해 B에서 A로 향하는 벡터를 구할 수 있다.

  • 이어서 각도를 구하는 과정을 살펴보도록 하겠다.

[부연 설명]

angle = Mathf.Acos((mousePos.x - point.x) / dir.magnitude) * (180 / Mathf.PI);

삼각함수의 역함수를 활용해 삼각비를 통해 각도를 구할 수 있다.

※ Acos = Arccos = Cos함수의 역함수

먼저 마우스의 x 좌표값과 point의 x 좌표값을 빼서 나온 값은 우리가 찾고자 하는 각 θ를 가지는 직각삼각형의 밑변으로 볼 수 있다. 그리고 dir.magnitude는 벡터의 크기를 나타내는 것으로 빗변으로 볼 수 있기에 밑변/빝변 = Cos(θ)인 것이다.
→ θ = Acos(밑변/빝변)
여기에 180/π를 곱해주는 이유는 Acos(밑변/빝변)가 반환하는 값이 라디안 형태이므로 우리가 사용하는 degree(각도) 형태로 바꿔 주기 한 것이다.

각도를 라디안으로 바꿔줄 때: 각도 π/180
라디안을 각도로 바꿔줄 때: 라디안
180/π

  • 마우스를 따라 회전하는 것을 확인할 수 있다.

4. 전체 구조가 마우스를 따라 이동(work in progress)

  • Inverse Kinematic과 전체 구조가 마우스를 따라 이동하는 것이 어떤 관계가 있을까?
    이후에 위와 동일한 구조가 여러 개가 연결되어 전체 구조를 형성할 것이다. 그때 각각이 끝 지점을 향해 회전, 이동한다면 자연스러운 움직임을 만들 수 있을 것이다.
  • 다만 제목에서도 알 수 있다 싶이 아직 완전히 기능을 완성하지 못했다.
Vector2 normalizedDir = dir.normalized; // 노멀라이즈된 방향 저장
Vector2 inverse_dir = normalizedDir  * -1 * len; // 노멀라이즈된 방향을 사용
Vector2 point = dir + inverse_dir; // 원래의 dir을 사용
  • 원리 자체는 이해했으나 이를 Unity 상에서 저장하는 과정에 문제가 발생하였다. 문제에 대해 설명하기 이전에 원리부터 설명하도록 하겠다.
  • 원리는 간단하다. 점 a의 위치가 mousePos로부터 len만큼 떨어져 있는 상태로 마우스를 따라오게 된다면 앞서 구현한 기능에 따라 점 b는 mousePos를 향하도록 회전하여 있는 상태가 만들어진다. 이는 목표로 하였던 앞의 점을 따라가는 구조의 기본 형태를 이룬다고 할 수 있다. 여기서 문제가 발생한 부분은

문제점

1. point 계산이 확정되지 않음

  • Iksystem 내부에선 point를 사용하여 값을 계산한 이후에 이를 vertex.a로 값을 넘겨주고 이후에 GameObject를 사용해 화면에 표시하는 과정에서는 vertex의 정보를 불러와 사용하고 있다. 이 과정이 다소 걱정스러웠는데 역시나 point를 사용하여 계산하고 이를 적용하는 과정에서 지속적으로 값이 특정되지 않고 실행 과정 중에 지속해서 빠르게 변경되는 문제가 발생하였다.
  • 문제 해결 과정에서 이유는 알 수 없지만 이를 직접 vertex.a에 할당하는 경우에는 문제가 해소되는 경우도 있어서 연산 과정에서 어떤 문제가 발생하는지 더 자세히 확인할 필요가 있어 보였다.

2. 점 a가 마우스에 위치함

  • 구상한 원리를 설명하자면 이와 같다.

    1. 점 a에서 마우스로 향하는 벡터를 노멀라이즈하여 방향 성분만 남기고 이를 len만큼 곱한 뒤 -1을 곱해 반대 방향을 향하게 만든 것을 구하고 이를 inverse_dir 이라고 저장한다.
    2. 이를 dir과 더하면 dir로 향하지만 len만큼 떨어진 벡터를 구할 수 있다.
    3. 해당 벡터로 점 a를 이동한다.
  • 이에 따라 코드를 작성하였다고 생각했지만 1번에서 나온 문제가 발생하지 않았을 때에도 점 a가 마우스 커서에 위치하는 상황이 있어 앞선 오류로 인한 것인지, 전체적으로 구상한 원리가 문제인 것인지 확인이 필요한 상황이다.

0개의 댓글