時間軸編輯器


using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
using UnityEditor;
using UnityEngine;

public static class HandleUtilityWrapper
{
    private static Type realType;
    private static PropertyInfo s_property_handleWireMaterial;

    private static void InitType()
    {
        if (realType == null)
        {
            Assembly assembly = Assembly.GetAssembly(typeof(Editor));
            realType = assembly.GetType("UnityEditor.HandleUtility");

            s_property_handleWireMaterial = realType.GetProperty("handleWireMaterial", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);
        }
    }

    public static Material handleWireMaterial
    {
        get
        {
            InitType();
            return s_property_handleWireMaterial.GetValue(null, null) as Material;
        }
    }
}

public class NewBehaviourScript : EditorWindow
{
    public static NewBehaviourScript editor;


    #region 屬性

    private EventKey mytargetEvent;
    public static EventKey myclipboard;



    private string targetAvatar;
    private Dictionary<string, object> currAvatar;
    private int selectedAvatar = 0;
    private int OldSelectAvatar = -1;
    private Vector2 avatarPanelScrollPos;
    private string currAvatarName = string.Empty;
    private string currAvatarNameField = string.Empty;
    private Vector2 avatarPropPanelScrollPos;
  
    private Vector2 eventPanelScrollPos;
    private int selectedEvent = 1;
    private Vector2 subeventPanelScrollPos;
    private int selectedsubEvent = 0;
    private float playbackTime = 0.0f;
    private bool enableTempPreview = false;
    private float tempPreviewPlaybackTime = 0.0f;
    private static int timelineHash = "timelinecontrol".GetHashCode();
    private bool bPlayLoop = true;
    private bool bPlaying = false;
    private bool bDoAvatarEditor = false;
    private bool bDragging = false;
    private bool bDraggingKey = false;

    private Vector2 propPanelScrollPos;
    private Vector2 propSubPanelScrollPos;
    private int hotEventKey = 0;
    private List<Dictionary<string, object>> SkillDict;

    private Vector2 skillpropPanelScrollPos;
    private Dictionary<string, object> currSkillData;
    private Vector2 controllerPanelScrollPos;
    private int selectedController = 0;
    private int OldSelectedController = -1;
    private Dictionary<string, object> currSeq;
    private Vector2 actionPanelScrollPos;
    private int selectedAction = 0;
    private int OldSelectedAction = -1;
    private Vector2 seqpropPanelScrollPos;




    public AnimationState CurrAnimState
    {
        get; set;
    }

    public float PlaybackTime
    {
        get { return playbackTime; }
    }
    #endregion

    [MenuItem("Tools/test")]
    static void Init()
    {
        editor = EditorWindow.GetWindow<NewBehaviourScript>();
    }

    void OnEnable()
    {
        //OldSelectAvatar = -1;
        //selectedAvatar = 0;
        //bDoAvatarEditor = false;
        //LoadSkillTemplate();

        //minSize = new Vector2(850, 320);
        //if (this.mTaskList == null)
        //{
        //    this.mTaskList = ScriptableObject.CreateInstance<ActionList>();
        //}
        //this.mTaskList.Init();
        editor = EditorWindow.GetWindow<NewBehaviourScript>();
    }

    void OnGUI()
    {
        GUILayout.BeginHorizontal();
        {
            DrawAvatarPanel();
            DrawActionProperty();
        }
        GUILayout.EndHorizontal();

        GUILayout.BeginHorizontal(GUILayout.MaxHeight(100));
        {

            DrawTimelinePanel();

        }
        GUILayout.EndHorizontal();
    }

    void DrawAvatarPanel()
    {
        List<string> names = new List<string>();
        names.Add("111");
        names.Add("211");
        names.Add("311");

        GUILayoutOption[] optionArray = new GUILayoutOption[] { GUILayout.Width(100) };
        GUILayout.BeginVertical(optionArray);


        GUILayout.BeginVertical("Box");

        Vector2 pos = new Vector2(30, 200);
        pos = GUILayout.BeginScrollView(pos);
        selectedEvent = GUILayout.SelectionGrid(selectedEvent, names.ToArray(), 1);
        GUILayout.EndScrollView();

        GUILayout.EndVertical();

        GUILayout.EndVertical();
    }

    void DrawActionProperty()
    {
        GUILayout.BeginVertical("Box");
        Vector2 pos = new Vector2(100, 200);
        GUILayout.Label("Action properties:");
        pos = GUILayout.BeginScrollView(pos);
        {
            

        }
        GUILayout.EndScrollView();
        GUILayout.EndVertical();
    }

    void DrawTimelinePanel()
    {

        if (!enableTempPreview)
            playbackTime = GetPlaybackTime();


        GUILayout.BeginVertical();
        {

            GUILayout.Space(10);

            GUILayout.BeginHorizontal();
            {

                GUILayout.Space(20);

                playbackTime = Timeline(playbackTime);

                GUILayout.Space(10);

            }


            GUILayout.EndHorizontal();

            GUILayout.FlexibleSpace();

            GUILayout.BeginHorizontal();
            {

                GUILayout.FlexibleSpace();
                bPlayLoop = GUILayout.Toggle(bPlayLoop, "loop");
                if (bPlaying)
                {
                    if (GUILayout.Button("Stop", GUILayout.Width(80)))
                    {
                        if (CurrAnimState != null)
                        {
                            CurrAnimState.speed = 0f;
                        }
                        //CallMethod("StopSkill");
                        bPlaying = false;
                    }

                }
                else
                {
                    if (GUILayout.Button("Play", GUILayout.Width(80)))
                    {
                        //CallMethod("PlaySkill", bPlayLoop);
                        bPlaying = true;
                    }
                }
                if (bPlaying)
                {
                    if (GUILayout.Button("Pause", GUILayout.Width(80)))
                    {
                        if (CurrAnimState != null)
                        {
                            CurrAnimState.speed = 0f;
                        }
                       // CallMethod("StopSeq");
                        bPlaying = false;
                    }

                }
                else
                {
                    if (GUILayout.Button("PlaySeq", GUILayout.Width(80)))
                    {
                        //CallMethod("PlaySeq", bPlayLoop);
                        bPlaying = true;
                    }
                }


                EditorGUI.BeginDisabledGroup(mytargetEvent == null);


                //if (GUILayout.Button("Duplicate", GUILayout.Width(80)))
                //{
                //    ActionType entry = TaskTemplateManager.Instance.GetActionType(targetEvent.TypeName);
                //    ActionTypeData actTypeData = new ActionTypeData { type = typeof(LuaAction), scriptAction = entry };
                //    LuaAction oldTargetEvent = targetEvent;
                //    LuaAction newtargetEvent = this.AddEffect(actTypeData);
                //    newtargetEvent.Clone(oldTargetEvent);
                //}

                //if (GUILayout.Button("Copy", GUILayout.Width(80)))
                //{
                //    clipboard = TaskUtility.CreateInstance(targetEvent) as LuaAction;
                //    clipboard.Clone(targetEvent);
                //}

                EditorGUI.EndDisabledGroup();

                //EditorGUI.BeginDisabledGroup(clipboard == null);

                //if (GUILayout.Button("Paste", GUILayout.Width(80)))
                //{
                //    targetEvent.Clone(clipboard);
                //    SaveData();
                //}

                //EditorGUI.EndDisabledGroup();

                //EditorGUI.BeginDisabledGroup(targetEvent == null);



                //EditorGUI.EndDisabledGroup();

                //if (GUILayout.Button("Save", GUILayout.Width(80)))
                //{
                //    SaveData();
                //}
                //if (GUILayout.Button("Syn", GUILayout.Width(80)))
                //{
                //    SynData();
                //}
                //if (GUILayout.Button("Close", GUILayout.Width(80)))
                //{
                //    Close();
                //}

            }
            GUILayout.EndHorizontal();

        }
        GUILayout.EndVertical();
        //if (!IsPlaying())
        //{
        //    SetPlaybackTime(tempPreviewPlaybackTime);
        //    StopPlaying();
        //}
    }

    #region 界面7的方法

    public List<EventKey> eventList = new List<EventKey>();

    private float Timeline(float time)
    {

        Rect rect = GUILayoutUtility.GetRect(500, 10000, 50, 50);

        int timelineId = GUIUtility.GetControlID(timelineHash, FocusType.Passive, rect);

        Rect thumbRect = new Rect(rect.x + rect.width * time - 5, rect.y + 2, 10, 10);

        Event e = Event.current;

        switch (e.type)
        {
            case EventType.Repaint:
                Rect lineRect = new Rect(rect.x, rect.y + 10, rect.width, 1.5f);
                DrawTimeLine(lineRect, time);
                GUI.skin.horizontalSliderThumb.Draw(thumbRect, new GUIContent(), timelineId);
                break;

            case EventType.MouseDown:
                if (thumbRect.Contains(e.mousePosition))
                {
                    this.bDragging = false;
                    GUIUtility.hotControl = timelineId;
                    tempPreviewPlaybackTime = GetPlaybackTime();
                    e.Use();

                    if (CurrAnimState != null)
                    {
                        CurrAnimState.normalizedSpeed = 0;
                        CurrAnimState.normalizedTime = time;
                    }
                }
                break;

            case EventType.MouseUp:
                if (GUIUtility.hotControl == timelineId)
                {
                    if (!this.bDragging && thumbRect.Contains(e.mousePosition))
                    {
                        // Now create the menu, add items and show it
                        //GenericMenu menu = new GenericMenu();
                        //this.mTaskList.AddTasksToMenu(ref menu, null, "", new GenericMenu.MenuFunction2(this.addMenuEffect));
                        //menu.ShowAsContext();

                        GenericMenu menu = new GenericMenu();
                        menu.AddItem(new GUIContent("MenuItem1"), false, new GenericMenu.MenuFunction2(this.AddMenuCallback), "item 1");
                        menu.AddItem(new GUIContent("MenuItem2"), false, new GenericMenu.MenuFunction2(this.AddMenuCallback), "item 2");
                        menu.AddSeparator("");
                        menu.AddItem(new GUIContent("SubMenu/MenuItem3"), false, new GenericMenu.MenuFunction2(this.AddMenuCallback), "item 3");
                        menu.ShowAsContext();
                    }
                    GUIUtility.hotControl = 0;
                    e.Use();
                    this.bDragging = false;
                }
                break;

            case EventType.MouseDrag:
                if (GUIUtility.hotControl == timelineId)
                {
                    this.bDragging = true;
                    Vector2 guiPos = e.mousePosition;
                    float clampedX = Mathf.Clamp(guiPos.x, rect.x, rect.x + rect.width);
                    time = (clampedX - rect.x) / rect.width;
                    tempPreviewPlaybackTime = time;
                    e.Use();
                    if (CurrAnimState != null)
                    {
                        CurrAnimState.normalizedTime = time;
                        CurrAnimState.speed = 0f;
                    }
                }
                break;
        }

        //if (displayEvents != null)
        //{

        //    foreach (LuaAction me in displayEvents)
        //    {

        //        if (me == targetEvent)
        //            continue;

        //        DrawEventKey(rect, me);
        //    }

        //    if (targetEvent != null)
        //        DrawEventKey(rect, targetEvent);
        //    SortEvents();
        //}

        foreach (var me in eventList)
        {
             DrawEventKey2(rect, me);
        }

        return time;
    }

    public class EventKey {
        public float normalizedTime;
        public string TypeName;
    }

    private void DrawTimeLine(Rect rect, float currentFrame)
    {
        if (Event.current.type != EventType.Repaint)
        {
            return;
        }

        HandleUtilityWrapper.handleWireMaterial.SetPass(0);
        Color c = new Color(1f, 0f, 0f, 0.75f);
        GL.Color(c);

        GL.Begin(GL.LINES);
        GL.Vertex3(rect.x, rect.y, 0);
        GL.Vertex3(rect.x + rect.width, rect.y, 0);

        GL.Vertex3(rect.x, rect.y + 25, 0);
        GL.Vertex3(rect.x + rect.width, rect.y + 25, 0);


        for (int i = 0; i <= 100; i += 1)
        {
            if (i % 10 == 0)
            {
                GL.Vertex3(rect.x + rect.width * i / 100f, rect.y, 0);
                GL.Vertex3(rect.x + rect.width * i / 100f, rect.y + 15, 0);
            }
            else if (i % 5 == 0)
            {
                GL.Vertex3(rect.x + rect.width * i / 100f, rect.y, 0);
                GL.Vertex3(rect.x + rect.width * i / 100f, rect.y + 10, 0);
            }
            else
            {
                GL.Vertex3(rect.x + rect.width * i / 100f, rect.y, 0);
                GL.Vertex3(rect.x + rect.width * i / 100f, rect.y + 5, 0);
            }
        }

        c = new Color(1.0f, 1.0f, 1.0f, 0.75f);
        GL.Color(c);

        GL.Vertex3(rect.x + rect.width * currentFrame, rect.y, 0);
        GL.Vertex3(rect.x + rect.width * currentFrame, rect.y + 20, 0);

        GL.End();
    }


    private void DrawEventKey2(Rect rect, EventKey key)
    {
        float keyTime = key.normalizedTime;

        Rect keyRect = new Rect(rect.x + rect.width * keyTime - 3, rect.y + 25, 6, 18);

        int eventKeyCtrl = key.GetHashCode();

        Event e = Event.current;

        switch (e.type)
        {
            case EventType.Repaint:
                Color savedColor = GUI.color;

                if (mytargetEvent == key)
                    GUI.color = Color.red;
                else
                    GUI.color = Color.green;

                GUI.skin.button.Draw(keyRect, new GUIContent(), eventKeyCtrl);

                GUI.color = savedColor;

                if (hotEventKey == eventKeyCtrl || (hotEventKey == 0 && keyRect.Contains(e.mousePosition)))
                {
                    string labelString = string.Format("{0}@{1}", key.TypeName, key.normalizedTime.ToString("0.0000"));
                    Vector2 size = EditorStyles.largeLabel.CalcSize(new GUIContent(labelString));

                    Rect infoRect = new Rect(rect.x + rect.width * keyTime - size.x / 2, rect.y + 50, size.x, size.y);
                    EditorStyles.largeLabel.Draw(infoRect, new GUIContent(labelString), eventKeyCtrl);
                }
                break;
            case EventType.MouseDown:
                this.bDraggingKey = false;
                if (keyRect.Contains(e.mousePosition))
                {

                    hotEventKey = eventKeyCtrl;
                    enableTempPreview = true;
                    tempPreviewPlaybackTime = key.normalizedTime;

                    SetActiveEvent(key);
                    e.Use();
                }
                break;

            case EventType.MouseDrag:
                this.bDraggingKey = true;
                if (hotEventKey == eventKeyCtrl)
                {

                    if (e.button == 0)
                    {
                        Vector2 guiPos = e.mousePosition;
                        float clampedX = Mathf.Clamp(guiPos.x, rect.x, rect.x + rect.width);
                        key.normalizedTime = (clampedX - rect.x) / rect.width;
                        tempPreviewPlaybackTime = key.normalizedTime;

                        SetActiveEvent(key);
                        //StopPlaying();
                    }

                    e.Use();
                }
                break;
            case EventType.MouseUp:
                if (hotEventKey == eventKeyCtrl)
                {
                    hotEventKey = 0;
                    enableTempPreview = false;
                    // SetPlaybackTime(playbackTime);       // reset to original time
                    if (!bDraggingKey)
                    {
                        GenericMenu menu = new GenericMenu();
                        GenericMenu.MenuFunction2 callback = delegate (object obj)
                        {
                            int id = (int)obj;

                            switch (id)
                            {
                                case 1:
                                    {
                                        //clipboard = TaskUtility.CreateInstance(targetEvent) as LuaAction;
                                        myclipboard = myclipboard;
                                        break;
                                    }

                                case 2:
                                    {
                                        myclipboard = myclipboard;
                                        // SaveData();
                                        break;
                                    }
                                case 3:
                                    {
                                       // DelEvent(myclipboard);
                                        break;
                                    }
                                case 4:
                                    //myclipboard.isEnable = !targetEvent.isEnable;
                                    break;

                            }
                        };

                        if (mytargetEvent == null)
                            menu.AddDisabledItem(new GUIContent("Copy"));
                        else
                            menu.AddItem(new GUIContent("Copy"), false, callback, 1);

                        if (mytargetEvent == null || myclipboard == null)
                            menu.AddDisabledItem(new GUIContent("Paste"));
                        else
                            menu.AddItem(new GUIContent("Paste"), false, callback, 2);

                        if (mytargetEvent == null)
                            menu.AddDisabledItem(new GUIContent("Del"));
                        else
                            menu.AddItem(new GUIContent("Del"), false, callback, 3);

                        //if (mytargetEvent != null)
                        //    menu.AddItem(new GUIContent(mytargetEvent.isEnable ? "Disable" : "Enable"), false, callback, 4);

                        menu.ShowAsContext();
                        e.Use();
                    }
                    this.bDraggingKey = false;
                }
                break;

        }
    }

    private void SetActiveEvent(EventKey key)
    {
        int i = eventList.IndexOf(key);
        if (i >= 0)
        {
            selectedEvent = i;
            mytargetEvent = key;
        }
    }

    //private void SetActiveEvent(LuaAction key)
    //{
    //    int i = displayEvents.IndexOf(key);
    //    if (i >= 0)
    //    {
    //        selectedEvent = i;
    //        targetEvent = key;
    //    }
    //}

    //public void DelEvent(LuaAction e)
    //{
    //    if (displayEvents != null)
    //    {
    //        CallMethod("RemSkillAction", displayEvents.IndexOf(e) + 1);

    //        displayEvents.Remove(e);
    //        selectedEvent = 0;
    //        selectedsubEvent = 0;
    //        targetEvent = null;
    //        targetSubEvent = null;
    //    }
    //}
    #endregion

    #region 數據管理

    void AddMenuCallback(object obj)
    {
        Debug.Log("Selected: " + obj);

        EventKey eventKey = new EventKey();
        eventKey.normalizedTime = playbackTime;
        eventKey.TypeName = obj.ToString();

        eventList.Add(eventKey);
    }

    public float GetPlaybackTime()
    {
        if (CurrAnimState != null)
        {
            return CurrAnimState.normalizedTime - (int)CurrAnimState.normalizedTime;
        }
        return 0;
    }


    #endregion
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章