포스트

Unity 런타임 애니메이션 녹화

Unity 런타임 애니메이션 녹화

📀 말머리


📀 시작


💿 목표

Chanity에 사용될 모션녹화 모듈 개발.

아바타 Transform을 이용해서 FBX파일로

  • XsAnimationRecorder.cs에서 Unity Animation 파일로 뽑아내는 건 있고 (에디터 스크립트라, Only 에디터 타임에)
  • Unity Animation을 FBX 파일로 변환하는 건 이런거 참고

아바타 Animation 데이터는

  • 아바타 Animator 컴포넌트에서 .GetHumanBone() 아니면 .GetMuscle()로 값을 가져오는걸로 하는게 좋을 것. (구상)
  • 접근 가능한 값은 Animator랑 Avatar 클래스 (Chanity Avatar 클래스겠지?)

목표

  • Banana Man 샘플 모델 아바타에 위에 Unity쟝 Animation 모션 넣어서 재생시키고 녹화 테스트

목표 결과물

최종적으로 위처럼 모델, 애니메이션, 본이 포함된 FBX 파일을 뽑으면 된다.
녹화하면 보통 FBX로 파일 뽑아주 는 듯하다.

📀 과정


💿 XsAnimationRecorder 분석

런타임에서 애니메이션을 녹화하는 방식을 알아내기 위해 XsAnimationRecorder.cs 파일을 분석한다.

에디터용 스크립트다.
#if UNITY_EDITOR로 감싸져있어 빌드에서는 사용할 수 없다.

동작은 다음과 같다.

  1. Start() : EditorCurveBinding[], AnimationCurve[] 초기화
  2. Record() :
  3. SaveRecording()에서 애니메이션 클립을 만들어 저장한다.
  • 알아야 할 것
    • EditorCurveBinding
    • HumanPose, HumanPoseHandler
    • AnimationUtility.GetAnimatableBindings
    • HumanTrait
    • HumanTrait.MurcleName
    • AnimationCurve
    • Animator.avatar
    • HumanPoseHandler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/// <summary>
/// Use the AnimationUtility to save our AnimationCurves to the correct EditorCurveBindings and then save our new clip to disk
/// </summary>
void SaveRecording()
{
	//Creates a new clip so we can save all of our curves.
	AnimationClip clip = new();

	//Iterate through all curves and add the data to the currect EditorCurveBindings
	for (int i = 0; i < recordedCurvesCount; i++)
	{
		AnimationUtility.SetEditorCurve(clip, indexToCurve[i], curves[i]);
	}

	//Save the clip to disk
	AssetDatabase.CreateAsset(clip, filePath + fileName + ".anim");
	AssetDatabase.SaveAssets();

	Debug.Log("[xens] Animation Clip <b>\"" + fileName + ".anim\"</b> saved successfuly in <b>" + filePath + "</b>");
}

💿 HumanPose

캐릭터의 포즈를 나타내는 구조체.
캐릭터의 위치, 회전, 근육 값을 포함.

  • Vector3 bodyPosition: 캐릭터의 몸 위치
  • Quaternion bodyRotation: 캐릭터의 몸 회전
  • float[] muscles: 캐릭터의 근육 값 배열

HumanPoseHandler

HumanPose를 관리하고 조작하는 클래스.
HumanPose를 가져오거나 설정.

  • HumanPoseHandler(Avatar avatar, Transform root) : 생성자. Avatar와 Transform을 사용하여 HumanPoseHandler를 초기화합니다
  • void GetHumanPose(ref HumanPose humanPose) : 현재 포즈를 HumanPose 구조체에 저장합니다.
  • void SetHumanPose(ref HumanPose humanPose) : HumanPose 구조체에 저장된 포즈를 설정합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
using UnityEngine;

public class HumanPoseHandlerExample : MonoBehaviour
{
    public Animator animator;

    void Start()
    {
        HumanPoseHandler poseHandler = new HumanPoseHandler(animator.avatar, animator.transform);
        HumanPose pose = new HumanPose();

        // 현재 포즈 가져오기
        poseHandler.GetHumanPose(ref pose);

        // 포즈 정보 출력
        Debug.Log("Body Position: " + pose.bodyPosition);
        Debug.Log("Body Rotation: " + pose.bodyRotation);
        Debug.Log("Muscles: " + string.Join(", ", pose.muscles));

        // 포즈 수정
        pose.bodyPosition += Vector3.up * 0.1f; // 몸 위치를 약간 위로 이동
        pose.bodyRotation *= Quaternion.Euler(0, 10, 0); // 몸을 약간 회전

        // 수정된 포즈 설정
        poseHandler.SetHumanPose(ref pose);
    }
}

💿 AnimationUtility

AnimationUtility.GetAnimatableBindings

2021.3 기준.

AnimationUtility.GetAnimatableBindings(Gameobject targetObject, GameObject root)'

TargetObject의 Animatable한 것들을 EditorCurveBinding[]으로 반환.

root는 반드시 targetObject의 루트일 필요 없음.
targetObject랑 같거나 더 상위 계층의 오브젝트.

AnimationUtility.SetEditorCurve

💿 AnimationClip To FBX

먼저 에디터에서만 사용 가능한 AnimationUtility.SetEditorCurveAnimationClip.SetCurve로 대신한다.

1
2
3
4
5
for (int i = 0; i < recordedCurvesCount; i++)
{
    // AnimationUtility.SetEditorCurve(clip, indexToCurve[i], curves[i]);
    clip.SetCurve(indexToCurve[i].path, indexToCurve[i].type, indexToCurve[i].propertyName, curves[i]);
}

XsAnimationRecorder.cs에서는 이 다음 애니메이션 클립을 AssetDatabase를 이용해 파일로 저장하는데, AssetDatabase 역시 에디터에서만 사용 가능하다.

현재 만들고자 하는 모듈의 목표는, AnimationClip을 FBX로 변환하여 저장하는 것이라서 굳이 이 부분은 바꿔 쓸 필요가 없다. 지워준다.

1
2
3
// Save the clip to disk
// AssetDatabase.CreateAsset(clip, filePath + fileName + ".anim");
// AssetDatabase.SaveAssets();

AnimationClip을 FBX로 변환한다.
이를 위해

📀 메모/생각


이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.