Animator

3D 모델 애니메이션 시스템은 다음과 같은 핵심 원리를 기반으로 합니다:

  1. 효율적인 데이터 구조: 메시, 뼈, 머티리얼, 애니메이션 데이터를 효율적으로 관리하는 구조

  2. 계층적 뼈 구조: 부모-자식 관계로 연결된 뼈 계층 구조를 통한 자연스러운 움직임 표현

  3. 좌표계 변환 처리: T-포즈 기준의 루트 변환을 로컬 변환으로 변환하고 적용하는 명확한 처리 과정

  4. GPU 최적화: 애니메이션 데이터를 GPU 친화적인 텍스처 형태로 변환하여 효율적인 처리 가능

  5. 블렌딩 지원: 두 애니메이션 간 부드러운 전환을 위한 블렌딩 구현

전체 데이터 흐름도

메시와 뼈 데이터 로드 과정

  • 데이터 로드 흐름도

  • 핵심 코드 분석

BindCacheInfo() 함수는 모델의 여러 구성 요소 간의 관계를 설정하는 중요한 역할을 합니다:

  1. 메시와 머티리얼 연결

  2. 메시와 뼈 연결

  3. 뼈 계층 구조 구성 (부모-자식 관계)

Material 데이터 로드 과정

  • 데이터 로드 흐름도

Material 로드 핵심 요소

XML 파일에서 다음 정보를 로드합니다:

  • Material 이름: 고유 식별자

  • 텍스처 경로: 디퓨즈, 스페큘러, 노말 맵

  • 머티리얼 속성: 앰비언트, 디퓨즈, 스페큘러, 이미시브 색상

애니메이션 데이터 로드 및 텍스처 변환 과정

  • 애니메이션 처리 흐름도

  • 주요 코드 분석 및 접근 방식

이 코드는 애니메이션의 기본 정보와 각 뼈마다의 키프레임 데이터를 로드합니다.

  • 애니메이션 변환 행렬 계산 (CreateAnimationTransform)

이 부분은 Root 기준 Transform을 뼈 계층 구조에 맞게 변환하는 핵심 과정입니다:

  • 애니메이션 변환 과정 시각화

핵심 이해 포인트:

  1. T-포즈에서 뼈 변환: 각 뼈는 T-포즈에서의 글로벌 변환 행렬(bone->transform)을 가집니다.

  2. 로컬 좌표계로 변환: 이 글로벌 변환의 역행렬(invGlobal)을 사용하여 로컬 좌표계로 변환합니다.

  3. 애니메이션 변환 적용: 키프레임 데이터(스케일, 회전, 이동)를 사용하여 애니메이션 변환 행렬을 계산합니다.

  4. 부모 영향 적용: 부모 뼈의 변환을 적용하여 계층 구조를 유지합니다.

  5. 최종 변환 계산: invGlobal * tempAnimBoneTransforms[b]를 통해 최종 변환 행렬을 계산합니다.

    1. invGlobal: T-포즈 글로벌 → 로컬 변환

    2. tempAnimBoneTransforms[b]: 애니메이션 적용 후 글로벌 변환

  • 애니메이션 데이터를 텍스처로 변환 (CreateTexture)

  • 텍스처의 메모리 레이아웃 시각화

  • 셰이더에서의 활용

Animator의 개념

Animator는 3D 모델의 다양한 애니메이션 클립들과 그 사이의 전환(트랜지션)을 관리하는 시스템입니다. 이는 게임 캐릭터나 객체의 여러 동작 상태(달리기, 점프, 공격 등)를 자연스럽게 연결하고 제어할 수 있게 해줍니다.

Animator 컴포넌트는 다음 주요 기능을 제공합니다:

  1. 애니메이션 클립 관리: 여러 애니메이션 클립을 등록하고 관리

  2. 트랜지션 시스템: 클립 간 자연스러운 전환을 위한 트랜지션 정의

  3. 파라미터 기반 제어: 불리언, 정수, 부동소수점 파라미터를 통한 상태 전환 조건 설정

  4. 기본 클립 설정: 시작 시 자동으로 재생될 기본 클립 지정

Animator에서 사용하는 구조들

  • Clip 구조체

  1. name: 클립의 고유 이름

  2. isLoop: 반복 재생 여부

  3. animIndex: 모델의 애니메이션 배열에서의 인덱스

  4. progressRatio: 현재 재생 진행률(0~1)

  5. transitions: 이 클립에서 다른 클립으로의 전환 정보

  • Transition 구조체

  1. clipA / clipB: 시작 클립과 목표 클립

  2. flag: 트랜지션 활성화 여부

  3. hasExitTime: exitTime에 도달해야만 전환이 시작되는지 여부

  4. exitTime: 소스 클립의 얼마만큼 진행 후 전환을 시작할지(0~1)

  5. transitionDuration: 전환에 걸리는 시간(초)

  6. conditions: 이 트랜지션이 발생하기 위한 조건들의 배열

  • Parameter와 Condition 구조체

이 구조들은 애니메이션 전환 조건을 정의합니다:

  1. Parameter: 애니메이터의 상태를 나타내는 변수(불리언, 정수, 부동소수점)

  2. Condition: 파라미터가 특정 값과 특정 관계인지 검사하는 조건(같음, 다름, 큼, 작음)

  • 애니메이션 블렌딩 구조체

이 구조체들은 두 애니메이션 사이의 블렌딩(혼합) 정보를 처리합니다:

  1. KeyframeDesc: 현재 프레임, 다음 프레임, 두 프레임 사이의 혼합 비율 등을 포함

  2. blendFrameDesc: 두 애니메이션 클립 사이의 블렌딩 정보를 포함

GUIManager에서 애니메이터 에디팅

GUIManager는 애니메이터 그래프를 시각적으로 편집할 수 있는 인터페이스를 제공합니다. 핵심 기능은 다음과 같습니다:

  • 노드 및 트랜지션 렌더링

  • 트랜지션 설정

  • 클립 사이의 연결 그리기

Animator의 동작 원리와 셰이더 연동

  • Animator::Update 함수

이 함수는 다음을 수행합니다:

  1. 트랜지션 중이면 블렌딩 처리

  2. 아니면 현재 클립을 재생하고 진행률 업데이트

  3. 조건을 체크하여 트랜지션 플래그 설정

  4. 애니메이션 이벤트가 있으면 처리

  5. 진행 중인 트랜지션이 있으면 해당 트랜지션으로 전환

  • 트랜지션 블렌딩 처리

이 함수는 두 애니메이션 클립 간의 블렌딩을 처리합니다:

  1. 두 클립의 현재 상태(프레임, 진행률 등) 계산

  2. 블렌딩 비율 계산(시간 기반)

  3. 블렌딩 정보를 셰이더에 전달하기 위한 구조체 설정

  4. 블렌딩이 완료되면 목표 클립으로 완전히 전환

  • 조건 확인 및 트랜지션 플래그 설정

이 함수는 모든 트랜지션에 대해:

  1. 각 조건을 파라미터 값과 비교하여 검사

  2. exitTime 조건이 있으면 현재 클립의 진행률이 충분한지 체크

  3. 모든 조건이 만족되면 트랜지션 플래그를 활성화

  • 셰이더에서의 애니메이션 블렌딩 처리

이 셰이더 함수는:

  1. 각 정점에 영향을 주는 뼈 인덱스와 가중치를 가져옴

  2. 현재 애니메이션과 전환 중인 애니메이션(있는 경우)의 프레임 정보를 로드

  3. TransformMap 텍스처에서 각 뼈의 변환 행렬을 가져옴

  4. 프레임 사이의 보간을 통해 부드러운 애니메이션 제공

  5. 두 애니메이션 사이의 블렌딩(필요한 경우)

  6. 각 뼈의 가중치를 적용하여 최종 변환 행렬 계산

  • 애니메이터 시스템 시각화

애니메이션 이벤트

애니메이션 이벤트 실행 흐름

  1. 등록 단계:

    1. REGISTER_MONOBEHAVIOR_METHOD 매크로를 통해 함수 등록

    2. 클래스 이름과 함수 이름으로 구성된 키로 MethodRegistry에 저장

  2. 이벤트 설정 단계:

    1. GUIManager를 통해 애니메이션 타임라인에 이벤트 추가

    2. 애니메이션 클립의 특정 시간(0-1 사이의 진행률)에 이벤트 연결

    3. 게임오브젝트의 MonoBehaviour에서 사용 가능한 함수 목록에서 선택

  3. 런타임 실행 단계:

    1. Animator::Update에서 애니메이션 진행률 추적

    2. 진행률이 이벤트 시간에 도달하면 InvokeAnimationEvent 호출

    3. MethodRegistry에서 함수 포인터를 가져와 실행

    4. 이벤트 플래그를 설정하여 중복 호출 방지

  4. 리셋 단계:

    1. 애니메이션 루프가 완료되면 모든 이벤트 플래그 리셋

    2. 다음 루프에서 이벤트가 다시 발생할 수 있도록 함

이벤트 관련 구조체

  • time: 애니메이션 진행률(0~1 사이)에 해당하는 이벤트 발생 시간

  • function: 호출할 함수 정보(스크립트 객체와 함수 키)

  • isFuctionCalled: 이벤트가 이미 호출되었는지 추적하는 플래그

MethodRegistry 시스템

MethodRegistry는 함수 참조를 문자열 키로 관리하는 전역 레지스트리입니다. 이것은 런타임에 함수를 동적으로 찾고 호출할 수 있게 해줍니다.

REGISTER_MONOBEHAVIOR_METHOD 매크로

이 매크로는 MonoBehavior 파생 클래스의 메서드를 MethodRegistry에 등록하는 과정을 간소화합니다:

  1. 클래스와 메서드 이름으로 고유한 키를 생성

  2. 함수 포인터를 생성하여 이 키에 등록

  3. 정적 변수를 통해 프로그램 시작 시 자동으로 등록되도록 함

이벤트 함수 탐색 및 실행 메커니즘

이 함수는 애니메이터가 부착된 게임 오브젝트에서 사용 가능한 모든 이벤트 함수 목록을 생성합니다:

  1. 게임 오브젝트에 부착된 모든 컴포넌트를 검색

  2. MonoBehaviour 파생 컴포넌트만 필터링

  3. 각 컴포넌트의 클래스 이름을 가져옴

  4. 등록된 모든 메서드 중 해당 클래스에 속하는 메서드만 필터링하여 목록에 추가

함수 실행: InvokeAnimationEvent

이 함수는 등록된 이벤트 함수를 실행합니다:

  1. MethodRegistry에서 함수 키에 해당하는 함수 포인터를 가져옴

  2. 함수가 존재하면 MonoBehaviour 객체를 인자로 전달하여 실행

애니메이션 재생 중 이벤트 처리

이 코드는 다음 작업을 수행합니다:

  1. 현재 재생 중인 클립의 모든 이벤트를 순회

  2. 현재 애니메이션 진행률이 이벤트 시간에 도달했는지 확인

  3. 아직 호출되지 않은 이벤트라면 InvokeAnimationEvent를 통해 함수 호출

  4. 호출 후 isFuctionCalled 플래그를 true로 설정하여 중복 호출 방지

애니메이션 루프 시 이벤트 리셋

이 코드는 애니메이션이 마지막 프레임에 도달했을 때:

  1. 클립의 isEndFrame 플래그를 true로 설정

  2. 모든 이벤트의 isFuctionCalled 플래그를 false로 리셋하여 다음 루프에서 다시 호출될 수 있도록 함

  3. 반복 재생을 위해 프레임 인덱스를 초기화(isLoop가 true인 경우)

Last updated