c1_unity/Assets/Editor/InspectorTools/TimelineHelperInspector.cs
2023-04-03 11:04:31 +08:00

399 lines
14 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using BF;
using UnityEngine.Playables;
namespace BFEditor
{
[CustomEditor(typeof(TimelineHelper))]
public class TimelineHelperInspector : Editor
{
private const uint HASH_SEED = 31;
TimelineHelper helper;
private ISet<GameObject> gameobjectSet = new HashSet<GameObject>();
private ISet<uint> hashNameSet = new HashSet<uint>();
private ISet<string> nameSet = new HashSet<string>();
private ISet<uint> tlHashNameSet = new HashSet<uint>();
private ISet<string> tlNameSet = new HashSet<string>();
void OnEnable()
{
helper = target as TimelineHelper;
}
public override void OnInspectorGUI()
{
gameobjectSet.Clear();
hashNameSet.Clear();
nameSet.Clear();
tlHashNameSet.Clear();
tlNameSet.Clear();
GUILayout.Space(10);
for (int i = 0; i < helper.prefabList.Count; ++i)
{
DrawPrefab(i);
HashName(i);
CheckPrefabList(i);
}
DrawAddBtn();
DrawClipBoardBtn();
GUILayout.Space(10);
DrawTimelineEvent();
for (int i = 0; i < helper.timelineEventList.Count; ++i)
{
DrawTimelineEventItem(i);
HashTimelineEventName(i);
// CheckTimelineEventList(i);
}
DrawTimelineBtns();
}
void DrawPrefab(int index)
{
if (index < 0 || index >= helper.prefabList.Count)
return;
GUILayout.BeginHorizontal();
{
EditorGUI.BeginChangeCheck();
GameObject go = (GameObject)EditorGUILayout.ObjectField("", helper.prefabList[index].gameObject,
typeof(GameObject), true, GUILayout.Width(140));
if (EditorGUI.EndChangeCheck())
{
Undo.RecordObject(helper, helper.name + "Change GameObject Info GameObject");
GameObjectInfo info = new GameObjectInfo();
string path = "";
if (go == null)
{
info.gameObject = go;
}
else
{
Utils.GetTransformPath(go.transform, helper.transform, ref path);
path = path.Replace("/", ".");
info.gameObject = go;
info.name = path;
info.hashName = BKDRHash(path);
info.objectType = GetGameObjectType(go);
}
helper.prefabList[index] = info;
EditorUtility.SetDirty(helper);
}
if (GUILayout.Button("Copy", GUILayout.Width(55)))
{
Undo.RecordObject(helper, helper.name + "Copy Name");
EditorApplication.Beep();
TextEditor te = new TextEditor();
var goInfo = helper.prefabList[index];
te.text = goInfo.name;
te.SelectAll();
te.Copy();
}
if (GUILayout.Button("Remove", GUILayout.Width(55)))
{
Undo.RecordObject(helper, helper.name + "Remove GameObject Info");
EditorApplication.Beep();
helper.prefabList.RemoveAt(index);
EditorUtility.SetDirty(helper);
}
if (GUILayout.Button("Update", GUILayout.Width(55)))
{
Undo.RecordObject(helper, helper.name + "Update GameObject Info");
EditorApplication.Beep();
var goInfo = helper.prefabList[index];
var newPath = string.Empty;
Utils.GetTransformPath(go.transform, helper.transform, ref newPath);
newPath = newPath.Replace("/", ".");
goInfo.name = newPath;
goInfo.hashName = BKDRHash(newPath);
helper.prefabList[index] = goInfo;
EditorUtility.SetDirty(helper);
}
GUILayout.Label("Name", EditorStyles.label, GUILayout.Width(35));
EditorGUI.BeginChangeCheck();
string newName = GUILayout.TextField(helper.prefabList[index].name);
if (EditorGUI.EndChangeCheck())
{
Undo.RecordObject(helper, helper.name + "Change GameObject Info name");
GameObjectInfo info = new GameObjectInfo();
info.gameObject = helper.prefabList[index].gameObject;
info.name = newName;
info.hashName = BKDRHash(newName);
info.objectType = GetGameObjectType(info.gameObject);
helper.prefabList[index] = info;
EditorUtility.SetDirty(helper);
}
}
GUILayout.EndHorizontal();
}
void HashName(int index)
{
if (index < 0 || index >= helper.prefabList.Count)
return;
if (!string.IsNullOrEmpty(helper.prefabList[index].name))
{
uint hashName = BKDRHash(helper.prefabList[index].name);
if (hashName != helper.prefabList[index].hashName)
{
Undo.RecordObject(helper, helper.name + "add hash name");
GameObjectInfo info = new GameObjectInfo();
info.gameObject = helper.prefabList[index].gameObject;
info.name = helper.prefabList[index].name;
info.hashName = hashName;
info.objectType = GetGameObjectType(info.gameObject);
helper.prefabList[index] = info;
EditorUtility.SetDirty(helper);
}
}
}
void CheckPrefabList(int index)
{
if (index < 0 || index >= helper.prefabList.Count)
return;
GameObjectInfo info = helper.prefabList[index];
if (info.gameObject == null)
{
return;
}
if (!gameobjectSet.Add(info.gameObject))
{
Debug.LogError("prefab list have the same GameObject");
}
if (!hashNameSet.Add(info.hashName))
{
Debug.LogError("prefab list have the same hashName");
}
if (!nameSet.Add(info.name))
{
Debug.LogError("prefab list have the same name");
}
}
void DrawAddBtn()
{
if (GUILayout.Button("Add"))
{
Undo.RecordObject(helper, helper.name + "Add GameObject Info");
EditorApplication.Beep();
helper.prefabList.Add(new GameObjectInfo());
EditorUtility.SetDirty(helper);
}
}
void DrawClipBoardBtn()
{
if (GUILayout.Button("ClipBoardMap"))
{
string content = string.Empty;
var list = helper.prefabList;
for (int i = 0; i < list.Count; i++)
{
var info = list[i];
var itemDesc = string.Format("local {0} = uiMap['{1}']\n", info.gameObject.name, info.name);
content += itemDesc;
}
GUIUtility.systemCopyBuffer = content;
}
}
void DrawTimelineEvent()
{
var playableDir = helper.transform.GetComponent<PlayableDirector>();
if (playableDir)
{
helper.duration = playableDir.duration;
EditorGUI.BeginDisabledGroup(true);
EditorGUILayout.LabelField("timeline总时长", helper.duration.ToString());
EditorGUI.EndDisabledGroup();
}
}
void DrawTimelineBtns()
{
if (GUILayout.Button("Add TimeLine Event"))
{
Undo.RecordObject(helper, helper.name + "Add TimeLine Event");
EditorApplication.Beep();
helper.timelineEventList.TryAdd(new TimelineEventItem());
EditorUtility.SetDirty(helper);
}
if (GUILayout.Button("TimeLine Sort"))
{
SortTimelineEvent();
}
}
void DrawTimelineEventItem(int index)
{
if (index < 0 || index >= helper.timelineEventList.Count)
return;
GUILayout.BeginHorizontal();
{
EditorGUI.BeginChangeCheck();
GUILayout.Label("事件名称:", EditorStyles.label, GUILayout.Width(50));
var eventName = helper.timelineEventList[index].eventName;
eventName = EditorGUILayout.TextField(eventName, GUILayout.Width(140));
GUILayout.Label("触发时间:", EditorStyles.label, GUILayout.Width(50));
var eventTime = helper.timelineEventList[index].eventTime;
eventTime = Mathf.Clamp((float)EditorGUILayout.DoubleField(eventTime, GUILayout.Width(140)), 0, (float)helper.duration);
GUILayout.Label("回调名:", EditorStyles.label, GUILayout.Width(50));
EditorGUILayout.LabelField(helper.timelineEventList[index].eventHash.ToString(), GUILayout.Width(100));
if (EditorGUI.EndChangeCheck())
{
Undo.RecordObject(helper, helper.name + "Change TimelineEventItem");
TimelineEventItem info = new TimelineEventItem();
if (!string.IsNullOrEmpty(eventName))
{
info.eventName = eventName;
info.eventHash = GetTimelineEventHash(eventName);
info.eventTime = eventTime;
}
helper.timelineEventList[index] = info;
EditorUtility.SetDirty(helper);
}
if (GUILayout.Button("Remove", GUILayout.Width(55)))
{
Undo.RecordObject(helper, helper.name + "Remove TimelineEventItem");
EditorApplication.Beep();
helper.timelineEventList.RemoveAt(index);
EditorUtility.SetDirty(helper);
}
}
GUILayout.EndHorizontal();
}
void HashTimelineEventName(int index)
{
if (index < 0 || index >= helper.timelineEventList.Count)
return;
if (!string.IsNullOrEmpty(helper.timelineEventList[index].eventName))
{
uint hashName = BKDRHash(helper.timelineEventList[index].eventName);
if (hashName != helper.timelineEventList[index].eventHash)
{
Undo.RecordObject(helper, helper.name + "add hash name");
TimelineEventItem info = new TimelineEventItem();
info.eventName = helper.timelineEventList[index].eventName;
info.eventHash = hashName;
helper.timelineEventList[index] = info;
EditorUtility.SetDirty(helper);
}
}
}
void CheckTimelineEventList(int index)
{
if (index < 0 || index >= helper.timelineEventList.Count)
return;
TimelineEventItem info = helper.timelineEventList[index];
if(string.IsNullOrEmpty(info.eventName))
return;
if (!tlHashNameSet.Add(info.eventHash))
{
Debug.LogError("timeline event list have the same hashName");
}
if (!tlNameSet.Add(info.eventName))
{
Debug.LogError("timeline event list have the same name");
}
}
uint GetTimelineEventHash(string eventName)
{
var count = helper.timelineEventList.Count;
for (int i = 0; i < count; i++)
{
var item = helper.timelineEventList[i];
if (!string.IsNullOrEmpty(eventName) && item.eventName == eventName)
return item.eventHash;
}
return BKDRHash(eventName);
}
void SortTimelineEvent()
{
helper.timelineEventList.Sort((x, y) =>
{
return x.eventTime <= y.eventTime ? -1 : 1;
});
}
private static uint BKDRHash(string name)
{
uint h = 0;
var chars = name.ToCharArray();
for (int i = 0; i < chars.Length; ++i)
{
h = h * HASH_SEED + (byte)chars[i];
}
return h;
}
private static string GetGameObjectTypeName(int gameObjectType)
{
switch (gameObjectType){
case (int)GameObjectType.Default:
return "UI";
case (int)GameObjectType.UIObject:
return "UI预制件";
case (int)GameObjectType.EffectObject:
return "特效";
case (int)GameObjectType.CharacterObject:
return "角色";
case (int)GameObjectType.SpineMeshObject:
return "MeshSpine";
case (int)GameObjectType.SpineUIObject:
return "UISpine";
case (int)GameObjectType.TimelineObject:
return "TimeLine";
default:
return "UI";
}
}
private static int GetGameObjectType(GameObject go)
{
if (go == null)
{
return (int)GameObjectType.Default;
}
if (go.GetComponent<PrefabHelper>() != null)
{
return (int)GameObjectType.UIObject;
}
else if(go.GetComponent<EffectHelper>() != null)
{
return (int)GameObjectType.EffectObject;
}
else if(go.GetComponent<CharacterHelper>() != null)
{
return (int)GameObjectType.CharacterObject;
}
else if(go.GetComponent<TimelineHelper>() != null)
{
return (int)GameObjectType.TimelineObject;
}
else if(go.GetComponent<Spine.Unity.SkeletonGraphic>() != null)
{
return (int)GameObjectType.SpineUIObject;
}
else if(go.GetComponent<Spine.Unity.SkeletonAnimation>() != null)
{
return (int)GameObjectType.SpineMeshObject;
}
return (int)GameObjectType.Default;
}
}
}