Files
Main/Assets/Editor/DIY/SkillEditor/SkillEditor.cs

685 lines
25 KiB
C#
Raw Normal View History

2025-01-25 04:38:09 +08:00
using Thousandto.Code.Logic;
using Thousandto.Core.Asset;
using Thousandto.SkillEditor;
using Thousandto.SkillEditor.DIY;
using Thousandto.SkillEditor.Support;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;
using UnityEditor;
using UnityEngine;
namespace Thousandto.SkillEditor.DIY
{
public class SkillEditor : EditorWindow
{
#region//入口
[MenuItem("Ares/SkillEditor")]
static void OpenSkillEditor()
{
var curScenes = EditorBuildSettings.scenes;
var needSet = true;
var allScenes = new List<EditorBuildSettingsScene>();
for (int i = 0; i < curScenes.Length; ++i)
{
allScenes.Add(new EditorBuildSettingsScene(curScenes[i].path, true));
if (curScenes[i].path == "Assets/SkillEditor/EditorRes/Scene/EditorScene.unity")
{
needSet = false;
}
}
if (needSet)
{
allScenes.Add(new EditorBuildSettingsScene("Assets/SkillEditor/EditorRes/Scene/EditorScene.unity", true));
EditorBuildSettings.scenes = allScenes.ToArray();
EditorUtility.DisplayDialog("提示", "自动将EditorScene场景添加到BuildSetting请重新启动!", "确定");
EditorApplication.isPlaying = false;
return;
}
if (!EditorApplication.isPlaying)
{
EditorUtility.DisplayDialog("提示", "播放状态下才能打开技能编辑器!", "确定");
return;
}
SkillResPathEditor.InitResPath();
var win = (SkillEditor)EditorWindow.GetWindow(typeof(SkillEditor), true);
win.wantsMouseMove = true;
win.minSize = new Vector2(1860, 960);
win.maxSize = new Vector2(1860, 960);
win.Show();
win.Init();
IsOpen = true;
}
#endregion
#region//界面渲染
bool OnEditorModeGUI()
{
SkillEditorScene.OnGUI();
bool isLeftMouseDown = false;
bool isRightMouseUP = false;
switch (Event.current.type)
{
case EventType.ScrollWheel:
{
if (_buttomRect.Contains(Event.current.mousePosition))
{
float oldScale = _curFrameWidthScale;
_curFrameWidthScale -= Event.current.delta.y * 0.05f;
if (_curFrameWidthScale > FrameWidthMaxScale)
{
_curFrameWidthScale = FrameWidthMaxScale;
}
if (_curFrameWidthScale < FrameWidthMinScale)
{
_curFrameWidthScale = FrameWidthMinScale;
}
}
}
break;
case EventType.MouseDown:
{
if (_buttomRect.Contains(Event.current.mousePosition))
{
if (Event.current.button == 0)
{
//左键
isLeftMouseDown = true;
_draging = true;
}
else if (Event.current.button == 1)
{
//右键
isRightMouseUP = false;
}
}
if (SkillEventEditor.IsOpen)
{
SkillEventEditor.Hide();
}
}
break;
case EventType.MouseUp:
{
if (Event.current.button == 0)
{
//左键
isLeftMouseDown = false;
_curDragEvent = null;
_draging = false;
}
else if (Event.current.button == 1)
{
//右键
if (_buttomRect.Contains(Event.current.mousePosition))
{
isRightMouseUP = true;
}
}
}
break;
}
#region//左侧操作面板
GUILayout.BeginArea(_leftRect);
EditorGUILayout.BeginHorizontal();
if (GUILayout.Button("载入", GUILayout.Width(60)))
{
SkillEditorData.Load();
Init();
}
bool bSave = false;
if (GUILayout.Button("保存", GUILayout.Width(60)))
{
bSave = true;
}
if (GUILayout.Button("新技能", GUILayout.Width(60)))
{
SkillCreateAndChangeEditor.OpenCreate(this);
}
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginVertical();
GUILayout.Space(20);
GUILayout.Label("筛选技能");
EditorGUILayout.BeginHorizontal();
if (SkillFilterEditor.FilterKeys != null)
{
var newSelect = EditorGUILayout.Popup(_selectFilter, SkillFilterEditor.FilterKeys, GUILayout.Width(100));
if (newSelect != _selectFilter)
{
_limitSkillName = SkillFilterEditor.GetFilterText(SkillFilterEditor.FilterKeys[newSelect]);
_selectFilter = newSelect;
ResetSkillList(_limitSkillName);
SetSelectSkill(_curSelectSkillName);
}
}
if (GUILayout.Button("编辑筛选器", GUILayout.Width(90), GUILayout.Height(16)))
{
SkillFilterEditor.Open();
}
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
string tmpFindName = EditorGUILayout.TextField(_limitSkillName, GUILayout.Width(180));
if (_limitSkillName != tmpFindName)
{
ResetSkillList(tmpFindName);
SetSelectSkill(_curSelectSkillName);
}
if (GUILayout.Button("X", GUILayout.Width(16), GUILayout.Height(16)))
{
ResetSkillList("");
SetSelectSkill(_curSelectSkillName);
}
EditorGUILayout.EndHorizontal();
GUILayout.Label("技能列表");
if (_showSkillList.Count > 0)
{
int nowSelect = EditorGUILayout.Popup(_curSelectSkillIndex, _showSkillList.ToArray(), GUILayout.Width(200));
if (nowSelect != _curSelectSkillIndex)
{
//刷新界面
SetSelectSkill(_showSkillList[nowSelect]);
_curSelectSkillIndex = nowSelect;
}
}
else
{
GUILayout.Label("没有符合筛选文本的技能!");
}
GUILayout.Space(50);
var curSkill = SkillEditorData.FindSkill(_curSelectSkillName);
if (curSkill != null)
{
EditorGUILayout.BeginHorizontal();
GUILayout.Label("技能名字", GUILayout.Width(90));
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
EditorGUILayout.TextField(curSkill.Name, GUILayout.Width(160));
if (GUILayout.Button("修改", GUILayout.Width(36)))
{
SkillCreateAndChangeEditor.OpenChange(this, curSkill);
}
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
GUILayout.Label("是否是召唤对象", GUILayout.Width(110));
curSkill.IsSkillObject = EditorGUILayout.Toggle(curSkill.IsSkillObject, GUILayout.Width(20));
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
GUILayout.Label("受击效果对玩家有效", GUILayout.Width(110));
curSkill.IsPlayerValid = EditorGUILayout.Toggle(curSkill.IsPlayerValid, GUILayout.Width(20));
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
GUILayout.Label("结束清除特效", GUILayout.Width(110));
curSkill.EndClearVfx = EditorGUILayout.Toggle(curSkill.EndClearVfx, GUILayout.Width(20));
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
GUILayout.Label("等待服务器返回后再执行", GUILayout.Width(110));
curSkill.WaitServerResult = EditorGUILayout.Toggle(curSkill.WaitServerResult, GUILayout.Width(20));
EditorGUILayout.EndHorizontal();
if (GUILayout.Button("复制技能", GUILayout.Width(200), GUILayout.Height(20)))
{
CopySkill(curSkill);
}
if (GUILayout.Button("删除技能", GUILayout.Width(200)))
{
DeleteSkill(curSkill.Name);
EditorGUILayout.EndVertical();
GUILayout.EndArea();
return true;
}
}
EditorGUILayout.EndVertical();
GUILayout.EndArea();
if(bSave)
{
SkillEditorData.Save();
SkillEditorData.SaveBinary();
}
#endregion
#region//下侧播放面板
if (curSkill != null)
{
GUILayout.BeginArea(_buttomRect);
EditorGUILayout.BeginHorizontal();
curSkill.FrameCount = EditorGUILayout.IntField("技能帧数", curSkill.FrameCount, GUILayout.Width(200));
GUILayout.Space(30);
if (GUILayout.Button("播放", GUILayout.Width(100)))
{
if (Application.isPlaying)
{
SkillEditorScene.UseSkill(curSkill);
//SkillEditorPlayerUI.PlaySkill(curSkill.Name);
}
else
{
EditorUtility.DisplayDialog("提示", "在Unity播放模式下才能使用技能播放功能", "确定");
}
}
GUILayout.Space(30);
GUILayout.Label("显示走跑动作对比", GUILayout.Width(110));
_showPauseContrast = EditorGUILayout.Toggle(_showPauseContrast, GUILayout.Width(30));
GUILayout.Space(30);
GUILayout.Label("显示技能范围", GUILayout.Width(110));
EditorBaseObject.ShowSkillRange = EditorGUILayout.Toggle(EditorBaseObject.ShowSkillRange, GUILayout.Width(30));
EditorGUILayout.EndHorizontal();
_scrollPos = GUILayout.BeginScrollView(_scrollPos, true, false, GUILayout.Width(1820));
int drawFrameCount = Math.Max(PageFrameCount, curSkill.FrameCount);
var spaceCount = (int)(CurFrameWidth * drawFrameCount);
GUILayout.Box("", GUILayout.Width(spaceCount + 30));
Vector2 size = new Vector2(2, 50);
Vector2 pos = Vector2.zero;
Rect boxRect = new Rect();
Rect textRect = new Rect();
textRect.size = new Vector2(30, 20);
GUIStyle textStyle = new GUIStyle();
textStyle.alignment = TextAnchor.MiddleCenter;
GUIStyle eventStyle = new GUIStyle();
eventStyle.alignment = TextAnchor.MiddleCenter;
eventStyle.fontSize = 10;
float frontY = 0f;
int frontEventIndex = 0;
int diffIndex = Mathf.RoundToInt(24f / CurFrameWidth);
bool isShowEventMenu = false;
for (int i = 0; i < drawFrameCount; ++i)
{
pos.x = i * CurFrameWidth + 10;
textRect.position = new Vector2(pos.x - 15, 0);
if (i % 5 == 0)
{
GUI.Label(textRect, i.ToString(), textStyle);
boxRect.size = new Vector2(2, 240);
pos.y = 20;
boxRect.position = pos;
}
else
{
pos.y = 25;
boxRect.size = new Vector2(2, 230);
boxRect.position = pos;
}
if (i < curSkill.FrameCount)
{
GUI.color = Color.white;
}
else
{
GUI.color = Color.black;
}
GUI.Box(boxRect, string.Empty);
var eventList = curSkill.FindEventByFrame(i);
boxRect.size = new Vector2(24, 16);
if (i - frontEventIndex >= diffIndex)
{
frontY = 0;
}
int j = 0;
for (; j < eventList.Count; ++j)
{
GUI.color = Color.white;
boxRect.position = new Vector2(i * CurFrameWidth, frontY + 25 + j * 18);
frontEventIndex = i;
if (isLeftMouseDown && boxRect.Contains(Event.current.mousePosition))
{
_curDragEvent = eventList[j];
}
if (SkillEventEditor.IsOpen && SkillEventEditor.EventInfo == eventList[j])
{
GUI.color = Color.red;
}
if (GUI.Button(boxRect, GetEventName(eventList[j].EventType)))
{
if (isRightMouseUP)
{
_curDragEvent = null;
if (!isShowEventMenu)
{
var mousePos = Event.current.mousePosition;
_skillEventGo.name = string.Format("edit;{0};{1}", curSkill.Name, eventList[j].EventID);
EditorUtility.DisplayPopupMenu(new Rect(mousePos.x, mousePos.y, 0, 0), "CONTEXT/SkillEvent/", new MenuCommand(_skillEventGo));
isShowEventMenu = true;
}
}
else
{
//连续两次点击,打开编辑界面
SkillEventEditor.Open(eventList[j]);
}
}
}
GUI.color = Color.white;
frontY += j * 18;
pos.x -= (CurFrameWidth / 2 - 4);
boxRect.position = pos;
boxRect.size = new Vector2(CurFrameWidth, 200);
if (_draging && boxRect.Contains(Event.current.mousePosition))
{
_curSelectFrame = i;
if (_curDragEvent != null && i < curSkill.FrameCount)
{
_curDragEvent.EventFrame = i;
}
SkillEditorScene.DoPauseAnim(curSkill, _curSelectFrame, _showPauseContrast);
}
if (isRightMouseUP && boxRect.Contains(Event.current.mousePosition) && i < curSkill.FrameCount)
{
if (!isShowEventMenu)
{
var mousePos = Event.current.mousePosition;
_skillEventGo.name = string.Format("create;{0};{1}", curSkill.Name, i);
EditorUtility.DisplayPopupMenu(new Rect(mousePos.x, mousePos.y, 0, 0), "CONTEXT/SkillEvent/", new MenuCommand(_skillEventGo));
isShowEventMenu = true;
}
}
}
if (SkillEditorScene.LocalUser != null && SkillEditorScene.LocalUser.SkillManager.IsUsing && SkillEditorScene.LocalUser.SkillManager.CurSkill != null)
{
_curSelectFrame = SkillEditorScene.LocalUser.SkillManager.CurSkill.CurFrame;
if(SkillEditorScene.LocalUser.SkillManager.CurSkill.VisualInfo != curSkill)
{
curSkill = SkillEditorScene.LocalUser.SkillManager.CurSkill.VisualInfo;
}
}
GUI.color = Color.red;
boxRect.position = new Vector2(_curSelectFrame * CurFrameWidth + 10, 0);
boxRect.size = new Vector2(2, 280);
GUI.Box(boxRect, string.Empty);
GUI.color = Color.white;
GUILayout.EndScrollView();
GUILayout.EndArea();
}
#endregion
#region//右侧操作面板
GUILayout.BeginArea(_rightRect);
EditorGUILayout.BeginVertical();
SkillEditorPlayerUI.OnGUI();
EditorGUILayout.EndVertical();
GUILayout.EndArea();
#endregion
return true;
}
void OnGUI()
{
if (OnEditorModeGUI())
{
Repaint();
}
}
private void Update()
{
if (Application.isPlaying)
{
AudioPlayer.Update();
EditorVFXPlayer.Instance.Update();
SkillEditorScene.Update();
}
else
{
Close();
}
}
#endregion
#region//私有变量
private const float FrameWidthMaxScale = 1f;
private const float FrameWidthMinScale = 0.3f;
private Rect _leftRect = new Rect(10, 0, 200, 600);
private Rect _rightRect = new Rect(1650, 0, 200, 800);
private Rect _buttomRect = new Rect(10, 720, 1820, 240);
private float _curFrameWidthScale = 1f;
private int _curSelectFrame = 0;
private List<string> _showSkillList = new List<string>();
private int _curSelectSkillIndex = 0;
private string _curSelectSkillName = string.Empty;
private string _limitSkillName = string.Empty;
private SkillBaseEventInfo _curDragEvent = null;
private bool _draging = false;
private bool _frontPlayingState = false;
private float _sliderValue = 0f;
private const int PageFrameCount = 301;
private Vector2 _scrollPos = Vector2.zero;
private GameObject _skillEventGo = null;
private int _selectFilter = 0;
private bool _showPauseContrast = false;
#endregion
#region//属性
private float CurFrameWidth
{
get
{
return _curFrameWidthScale * 20;
}
}
public string CurSelectSkillName
{
get
{
return _curSelectSkillName;
}
}
public static bool IsOpen { get; private set; }
#endregion
#region//私有函数
//初始化
private void Init()
{
SkillFilterEditor.Init();
SkillEditorScene.Load();
_curFrameWidthScale = FrameWidthMaxScale;
_curSelectFrame = 0;
SkillEditorData.Load();
_limitSkillName = string.Empty;
ResetSkillList(_limitSkillName);
SetSelectSkill(string.Empty);
_draging = false;
_skillEventGo = new GameObject("SkillEditorTmp");
GameObject.DontDestroyOnLoad(_skillEventGo);
}
//创建新技能
public bool CreateNewSkill(string name)
{
if (SkillEditorData.CreateNewSkill(name))
{
_showSkillList.Add(name);
SetSelectSkill(name);
Repaint();
return true;
}
else
{
return false;
}
}
//删除技能
private void DeleteSkill(string name)
{
SkillEditorData.RemoveSkill(name);
ResetSkillList(_limitSkillName);
if (_showSkillList.Count <= 0)
{
//如果当前查找选项里边已经没有技能了,清空查找选项重新查找
ResetSkillList(string.Empty);
}
SetSelectSkill(string.Empty);
}
//复制技能
private void CopySkill(SkillVisualInfo skill)
{
var name = SkillEditorData.CopyNewSkill(skill);
_showSkillList.Add(name);
SetSelectSkill(name);
}
//修改名字
public bool ChangeSkillName(SkillVisualInfo skill, string newName)
{
for (int i = 0; i < SkillEditorData.SkillList.Count; ++i)
{
if (SkillEditorData.SkillList[i].Name == newName)
{
return false;
}
}
for (int i = 0; i < _showSkillList.Count; ++i)
{
if (_showSkillList[i] == skill.Name)
{
_showSkillList[i] = newName;
}
}
if (_curSelectSkillName == skill.Name)
{
_curSelectSkillName = newName;
}
skill.Name = newName;
Repaint();
return true;
}
string GetEventName(SkillEventDefine type)
{
string result = "None";
switch (type)
{
case SkillEventDefine.PlayAnimation:
result = "A";
break;
case SkillEventDefine.PlayVfx:
result = "V";
break;
case SkillEventDefine.PlaySfx:
result = "S";
break;
case SkillEventDefine.PlayCameraShake:
result = "K";
break;
case SkillEventDefine.PlayBlur:
result = "B";
break;
case SkillEventDefine.PlaySlow:
result = "L";
break;
case SkillEventDefine.PlayLockTrajectory:
result = "lt";
break;
case SkillEventDefine.DisableMove:
result = "dr";
break;
case SkillEventDefine.DisableChangeDir:
result = "dc";
break;
case SkillEventDefine.PlaySimpleSkillObject:
result = "so";
break;
case SkillEventDefine.PlaySkillObject:
result = "O";
break;
case SkillEventDefine.PlayHit:
result = "H";
break;
case SkillEventDefine.PlaySelfMove:
result = "M";
break;
case SkillEventDefine.PlayHideWeapon:
result = "W";
break;
case SkillEventDefine.PlayLinkDamage:
result = "L";
break;
}
return result;
}
public void OnDestroy()
{
IsOpen = false;
GameObject.DestroyImmediate(_skillEventGo, true);
SkillEventEditor.Hide();
SkillCreateAndChangeEditor.Hide();
SkillFilterEditor.Hide();
SkillEditorScene.UnLoad();
}
#endregion
#region//公有函数
//重新设置技能列表
public void ResetSkillList(string nameLimit)
{
_limitSkillName = nameLimit;
var skillList = SkillEditorData.SkillList;
_showSkillList.Clear();
for (int i = 0; i < skillList.Count; ++i)
{
if (string.IsNullOrEmpty(nameLimit) || skillList[i].Name.IndexOf(nameLimit) >= 0)
{
_showSkillList.Add(skillList[i].Name);
}
}
}
//设置选择的技能
public void SetSelectSkill(string skillName)
{
_curDragEvent = null;
SkillEventEditor.Hide();
if (_showSkillList.Count > 0)
{
_curSelectSkillIndex = 0;
_curSelectSkillName = _showSkillList[0];
}
for (int i = 0; i < _showSkillList.Count; ++i)
{
if (_showSkillList[i] == skillName)
{
_curSelectSkillIndex = i;
_curSelectSkillName = skillName;
}
}
}
#endregion
}
}