[-] Remove Thirdly of Animation

[-] Remove Thirdly of Animation because of it`s bad for editor
This commit is contained in:
ALEXTANG
2023-04-21 23:59:44 +08:00
parent 2caa6e686e
commit cb2b9331cf
6 changed files with 0 additions and 1022 deletions

View File

@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 0db55501a091a6e429dd80459f36b6af
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,9 +0,0 @@
fileFormatVersion: 2
guid: b94472036d46ad5498116fcc1cbf4dfe
folderAsset: yes
timeCreated: 1510262153
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,136 +0,0 @@
/*------------------------------------------------------------------------------
Original Author: Pikachuxxxx
Adapted By: Brandon Lyman
This script is an adaptation of Pikachuxxxx's utiltiy to reverse an animation
clip in Unity. Please find the original Github Gist here:
https://gist.github.com/8101da6d14a5afde80c7c180e3a43644.git
ABSOLUTELY ALL CREDIT FOR THIS SCRIPT goes to Pikachuxxxx. Thank you so much for
your original script!
Unfortunately, their method that utilizes
"AnimationUtility.GetAllCurves()" is obsolete, according to the official
unity documentation:
https://docs.unity3d.com/ScriptReference/AnimationUtility.GetAllCurves.html
The editor suggests using "AnimationUtility.GetCurveBindings()" in its stead,
and this script reveals how that can be accomplished as it is slightly
different from the original methodology. I also added in some logic to
differentiate between the original clip and the new clip being created, as
I experienced null reference exceptions after the original "ClearAllCurves()"
call. Additionally, I placed the script's logic in a ScriptableWizard class to
fit the needs for my project. For more information on ScriptableWizards, please
refer to this Unity Learn Tutorial:
https://learn.unity.com/tutorial/creating-basic-editor-tools#5cf6c8f2edbc2a160a8a0951
Hope this helps and please comment with any questions. Thanks!
------------------------------------------------------------------------------*/
using UnityEngine;
using UnityEditor;
using System.IO;
using System.Collections.Generic;
//using static DG.DemiEditor.DeGUIKey;
public class SpiteAnimationClip : ScriptableWizard
{
public string NewFileName = "";
public float BeginTime = 0;
public float EndTime = 1;
[MenuItem("Tools/SplitAnimationClip...")]
private static void SplitAnimationClipShow()
{
ScriptableWizard.DisplayWizard<SpiteAnimationClip>("SpiteAnimationClip...", "splite");
}
private void OnWizardCreate()
{
string directoryPath =
Path.GetDirectoryName(AssetDatabase.GetAssetPath(Selection.activeObject));
string fileName =
Path.GetFileName(AssetDatabase.GetAssetPath(Selection.activeObject));
string fileExtension =
Path.GetExtension(AssetDatabase.GetAssetPath(Selection.activeObject));
fileName = fileName.Split('.')[0];
string copiedFilePath = "";
if (NewFileName != null && NewFileName != "")
{
copiedFilePath = directoryPath + Path.DirectorySeparatorChar + NewFileName + fileExtension;
}
else
{
copiedFilePath = directoryPath + Path.DirectorySeparatorChar + fileName + $"_split_{BeginTime}_{EndTime}" + fileExtension;
}
AnimationClip originalClip = GetSelectedClip();
AssetDatabase.CopyAsset(AssetDatabase.GetAssetPath(Selection.activeObject), copiedFilePath);
AnimationClip reversedClip = (AnimationClip)AssetDatabase.LoadAssetAtPath(copiedFilePath, typeof(AnimationClip));
if (originalClip == null)
{
return;
}
float clipLength = originalClip.length;
EditorCurveBinding[] curveBindings = AnimationUtility.GetCurveBindings(originalClip);
Debug.Log(curveBindings.Length);
reversedClip.ClearCurves();
float timeOffset = -1;
foreach (EditorCurveBinding binding in curveBindings)
{
AnimationCurve curve = AnimationUtility.GetEditorCurve(originalClip, binding);
var keys = new List<Keyframe>();// curve.keys;
int keyCount = curve.keys.Length;
for (int i = 0; i < keyCount; i++)
{
Keyframe K = curve.keys[i];
if (K.time >= BeginTime && K.time <= EndTime)
{
if (timeOffset < 0)
{
timeOffset = K.time;
}
K.time = K.time - timeOffset;
keys.Add(K);
Debug.LogError("time " + clipLength + " index " + i + " time " + K.time);
}
}
curve.keys = keys.ToArray() ;
reversedClip.SetCurve(binding.path, binding.type, binding.propertyName, curve);
}
AnimationEvent[] events = AnimationUtility.GetAnimationEvents(originalClip);
var eventsList= new List<AnimationEvent>();
if (events.Length > 0)
{
for (int i = 0; i < events.Length; i++)
{
var eventTemp = events[i];
if (eventTemp.time <= BeginTime && eventTemp.time >= EndTime)
{
eventTemp.time = eventTemp.time - timeOffset;
eventsList.Add(eventTemp);
}
}
AnimationUtility.SetAnimationEvents(reversedClip, eventsList.ToArray());
}
Debug.Log("[[ReverseAnimationClip.cs]] Successfully reversed " +
"animation clip " + fileName + ".");
}
private AnimationClip GetSelectedClip()
{
Object[] clips = Selection.GetFiltered(typeof(AnimationClip), SelectionMode.Assets);
if (clips.Length > 0)
{
return clips[0] as AnimationClip;
}
return null;
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 9368fbead1d3043419793a2c9c3ef030
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,846 +0,0 @@
/// INFORMATION
///
/// Project: Chloroplast Games Framework
/// Game: Chloroplast Games Framework
/// Date: 02/05/2017
/// Author: Chloroplast Games
/// Web: http://www.chloroplastgames.com
/// Programmers: David Cuenca Diez
/// Description: Tool that allows change the path of hierarchy from a animation from an animation clip.
///
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using UnityEditor;
using UnityEngine;
// Local Namespace
namespace CGF.Editor.Tools
{
public class PathData
{
public string ClipName { get; }
public string CurrentPath { get; set; }
public string LastPath { get; set; }
public AnimationClip Clip { get; set; }
public EditorCurveBinding EditorCurve;
public PathData(string clipName, string currentPath, string lastPath, EditorCurveBinding editorCurve,AnimationClip clip)
{
ClipName = clipName;
CurrentPath = currentPath;
LastPath = lastPath;
EditorCurve = editorCurve;
Clip= clip;
}
}
/// \english
/// <summary>
/// Tool that allows change the path of hierarchy from a animation from an animation clip.
/// </summary>
/// \endenglish
/// \spanish
/// <summary>
/// Herramienta que permite canviar la ruta de la jerarqu<71>a de las animaciones de un clip de animaci<63>n.
/// </summary>
/// \endspanish
public class CGFAnimationHierarchyEditorTool : EditorWindow
{
#region Public Variables
#endregion
#region Private Variables
private enum TypeGameObject
{
None,
GameObject,
/*AnimationClip,
RuntimeAnimatorController*/
};
private TypeGameObject _currentSelectionGameObject;
private int index;
private List<GameObject> _gameObjects;
private Animator _animatorObject;
private Animator _animatorObject2;
private List<PathData> _pathDataList;
private RuntimeAnimatorController _myruntime;
private List<AnimationClip> _currentAnimationClips;
private List<AnimationClip> _myanimationClips;
private List<string> _clipNames = new List<string>();
private string[] _modes = new string[] { "Path", "GameObject" };
private int _selectedMode = 0;
private string _replacePath = "";
private GameObject _replaceGameObject;
private string _replacementPath = "";
private GameObject _replacementGameObject;
private Vector2 scrollPosContent;
#endregion
#region Main Methods
[MenuItem("Tools/Animation Hierarchy Editor Tool")]
private static void ShowWindow()
{
EditorWindow window = EditorWindow.GetWindow(typeof(CGFAnimationHierarchyEditorTool), false, "Animation Hierarchy Editor Tool", true);
window.minSize = new Vector2(1024, 250);
}
public CGFAnimationHierarchyEditorTool()
{
_currentSelectionGameObject = new TypeGameObject();
_currentSelectionGameObject = TypeGameObject.None;
_myanimationClips = new List<AnimationClip>();
_gameObjects = new List<GameObject>();
}
private void OnEnable()
{
ResetSelection();
}
private void OnSelectionChange()
{
ResetSelection();
this.Repaint();
}
private void ResetSelection()
{
_myanimationClips.Clear();
_clipNames.Clear();
_animatorObject = null;
_myruntime = null;
_animatorObject2 = null;
index = 0;
if (Selection.activeGameObject is GameObject)
{
_currentSelectionGameObject = TypeGameObject.GameObject;
}
else
{
_currentSelectionGameObject = TypeGameObject.None;
}
DrawSeletedAnimator();
}
private void DrawSeletedAnimator()
{
if (_currentSelectionGameObject != TypeGameObject.GameObject)
{
return;
}
_animatorObject2 = Selection.activeGameObject.GetComponent<Animator>();
if (_animatorObject2 == null)
{
_currentSelectionGameObject = TypeGameObject.None;
return;
}
_animatorObject = _animatorObject2;
if (_animatorObject2.runtimeAnimatorController == null)
{
_currentSelectionGameObject = TypeGameObject.None;
return;
}
_myruntime = _animatorObject2.runtimeAnimatorController;
if (_myruntime.animationClips.Length == 0)
{
_currentSelectionGameObject = TypeGameObject.None;
return;
}
foreach (AnimationClip i in _myruntime.animationClips)
{
_myanimationClips.Add(i);
}
_clipNames.Add("All Clips");
foreach (AnimationClip e in _myanimationClips)
{
_clipNames.Add(e.name);
}
if (_myanimationClips.Count > 0)
{
_currentAnimationClips = _myanimationClips;
}
else
{
_currentAnimationClips = null;
}
FillModel();
}
private void DrawGui()
{
bool animations = true;
EditorGUILayout.Space();
EditorGUILayout.Space();
EditorGUILayout.BeginHorizontal();
GUILayout.Label("Selected Animator", GUILayout.Width(170));
GUI.enabled = false;
_animatorObject = ((Animator)EditorGUILayout.ObjectField(_animatorObject, typeof(Animator), true, GUILayout.Width(300)));
GUILayout.FlexibleSpace();
GUI.enabled = _currentSelectionGameObject == TypeGameObject.GameObject;
GUILayout.Label("Bulk Replace Mode");
_selectedMode = EditorGUILayout.Popup(_selectedMode, _modes);
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
GUI.enabled = false;
GUILayout.Label("Selected Animator Controller", GUILayout.Width(170));
_myruntime = ((RuntimeAnimatorController)EditorGUILayout.ObjectField(_myruntime, typeof(RuntimeAnimatorController), true, GUILayout.Width(300)));
GUILayout.FlexibleSpace();
GUI.enabled = _currentSelectionGameObject == TypeGameObject.GameObject;
switch (_selectedMode)
{
case 0:
GUILayout.Label("Path");
_replacePath = EditorGUILayout.TextField(_replacePath);
break;
case 1:
GUILayout.Label("GameObject");
_replaceGameObject = (GameObject)EditorGUILayout.ObjectField(_replaceGameObject, typeof(GameObject), true);
break;
}
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
EditorGUI.BeginChangeCheck();
GUILayout.Label("Selected Animation Clip", GUILayout.Width(170));
switch (_currentSelectionGameObject)
{
case TypeGameObject.GameObject:
GUI.enabled = true;
index = EditorGUILayout.Popup(index, _clipNames.ToArray(), GUILayout.Width(300));
if (index == 0)
{
_currentAnimationClips = _myanimationClips;
}
else
{
_currentAnimationClips = new List<AnimationClip>() { _myanimationClips[index - 1] };
}
break;
case TypeGameObject.None:
GUI.enabled = false;
EditorGUILayout.Popup(index, new string[] { "" }, GUILayout.Width(300));
animations = false;
break;
}
if (EditorGUI.EndChangeCheck())
{
FillModel();
}
GUI.enabled = _currentSelectionGameObject == TypeGameObject.GameObject;
GUILayout.FlexibleSpace();
GUILayout.Label("Replacement");
switch (_selectedMode)
{
case 0:
_replacementPath = EditorGUILayout.TextField(_replacementPath);
break;
case 1:
_replacementGameObject = (GameObject)EditorGUILayout.ObjectField(_replacementGameObject, typeof(GameObject), true);
break;
}
EditorGUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
if (GUILayout.Button("Replace", GUILayout.Width(205)))
{
Replace();
}
_gameObjects.Clear();
EditorGUILayout.EndHorizontal();
EditorGUILayout.Space();
EditorGUILayout.Space();
GUILayout.BeginHorizontal("Toolbar");
GUILayout.Label("Animation Clip", GUILayout.Width(188));
GUILayout.Label("Property");
GUILayout.Label("Path");
GUILayout.Label("Object", GUILayout.Width(150));
if (GUILayout.Button("Apply All", EditorStyles.toolbarButton, GUILayout.Width(70)))
{
foreach (var pathData in _pathDataList)
{
UpdatePath(pathData);
}
EditorGUI.FocusTextInControl(null);
}
if (GUILayout.Button("Revert All", EditorStyles.toolbarButton, GUILayout.Width(70)))
{
foreach (var pathData in _pathDataList)
{
Revert(pathData);
}
EditorGUI.FocusTextInControl(null);
}
GUI.enabled = true;
GUILayout.EndHorizontal();
EditorGUILayout.Space();
if (_currentSelectionGameObject != TypeGameObject.None)
{
if (_pathDataList != null)
{
scrollPosContent = EditorGUILayout.BeginScrollView(scrollPosContent);
foreach (var pathData in _pathDataList)
{
GUICreatePathItem(pathData);
}
EditorGUILayout.EndScrollView();
}
}
if (!animations)
{
EditorGUILayout.BeginHorizontal();
GUI.enabled = false;
EditorGUILayout.LabelField(new GUIContent(EditorGUIUtility.ObjectContent(null, typeof(Animator)).image), GUILayout.Width(16));
EditorGUILayout.LabelField("Property");
EditorGUILayout.TextField("SomeNewObject");
EditorGUILayout.ObjectField(null, typeof(GameObject), true);
GUILayout.Button("Apply", GUILayout.Width(60));
GUILayout.Button("Revert", GUILayout.Width(60));
GUILayout.EndHorizontal();
EditorGUILayout.Space();
EditorGUILayout.BeginHorizontal();
GUI.enabled = true;
GUILayout.FlexibleSpace();
EditorGUILayout.HelpBox("Please select a GameObject or Prefab with an Animator, Animation Clip or an Animator Controller.", MessageType.Info);
GUILayout.FlexibleSpace();
GUILayout.EndHorizontal();
}
}
private void Revert(PathData pathData)
{
pathData.CurrentPath = pathData.LastPath;
UpdatePath(pathData);
}
private void Replace()
{
switch (_selectedMode)
{
case 0:
if (string.IsNullOrEmpty(_replacePath))
{
return;
}
foreach (var pathData in _pathDataList)
{
pathData.CurrentPath = pathData.CurrentPath.Replace(_replacePath, _replacementPath);
}
break;
case 1:
if (_replaceGameObject == null || _replacementGameObject == null)
{
return;
}
foreach (var pathData in _pathDataList)
{
if (pathData.CurrentPath.Equals(ChildPath(_replaceGameObject)))
{
pathData.CurrentPath = ChildPath(_replacementGameObject);
}
}
break;
}
}
private void OnGUI()
{
DrawGui();
}
private void GUICreatePathItem(PathData pathData)
{
GameObject newObj;
GameObject obj;
obj = FindObjectInRoot(pathData.CurrentPath);
EditorGUILayout.BeginHorizontal();
GUIStyle propertyNameStyle = new GUIStyle(EditorStyles.label);
propertyNameStyle.richText = true;
GUIStyle pathNameStyle = new GUIStyle(EditorStyles.textField);
if (obj == null || obj.GetComponent(pathData.EditorCurve.type) == null)
{
propertyNameStyle.normal.textColor = Color.yellow;
pathNameStyle.normal.textColor = Color.yellow;
}
EditorGUILayout.LabelField(pathData.ClipName, GUILayout.Width(280));
GUILayout.Space(-90);
var lastPath = pathData.CurrentPath.Split('/').Last();
var gameObjectName = string.IsNullOrEmpty(lastPath) ? obj?.name : lastPath;
EditorGUILayout.LabelField(new GUIContent(EditorGUIUtility.ObjectContent(null, pathData.EditorCurve.type).image), GUILayout.Width(16));
EditorGUILayout.LabelField(
$"<i>{gameObjectName}</i> - " +
$"{string.Join(" ", Regex.Split(pathData.EditorCurve.type.Name, @"(?<!^)(?=[A-Z])"))} - " +
$"<b>{ObjectNames.NicifyVariableName(pathData.EditorCurve.propertyName)}</b>",
propertyNameStyle
);
GUIStyle buttonStyle = new GUIStyle(EditorStyles.miniButton);
if (!pathData.CurrentPath.Equals(pathData.EditorCurve.path))
{
buttonStyle.fontStyle = FontStyle.Bold;
pathNameStyle.fontStyle = FontStyle.Bold;
}
pathData.CurrentPath = EditorGUILayout.TextField(pathData.CurrentPath, pathNameStyle);
Color standardColor = GUI.color;
if (obj != null)
{
GUI.color = Color.white;
}
if (obj == null || obj.GetComponent(pathData.EditorCurve.type) == null)
{
GUI.color = Color.yellow;
}
newObj = (GameObject)EditorGUILayout.ObjectField(obj, typeof(GameObject), true, GUILayout.Width(150));
if (obj != null)
{
_gameObjects.Add(obj);
}
GUI.color = standardColor;
GUI.enabled = true;
buttonStyle.fontSize = 11;
buttonStyle.fixedHeight = 18;
buttonStyle.fixedWidth = 68;
if (GUILayout.Button("Apply", buttonStyle) && !pathData.CurrentPath.Equals(pathData.EditorCurve.path))
{
UpdatePath(pathData);
EditorGUI.FocusTextInControl(null);
}
buttonStyle.fontStyle = !pathData.LastPath.Equals(pathData.EditorCurve.path) ? FontStyle.Bold : FontStyle.Normal;
if (GUILayout.Button("Revert", buttonStyle) && pathData.CurrentPath.Equals(pathData.EditorCurve.path))
{
Revert(pathData);
}
EditorGUILayout.EndHorizontal();
try
{
if (obj != newObj)
{
pathData.CurrentPath = ChildPath(newObj);
}
}
catch (UnityException ex)
{
Debug.LogError(ex.Message);
}
}
private void OnInspectorUpdate()
{
this.Repaint();
}
private void FillModel()
{
try
{
_pathDataList = new List<PathData>();
foreach (var currentAnimationClip in _currentAnimationClips)
{
var pathDataListByClip = FillModelWithCurves(currentAnimationClip.name, AnimationUtility.GetCurveBindings(currentAnimationClip), currentAnimationClip);
var pathDataListByObjectReference = FillModelWithCurves(currentAnimationClip.name, AnimationUtility.GetObjectReferenceCurveBindings(currentAnimationClip), currentAnimationClip);
_pathDataList.AddRange(pathDataListByClip);
_pathDataList.AddRange(pathDataListByObjectReference);
}
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
private List<PathData> FillModelWithCurves(string clipName, EditorCurveBinding[] curves,AnimationClip clip)
{
var pathDataList = new List<PathData>();
foreach (var curve in curves)
{
var pathData = _pathDataList?.Find(pd => pd.EditorCurve.Equals(curve) && pd.ClipName == clipName);
if (pathData != null)
{
pathData.EditorCurve = curve;
pathDataList.Add(pathData);
}
else
{
pathDataList.Add(new PathData(clipName, curve.path, curve.path, curve, clip));
}
}
return pathDataList;
}
private void UpdatePath(PathData pathData)
{
if (pathData.CurrentPath.Equals(pathData.EditorCurve.path))
{
return;
}
pathData.LastPath = pathData.EditorCurve.path;
AssetDatabase.StartAssetEditing();
AnimationClip animationClip = pathData.Clip;
Undo.RecordObject(animationClip, "Animation Hierarchy Change");
AnimationCurve curve = AnimationUtility.GetEditorCurve(animationClip, pathData.EditorCurve);
ObjectReferenceKeyframe[] objectReferenceCurve = AnimationUtility.GetObjectReferenceCurve(animationClip, pathData.EditorCurve);
if (curve != null)
{
AnimationUtility.SetEditorCurve(animationClip, pathData.EditorCurve, null);
}
else
{
AnimationUtility.SetObjectReferenceCurve(animationClip, pathData.EditorCurve, null);
}
pathData.EditorCurve.path = pathData.CurrentPath;
if (curve != null)
{
AnimationUtility.SetEditorCurve(animationClip, pathData.EditorCurve, curve);
}
else
{
AnimationUtility.SetObjectReferenceCurve(animationClip, pathData.EditorCurve, objectReferenceCurve);
}
AssetDatabase.StopAssetEditing();
EditorUtility.ClearProgressBar();
FillModel();
this.Repaint();
}
private GameObject FindObjectInRoot(string path)
{
if (_animatorObject == null)
{
return null;
}
Transform child = _animatorObject.transform.Find(path);
if (child != null)
{
return child.gameObject;
}
else
{
return null;
}
}
private string ChildPath(GameObject obj, bool sep = false)
{
if (_animatorObject == null)
{
throw new UnityException("Please assign Referenced Animator (Root) first!");
}
if (obj == _animatorObject.gameObject)
{
return "";
}
else
{
if (obj.transform.parent == null)
{
throw new UnityException("Object must belong to " + _animatorObject.ToString() + "!");
}
else
{
return ChildPath(obj.transform.parent.gameObject, true) + obj.name + (sep ? "/" : "");
}
}
}
#endregion
#region Utility Methods
#endregion
#region Utility Events
#endregion
}
}

View File

@@ -1,12 +0,0 @@
fileFormatVersion: 2
guid: 8be52d198504f814db7f9d88b54c5a44
timeCreated: 1510337152
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: