| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540 |
- using UnityEngine;
- using UnityEditor;
- using System.Collections.Generic;
- using System.Security;
- using Mono.Xml;
- using Flux;
- namespace FluxEditor
- {
- public class FSequenceWindowHeader
- {
- // padding on top, bottom, left and right
- public const float PADDING = 5;
- // space between labels and the fields
- public const float LABEL_SPACE = 5;
- // space between elements (i.e. label+field pairs)
- public const float ELEMENT_SPACE = 20;
- // height of the header
- public const float HEIGHT = 20 + PADDING + PADDING;
- private const float MAX_SEQUENCE_POPUP_WIDTH = 250;
- private const float UPDATE_MODE_FIELD_WIDTH = 100;
- private const float FRAMERATE_FIELD_WIDTH = 40;
- private const float LENGTH_FIELD_WIDTH = 100;
- // window this header belongs to
- private FSequenceEditorWindow _sequenceWindow;
- private SerializedObject _sequenceSO;
- private SerializedProperty _sequenceUpdateMode;
- private SerializedProperty _sequenceLength;
- // sequence selection popup variables
- private GUIContent _sequenceLabel = new GUIContent( "FrameEvents", "Select FrameEvent..." );
- // rect of the sequence label
- private Rect _sequenceLabelRect;
- // rect of the sequence name
- private Rect _sequencePopupRect;
- // rect for the button to create a new sequence
- private Rect _sequenceAddButtonRect;
- private FSequence[] _sequences;
- private GUIContent[] _sequenceNames;
- private int _selectedSequenceIndex;
- private GUIContent _fileLabel = new GUIContent("文件列表", "请选择编辑的buff文件");
- private Rect _fileLabelRect;
- private Rect _fileSearchRect;
- private Rect _fileListPopupRect;
- private List<string> mFrameEventFiles = new List<string>();
- private List<string> mFileNames = new List<string>();
- private List<string> mSearchFiles = new List<string>();
- private int _selectedFileIndex;
- private Dictionary<string, FSequence> mEventFileMapping = new Dictionary<string, FSequence>();
- // update mode UI variables
- private GUIContent _updateModeLabel = new GUIContent( "Update Mode", "How does the sequence update:\n\tNormal: uses Time.time in Update()\n\tAnimatePhysics: uses Time.fixedTime in FixedUpdate()\n\tUnscaledTime: uses Time.unscaledTime in Update()" );
- private Rect _updateModeLabelRect;
- private Rect _updateModeFieldRect;
- private bool _showUpdadeMode;
- // framerate UI variables
- private GUIContent _framerateLabel = new GUIContent( "Frame Rate", "How many frames does the sequence have per second" );
- private Rect _framerateLabelRect;
- private Rect _framerateFieldRect;
- private bool _showFramerate;
- // length UI variables
- private GUIContent _lengthLabel = new GUIContent( "Length", "What's the length of the sequence" );
- private Rect _lengthLabelRect;
- private Rect _lengthFieldRect;
- private bool _showLength;
- private GUIContent _addContainerLabel = new GUIContent( string.Empty, "新增新的FrameEvent" );
- private Rect _addContainerRect;
- private bool _showAddContainer;
- private GUIContent _openInspectorLabel = new GUIContent( string.Empty, "打开内容编辑" );
- private Rect _openInspectorRect;
- private GUIContent _saveEventLabel = new GUIContent(string.Empty, "保存内容");
- private Rect _saveEventRect;
- private GUIContent _refreshLabel = new GUIContent("刷新", "重新刷新技能编辑器");
- private Rect _refreshRect;
- // cached number field style, since we want numbers centered
- private GUIStyle _numberFieldStyle;
- private string searchContent = "";
- public FSequenceWindowHeader( FSequenceEditorWindow sequenceWindow )
- {
- _sequenceWindow = sequenceWindow;
- LoadFrameEventFromXml();
- RebuildSequenceList();
- EditorApplication.hierarchyWindowChanged += OnHierarchyChanged;
- _addContainerLabel.image = FUtility.GetFluxTexture("AddFolder.png");
- _openInspectorLabel.image = FUtility.GetFluxTexture("Inspector.png");
- _saveEventLabel.image = FUtility.GetFluxTexture("SkinSave.png");
- }
- private void OnHierarchyChanged()
- {
- RebuildSequenceList();
- }
- private void LoadFrameEventFromXml()
- {
- _selectedFileIndex = -1;
- mEventFileMapping.Clear();
- mFrameEventFiles.Clear();
- mFileNames.Clear();
- mSearchFiles.Clear();
- string[] fileList = FileUtils.TraverseAllFiles("Assets/Content/Xml/Skill", "*.xml");
- for (int idx = 0; idx < fileList.Length; idx++)
- {
- if (!fileList[idx].Contains("buff_")) continue;
- mFrameEventFiles.Add(fileList[idx]);
- }
- for (int idx = 0; idx < mFrameEventFiles.Count; idx++)
- {
- mFileNames.Add(FileUtils.RemoveExtension(FileUtils.ExtractPureName(mFrameEventFiles[idx])));
- }
- mSearchFiles.AddRange(mFileNames);
- }
- private void RebuildSequenceList()
- {
- _sequences = GameObject.FindObjectsOfType<FSequence>();
- System.Array.Sort<FSequence>( _sequences, delegate(FSequence x, FSequence y) { return x.name.CompareTo(y.name); } );
-
- _sequenceNames = new GUIContent[_sequences.Length+1];
- for( int i = 0; i != _sequences.Length; ++i )
- {
- _sequenceNames[i] = new GUIContent(_sequences[i].name);
- }
- _sequenceNames[_sequenceNames.Length-1] = new GUIContent("[Create New FrameEvent]");
- _selectedSequenceIndex = -1;
- }
- public void RebuildLayout( Rect rect )
- {
- rect.xMin += PADDING;
- rect.yMin += PADDING;
- rect.xMax -= PADDING;
- rect.yMax -= PADDING;
- float width = rect.width;
- _openInspectorRect = rect;
- _saveEventRect = rect;
- _updateModeLabelRect = _updateModeFieldRect = rect;
- _framerateLabelRect = _framerateFieldRect = rect;
- _lengthLabelRect = _lengthFieldRect = rect;
- _updateModeLabelRect.width = EditorStyles.label.CalcSize( _updateModeLabel ).x + LABEL_SPACE;
- _updateModeFieldRect.width = UPDATE_MODE_FIELD_WIDTH;
- _framerateLabelRect.width = EditorStyles.label.CalcSize( _framerateLabel ).x + LABEL_SPACE;
- _framerateFieldRect.width = FRAMERATE_FIELD_WIDTH;
- _lengthLabelRect.width = EditorStyles.label.CalcSize( _lengthLabel ).x + LABEL_SPACE;
- _lengthFieldRect.width = LENGTH_FIELD_WIDTH;
- _fileLabelRect = rect;
- _fileLabelRect.width = EditorStyles.label.CalcSize(_fileLabel).x + LABEL_SPACE;
- _fileSearchRect = rect;
- _fileSearchRect.xMin = _fileLabelRect.xMax;
- _fileSearchRect.width = 200;
- _fileListPopupRect = rect;
- _fileListPopupRect.xMin = _fileSearchRect.xMax;
- _fileListPopupRect.width = 200;
- _sequenceLabelRect = rect;
- _sequenceLabelRect.xMin = _fileListPopupRect.xMax + ELEMENT_SPACE;
- _sequenceLabelRect.width = EditorStyles.label.CalcSize( _sequenceLabel ).x + LABEL_SPACE;
- _sequencePopupRect = rect;
- _sequencePopupRect.xMin = _sequenceLabelRect.xMax;
- _sequencePopupRect.width = Mathf.Min( width - _sequenceLabelRect.width, MAX_SEQUENCE_POPUP_WIDTH );
- _sequenceAddButtonRect = rect;
- _sequenceAddButtonRect.xMin = _sequencePopupRect.xMax + LABEL_SPACE;
- _sequenceAddButtonRect.width = 16;
- float reminderWidth = width - _sequenceAddButtonRect.xMax;
- _addContainerRect = new Rect(0, 3, 22, 22);
- _addContainerRect.x = _sequencePopupRect.xMax + LABEL_SPACE;
- reminderWidth -= (ELEMENT_SPACE + _addContainerRect.width);
- _showAddContainer = reminderWidth >= 0;
- _saveEventRect.x = _addContainerRect.x + _addContainerRect.width + LABEL_SPACE + 20;
- _saveEventRect.width = 60;
- _refreshRect = rect;
- _refreshRect.xMin = _saveEventRect.xMax;
- _refreshRect.width = 100;
- _openInspectorRect.xMin = _openInspectorRect.xMax - 22;
- reminderWidth -= 22 + PADDING;
- _lengthFieldRect.x = rect.xMax - 22 - PADDING - _lengthFieldRect.width;
- _lengthLabelRect.x = _lengthFieldRect.xMin - _lengthLabelRect.width;
- reminderWidth -= (ELEMENT_SPACE + _lengthLabelRect.width + _lengthFieldRect.width);
- _showLength = reminderWidth >= 0;
- _framerateFieldRect.x = _lengthLabelRect.xMin - ELEMENT_SPACE - _framerateFieldRect.width;
- _framerateLabelRect.x = _framerateFieldRect.xMin - _framerateLabelRect.width;
- reminderWidth -= (_framerateLabelRect.width + _framerateFieldRect.width + ELEMENT_SPACE);
- _showFramerate = reminderWidth >= 0;
- _updateModeFieldRect.x = _framerateLabelRect.xMin - ELEMENT_SPACE - _updateModeFieldRect.width;
- _updateModeLabelRect.x = _updateModeFieldRect.xMin - _updateModeLabelRect.width;
- reminderWidth -= (_updateModeLabelRect.width + _updateModeFieldRect.width + ELEMENT_SPACE);
- _showUpdadeMode = reminderWidth >= 0;
- _numberFieldStyle = new GUIStyle( EditorStyles.numberField );
- _numberFieldStyle.alignment = TextAnchor.MiddleCenter;
- }
- public void OnGUI()
- {
- FSequence sequence = _sequenceWindow.GetSequenceEditor().Sequence;
- if( (_selectedSequenceIndex < 0 && sequence != null) || (_selectedSequenceIndex >= 0 && _sequences[_selectedSequenceIndex] != sequence) )
- {
- for( int i = 0; i != _sequences.Length; ++i )
- {
- if( _sequences[i] == sequence )
- {
- _selectedSequenceIndex = i;
- break;
- }
- }
- }
- if( Event.current.type == EventType.MouseDown && Event.current.alt && _sequencePopupRect.Contains(Event.current.mousePosition) )
- {
- Selection.activeObject = sequence;
- Event.current.Use();
- }
- EditorGUI.BeginChangeCheck();
- EditorGUI.PrefixLabel(_fileLabelRect, _fileLabel);
- searchContent = EditorGUI.TextField(_fileSearchRect, searchContent);
- if(EditorGUI.EndChangeCheck())
- {
- SearchFile(searchContent);
- }
- EditorGUI.BeginChangeCheck();
- int fileIdx = EditorGUI.Popup(_fileListPopupRect, _selectedFileIndex, mSearchFiles.ToArray());
- if (EditorGUI.EndChangeCheck())
- {
- _selectedFileIndex = fileIdx;
- string fileName = mSearchFiles[_selectedFileIndex];
- ReadFrameEvent(fileName);
- }
- EditorGUI.BeginChangeCheck();
- EditorGUI.PrefixLabel( _sequenceLabelRect, _sequenceLabel );
- int newSequenceIndex = EditorGUI.Popup( _sequencePopupRect, _selectedSequenceIndex, _sequenceNames );
- if( EditorGUI.EndChangeCheck() )
- {
- if( newSequenceIndex == _sequenceNames.Length-1 )
- {
- FSequence newSequence = FSequenceEditorWindow.CreateSequence();
- Selection.activeTransform = newSequence.transform;
- _sequenceWindow.GetSequenceEditor().OpenSequence( newSequence );
- }
- else
- {
- _selectedSequenceIndex = newSequenceIndex;
- _sequenceWindow.GetSequenceEditor().OpenSequence( _sequences[_selectedSequenceIndex] );
- _sequenceWindow.RemoveNotification();
- }
- EditorGUIUtility.keyboardControl = 0; // deselect it
- EditorGUIUtility.ExitGUI();
- }
- // if we're in play mode, can't change anything
- if( Application.isPlaying )
- GUI.enabled = false;
- if( sequence == null )
- return;
- if( _sequenceSO == null || _sequenceSO.targetObject != sequence )
- {
- _sequenceSO = new SerializedObject( sequence );
- _sequenceUpdateMode = _sequenceSO.FindProperty( "_updateMode" );
- _sequenceLength = _sequenceSO.FindProperty( "_length" );
- }
- _sequenceSO.Update();
- if( _showUpdadeMode )
- {
- EditorGUI.PrefixLabel( _updateModeLabelRect, _updateModeLabel );
- EditorGUI.PropertyField( _updateModeFieldRect, _sequenceUpdateMode, GUIContent.none );
- }
- if( _showFramerate )
- {
- EditorGUI.PrefixLabel( _framerateLabelRect, _framerateLabel );
- EditorGUI.BeginChangeCheck();
- int newFrameRate = FGUI.FrameRatePopup( _framerateFieldRect, sequence.FrameRate );
- if( EditorGUI.EndChangeCheck() )
- {
- if( newFrameRate == -1 )
- {
- FChangeFrameRateWindow.Show( new Vector2(_framerateLabelRect.xMin, _framerateLabelRect.yMax), sequence, FSequenceInspector.Rescale );
- }
- else
- {
- FSequenceInspector.Rescale( sequence, newFrameRate, true );
- }
- }
- }
-
- if( _showLength )
- {
- EditorGUI.PrefixLabel( _lengthLabelRect, _lengthLabel );
- _sequenceLength.intValue = Mathf.Clamp( EditorGUI.IntField( _lengthFieldRect, _sequenceLength.intValue, _numberFieldStyle ), 1, int.MaxValue );
- }
- GUIStyle s = new GUIStyle(EditorStyles.miniButton);
- s.padding = new RectOffset(1, 1, 1, 1);
- if( _showAddContainer )
- {
- if( FGUI.Button( _addContainerRect, _addContainerLabel ) )
- {
- AddContainer();
- }
- }
- if (FGUI.Button(_openInspectorRect, _openInspectorLabel))
- {
- FInspectorWindow.Open();
- }
- if (FGUI.Button(_saveEventRect, _saveEventLabel))
- {
- SaveContainer();
- }
- _sequenceSO.ApplyModifiedProperties();
- if (FGUI.Button(_refreshRect, _refreshLabel))
- {
- Refresh();
- }
- GUI.enabled = true;
- }
- private void Refresh()
- {
- if (_sequences == null) return;
- for (int idx = 0; idx < _sequences.Length; idx++)
- {
- _sequences[idx].ResetDefaultVal();
- }
- }
- private void AddContainer()
- {
- GenericMenu menu = new GenericMenu();
- bool hasDefaultContainers = false;
- List<FColorSetting> defaultContainers = FUtility.GetSettings().DefaultContainers;
- foreach( FColorSetting colorSetting in defaultContainers )
- {
- if( string.IsNullOrEmpty(colorSetting._str) )
- continue;
- menu.AddItem( new GUIContent( colorSetting._str ), false, CreateContainer, colorSetting );
- hasDefaultContainers = true;
- }
- if( !hasDefaultContainers )
- {
- _sequenceWindow.GetSequenceEditor().CreateContainer( new FColorSetting("Default", FGUI.DefaultContainerColor()) );
- return;
- }
- menu.AddSeparator(null);
- menu.AddItem( new GUIContent( "[Default New Container]" ), false, CreateContainer, new FColorSetting("Default", FGUI.DefaultContainerColor()) );
- menu.ShowAsContext();
- }
- private void CreateContainer( object data )
- {
- _sequenceWindow.GetSequenceEditor().CreateContainer( (FColorSetting)data );
- }
- private void SaveContainer()
- {
- _sequenceWindow.GetSequenceEditor().SaveToXml();
- }
- private void ReadFrameEvent(string fileName)
- {
- if (mEventFileMapping.ContainsKey(fileName))
- {
- Debug.LogError("文件 " + fileName + " 已经打开过");
- return;
- }
- string filePath = Constants.XmlConfig + "/Skill/" + fileName + ".xml";
- TextAsset ta = AssetDatabase.LoadAssetAtPath(filePath, typeof(TextAsset)) as TextAsset;
- if(ta == null)
- {
- Debug.LogError("加载文件:" + fileName + "失败!!");
- return;
- }
- SecurityParser doc = new SecurityParser();
- try
- {
- doc.LoadXml(ta.text);
- }
- catch (System.Exception e)
- {
- DebugHelper.LogError(string.Format("Load Frame Event, exception = {0}", e.Message));
- return;
- }
- SecurityElement root = doc.SelectSingleNode("FrameEvent");
- if (root == null || root.Children == null) return;
- for (int idx = 0; idx < root.Children.Count; idx++)
- {
- var buffNode = root.Children[idx] as SecurityElement;
- if (buffNode.Tag.CompareTo("buff") != 0) continue;
- int endFrame = 0;
- int.TryParse(buffNode.Attribute("endFrame"), out endFrame);
- string casterName = buffNode.Attribute("caster");
- string targetName = buffNode.Attribute("target");
- FSequence sequence = FSequence.CreateSequence();
- sequence.FrameRate = 30;
- sequence.Length = endFrame;
- if(!string.IsNullOrEmpty(casterName))
- sequence.CasterActor = GameObject.Find(casterName);
- if(!string.IsNullOrEmpty(targetName))
- sequence.TargetActor = GameObject.Find(targetName);
- sequence.CameraGo = Camera.main.gameObject;
- FTimeline timeline = FTimeline.Create(sequence.transform);
- sequence.Containers[0].Add(timeline);
- timeline.LoadFromXml(buffNode);
- Selection.activeTransform = sequence.transform;
- _sequenceWindow.GetSequenceEditor().OpenSequence(sequence);
- if(!mEventFileMapping.ContainsKey(fileName))
- {
- mEventFileMapping.Add(fileName, sequence);
- }
- else
- {
- string newFileName = fileName + "_" + timeline.Gender;
- mEventFileMapping.Add(newFileName, sequence);
- }
- }
- }
- public void Destroy()
- {
- foreach(var pair in mEventFileMapping)
- {
- GameObject.DestroyImmediate(pair.Value.gameObject);
- }
- mEventFileMapping.Clear();
- }
- private void SearchFile(string content)
- {
- mSearchFiles.Clear();
- for(int idx =0; idx < mFileNames.Count;idx++)
- {
- string name = mFileNames[idx];
- if(name.StartsWith(content))
- {
- mSearchFiles.Add(name);
- }
- }
- }
- }
- }
|