Files
Main/Assets/Editor/DIY/SkillEditor/SkillEditor.cs
2025-01-25 04:38:09 +08:00

685 lines
25 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 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
}
}