/// <summary> /// 루트모션 적용 시작 (주의! 애니메이션은 다른곳에서 플레이하던지 해야함. 여기서는 루트모션에 이동값만 적용시킴) /// </summary> /// <param name="animState">루트모션을 수행할 애니메이션</param> public void Play(AnimationState animState, bool rootMotion = false, bool ignoreEnemy = false) { if (null == curveDic || !curveDic.ContainsKey(animState.name)) { if (rootMotion) { if (GameDefine.TestMode) { if (null == curveDic) { Debug.Log("curveDic 가 없습니다"); } else if (!curveDic.ContainsKey(animState.name)) { Debug.Log("curveDic 에 애니가 없습니다 " + animState.name); } } } return; } //if (G_GameInfo.GameMode == GAME_MODE.FREEFIGHT) // rootMotion = false; _ignoreEnemy = ignoreEnemy; doRootMotion = rootMotion; playingAnimState = animState; playingAnimName = animState.name; playingAnimLength = animState.length; playingCurve = curveDic[playingAnimName]; prevFramePos = playingCurve.GetOffset(playingAnimState.time); }
public void End() { doRootMotion = false; if (null != playingAnimState) { playingAnimState = null; playingCurve = null; } }
/// <summary> /// RMCurve 객체를 정해진 경로에 빈 RMCurve Asset파일을 생성해준다. /// </summary> /// <param name="name">생성할 파일명</param> /// <returns>해당 경로에 생성된 asset</returns> public static RMCurve CreateEmptyRMCurve(string name) { RMCurve createdCurve = ScriptableObject.CreateInstance <RMCurve>(); createdCurve.Name = name; createdCurve.Length = 0f; AssetDatabase.CreateAsset(createdCurve, "Assets" + RMDataSavedPath + Path.DirectorySeparatorChar + name + ".asset"); AssetDatabase.SaveAssets(); return(createdCurve); }
public override void OnInspectorGUI() { if (null == target) { return; } RMCurve curData = target as RMCurve; EditorGUILayout.BeginHorizontal("box"); EditorGUILayout.LabelField("Matched Animation Name", GUILayout.Width(200)); EditorGUILayout.LabelField(curData.Name, new GUIStyle("textfield"), GUILayout.ExpandWidth(true)); EditorGUILayout.EndHorizontal(); EditorGUILayout.Separator(); EditorGUILayout.BeginHorizontal("box"); EditorGUILayout.LabelField("Matched Animation Length", GUILayout.Width(200)); EditorGUILayout.LabelField(curData.Length.ToString(), new GUIStyle("textfield"), GUILayout.ExpandWidth(true)); EditorGUILayout.EndHorizontal(); EditorGUILayout.Separator(); EditorGUILayout.BeginVertical("box"); { EditorGUILayout.LabelField("Motion Curve Data"); AnimationCurve[] curves = new AnimationCurve[] { curData.XCurve, curData.YCurve, curData.ZCurve }; for (int i = 0; i < curves.Length; i++) { AnimationCurve curve = curves[i]; if (null == curve) { continue; } curve = EditorGUILayout.CurveField(curve, Color.green, new Rect(0, 0, 0, 0), GUILayout.ExpandWidth(true), GUILayout.Height(100)); } } EditorGUILayout.EndVertical(); if (GUI.changed) { EditorUtility.SetDirty(curData); serializedObject.ApplyModifiedProperties(); } }
static RMCurve CreateRMCurveFromAnimationClip(AnimationClip animClip) { if (null == animClip) { Debug.LogWarning("존재하지 않는 AnimationClip 입니다."); } // // 해당 AnimationClip에서 존재하는 Curve들을 모두 찾아서, // RMBoneName에 존재하는 Curve만 데이터화 시키도록한다. AnimationCurve[] localPosCurves = null; AnimationClipCurveData[] curveDatas = AnimationUtility.GetAllCurves(animClip); foreach (AnimationClipCurveData curve in curveDatas) { // 위치 변위 값만 저장하기 위해서 조건 검사 if (curve.path != RMBoneName || !curve.propertyName.Contains("m_LocalPosition")) { continue; } /* TODO : 추후 최적화 아이디어 * * 키프레임간 차이가 Epsilon정도로 작게 차이나는 키값에 대해서 제거 작업해서 필요없는 키 값을 없애는 작업 * 삭제한 키값의 좌우 키들은 Left Tangent, Right Tanget을 Linear나 Constant로 조절할 필요가 있음. * */ if (null == localPosCurves) { localPosCurves = new AnimationCurve[3]; } switch (curve.propertyName) { case "m_LocalPosition.x": localPosCurves[0] = curve.curve; // new AnimationCurve( curve.curve.keys ); break; case "m_LocalPosition.y": localPosCurves[1] = curve.curve; // new AnimationCurve( curve.curve.keys ); break; case "m_LocalPosition.z": localPosCurves[2] = curve.curve; // new AnimationCurve( curve.curve.keys ); break; } } RMCurve createdRM = null; if (null != localPosCurves) { // RMCurve 생성후, Curve존재시 데이터 채우기 createdRM = ScriptableObject.CreateInstance <RMCurve>(); string animName = animClip.name; createdRM.Name = animName; createdRM.Length = animClip.length; CopyCurve(localPosCurves[0], ref createdRM.XCurve); CopyCurve(localPosCurves[1], ref createdRM.YCurve); CopyCurve(localPosCurves[2], ref createdRM.ZCurve); // // 그룹별 폴더 생성을 위한 코드 string[] splitNames = animName.Split('_'); string groupFolderName = ""; switch (splitNames[0]) { case "m": //몬스터 if (splitNames[1] == "b") //보스 { //ex ) m_b_merchant_01 groupFolderName = string.Format("{0}_{1}_{2}_{3}", splitNames[0], splitNames[1], splitNames[2], splitNames[3]); break; } //ex ) m_merchant_01 groupFolderName = string.Format("{0}_{1}_{2}", splitNames[0], splitNames[1], splitNames[2]); break; case "pc": //플레이어 //ex ) pc_f groupFolderName = string.Format("{0}_{1}", splitNames[0], splitNames[1]); break; case "par": //파트너 //ex ) par_mokkwailan_01 //groupFolderName = string.Format("{0}_{1}_{2}", splitNames[0], splitNames[1], splitNames[2]); groupFolderName = string.Format("{0}_{1}", splitNames[0], splitNames[1]); break; } //if (splitNames.Length > 3) // groupFolderName = string.Format("{0}_{1}_{0}", splitNames[0], splitNames[1], splitNames[2]); if (!string.IsNullOrEmpty(groupFolderName)) { string newFolder = Path.GetFullPath("Assets" + RMDataSavedPath + Path.DirectorySeparatorChar + groupFolderName); if (!Directory.Exists(newFolder)) { Directory.CreateDirectory(newFolder); } groupFolderName += Path.DirectorySeparatorChar; } // RMCurve데이터 asset으로 저장 AssetDatabase.CreateAsset(createdRM, "Assets" + RMDataSavedPath + Path.DirectorySeparatorChar + groupFolderName + createdRM.Name + ".asset"); AssetDatabase.SaveAssets(); } return(createdRM); }