399 lines
14 KiB
C#
399 lines
14 KiB
C#
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;
|
||
}
|
||
}
|
||
}
|