Unity AnimatorController 자동 생성
using UnityEngine;
using UnityEditor;
using UnityEditorInternal;
using System;
using System.Collections;
using System.Collections.Generic;
public class GetAnimationClips : AssetPostprocessor
{
void OnPostprocessModel(GameObject go)
{
List<AnimationClip> clips = new List<AnimationClip>();
UnityEngine.Object[] objects = AssetDatabase.LoadAllAssetsAtPath(assetPath);
Debug.Log(objects.Length);
foreach (var obj in objects) {
AnimationClip clip = obj as AnimationClip;
if (clip != null && clip.name.IndexOf("__preview__") == -1) {
clips.Add(clip);
}
}
CreateAnimationController(assetPath, clips);
}
static void CreateAnimationController(string path, List<AnimationClip> clips)
{
path = path.Replace("\\", "/").Replace(".FBX", ".fbx");
string acPath = path.Replace(".fbx", ".controller");
string prefabPath = path.Replace(".fbx", ".prefab");
//
AnimatorController animatorController = AnimatorController.CreateAnimatorControllerAtPath(acPath);
AnimatorControllerLayer layer = animatorController.GetLayer(0);
UnityEditorInternal.StateMachine sm = layer.stateMachine;
Vector3 anyStatePosition = sm.anyStatePosition;
float OFFSET_X = 220;
float OFFSET_Y = 60;
float ITEM_PER_LINE = 4;
float originX = anyStatePosition.x - OFFSET_X * (ITEM_PER_LINE / 2.5f);
float originY = anyStatePosition.y + OFFSET_Y;
float x = originX;
float y = originY;
foreach (AnimationClip newClip in clips) {
State state = sm.AddState(newClip.name.ToLower());
state.SetAnimationClip(newClip, layer);
state.position = new Vector3(x, y, 0);
x += OFFSET_X;
if (x >= originX + OFFSET_X * ITEM_PER_LINE) {
x = originX;
y += OFFSET_Y;
}
}
// prefab
string name = path.Substring(path.LastIndexOf("/") + 1).Replace(".fbx", "");
prefabPath = "Assets/Resources/" + name + ".prefab";
GameObject go = AssetDatabase.LoadAssetAtPath(path, typeof(GameObject)) as GameObject;
go.name = name;
Animator animator = go.GetComponent<Animator>();
if (animator == null) {
animator = go.AddComponent<Animator>();
}
animator.applyRootMotion = false;
animator.runtimeAnimatorController = animatorController;
//AssetDatabase.CreateAsset(go, prefabPath);
PrefabUtility.CreatePrefab(prefabPath, go);
GameObject.DestroyImmediate(go, true);
AssetDatabase.SaveAssets();
}
}
이 코드가 하는 일은 모델을 불러올 때 자동으로 애니메이션을 불러온 다음AnimatorController 파일(애니메이션의 흐름을 제어하는 파일)을 생성하고 대응하는prefab(코드를 직접 통해 실례화하는 데 사용)을 생성하는 것이다.다음과 같은 몇 가지 지식이 있습니다.
1、AssetDatabase.LoadAllAssetsAtPath는 이 함수를 통해 fbx 파일을 불러올 수 있습니다. (모든 애니메이션 정보를 포함합니다.)이것은 fbx 파일을 기반으로 AnimationClip을 가져오는 방법입니다.
2. AssetPostprocessor 이것은 Unity 자원을 불러오는 인터페이스입니다.애니메이션 컨트롤러를 자동으로 생성하는 코드는 여기에 두지 않고 Menu 메뉴를 확장해서 대응하는 기능을 완성할 수 있습니다. (예를 들어 폴더 아래의 fbx 파일을 반복해서 선택하고 관련 처리를 할 수 있습니다.)
이것은 내가 현재 알고 있는 MMO 중에서 가장 정확한 MecAnim의 사용법이다.
1、수동으로 편집하지 마세요.controller 파일은 애니메이션을 불러오든 연결을 불러오든 MMO에서 애니메이션의 양이 상당히 많기 때문에 인공 편집은 절대 받아들일 수 없다.
2. MecAnim은 어느 정도 장점이 있다. 예를 들어 방향을 바꾸면 현재 거의 모든 MMO는 오래된 애니메이션 시스템을 사용한다.그러나 나는 나의 이 방법이 낡은 애니메이션 시스템과 새로운 애니메이션 시스템을 겸용할 수 있다고 생각한다. 또는 낡은 애니메이션 시스템의 항목을 새로운 애니메이션 시스템으로 매끄럽게 전환시킬 수 있다고 생각한다.
3. 우리가 애니메이션을 유지하는 방식은 이럴 수 있다. 미술은 모델을 제시하고 가능하다면 애니메이션을 잘 나누는 것이 좋다(마야가 지원하는 것 같고blender도 지원하는 것 같지만 3dmax는 알 수 없다. 예를 들어 내가 blender를 사용하여 횃불의 빛을 내보낸 모델을 유닛에 사용하면 유닛은 직접 잘린 애니메이션을 식별할 수 있고 수동으로 애니메이션을 자르지 않아도 된다).만약 없다면, 애니메이션의 시작, 끝 프레임을 유지하는 설정 파일 (예: excel) 이 필요합니다.모델을 가져올 때 이 구성 파일에 따라 코드를 통해 AnimationClip을 추가할 수 있습니다.
4.AnimatorController를 자동으로 생성하는 사고방식과 같이 오래된 애니메이션 시스템에 응용할 수 있다. 왜냐하면 가장 핵심적인 내용은 fbx를 통해AnimationClip 정보를 어떻게 얻는가이기 때문이다.오래된 애니메이션 시스템이라면 AnimationClip을 prefab의 Animation 애니메이션 목록에 추가합니다.
5. 내가 어떻게 새로운 애니메이션 시스템을 사용하는지:
GameObject prefab = Resources.Load("player") as GameObject;
GameObject go = Instantiate(prefab) as GameObject;
Animator animator = go.GetComponent<Animator>();
animator.CrossFade("idle", 0.25f, 0);
controller 안은 연결이 되지 않고, 파라메트릭 제어도 필요 없습니다. 그것은 단지 용기일 뿐입니다.코드에서 직접 CrossFade를 사용하여 애니메이션 전환을 수행합니다.이것은 Asset Bundle에서 포장한prefab가Unity의Animator 페이지에서 데이터를 볼 수 없다는 추가 장점이 있습니다.애니메이션 전환을 스스로 제어하면 더욱 자유롭게 할 수 있다.
Unity5 수정 사항 보완:
UnityEditor.Animations.AnimatorState state = sm.AddState(clipName, new Vector3(x, y, 0));
state.motion = newClip;
API는 일부 수정 사항이 있으며 직접 motion을 통해 clip을 설정합니다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.