NLDClient-yudde/ProjectNLD/Assets/Editor/CharacterBuilder/CharacterBuilderWindow.cs

406 lines
15 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using System;
using System.Collections.Generic;
using DG.DemiEditor;
using Framework;
using Gameplay.Utils;
using UnityEditor;
using UnityEngine;
namespace CharacterBuilder
{
public class CharacterBuilderWindow : EditorWindow
{
[MenuItem("Tools/构建器/角色构建器")]
public static void ShowWindow()
{
var window = GetWindow<CharacterBuilderWindow>();
window.titleContent = new UnityEngine.GUIContent("角色构建器");
window.Show();
}
// [MenuItem("Test/测试")]
// public static void TestFunc()
// {
// }
private Vector2 _scrollPos1;
private Vector2 _scrollPos2;
private GUIStyle _styleNormal;
private GUIStyle _styleError;
private List<CharacterBuildData> _characterBuildDataList;
private List<NpcBuildData> _npcBuildDataList;
private Dictionary<string, AnimationClip> _animclipMap;
private void _CheckAllConfigs()
{
// 加载指定路径下的所有animationclip文件
var allAnimationClips = AssetDatabase.FindAssets("t:AnimationClip", new[]
{
"Assets/Art/Animations/Battle"
});
var dictAnimationClips = new Dictionary<string, AnimationClip>();
for (int i = 0; i < allAnimationClips.Length; i++)
{
var guid = allAnimationClips[i];
var path = AssetDatabase.GUIDToAssetPath(guid);
var clip = AssetDatabase.LoadAssetAtPath<AnimationClip>(path);
var clipName = clip.name;
dictAnimationClips.Add(clipName, clip);
}
_animclipMap = dictAnimationClips;
for (int i = 0; i < _characterBuildDataList.Count; i++)
{
var buildData = _characterBuildDataList[i];
buildData.errorInfo = null;
var weaponConfig = EditorTableManager.instance.tables.WeaponConfig.Get(buildData.mainConfig.WeaponId);
if (weaponConfig == null)
{
buildData.errorInfo = "无效的武器ID:" + buildData.mainConfig.WeaponId;
continue;
}
if (string.IsNullOrEmpty(weaponConfig.GroupName))
{
buildData.errorInfo = "未配置武器组";
continue;
}
if (buildData.skins.Count == 0)
{
buildData.errorInfo = "未配置皮肤";
continue;
}
for (int j = 0; j < buildData.skins.Count; j++)
{
var skinConfig = buildData.skins[j];
var prefabPath = PathEx.GetCharacterSrcModelPath(skinConfig.NameID);
if (string.IsNullOrEmpty(prefabPath))
{
buildData.errorInfo = "皮肤" + skinConfig.Name + "未配置预制体";
continue;
}
var loadPrefab = AssetDatabase.LoadAssetAtPath<GameObject>(prefabPath);
if (loadPrefab == null)
{
buildData.errorInfo = "预制体" + prefabPath + "不存在";
break;
}
}
if (buildData.errorInfo != null)
{
continue;
}
var checkAnim = buildData.CheckAnims(dictAnimationClips);
if (!string.IsNullOrEmpty(checkAnim))
{
buildData.errorInfo = checkAnim;
continue;
}
}
for (int i = 0; i < _npcBuildDataList.Count; i++)
{
var buildData = _npcBuildDataList[i];
buildData.errorInfo = null;
var weaponConfig = EditorTableManager.instance.tables.WeaponConfig.Get(buildData.mainConfig.WeaponId);
if (weaponConfig == null)
{
buildData.errorInfo = "无效的武器ID:" + buildData.mainConfig.WeaponId;
continue;
}
if (string.IsNullOrEmpty(weaponConfig.GroupName))
{
buildData.errorInfo = "未配置武器组";
continue;
}
var checkAnim = buildData.CheckAnims(dictAnimationClips);
if (!string.IsNullOrEmpty(checkAnim))
{
buildData.errorInfo = checkAnim;
continue;
}
}
}
private void _BuildDatas()
{
_characterBuildDataList = new List<CharacterBuildData>();
var characterConfigList = EditorTableManager.instance.tables.CharacterAttri.DataList;
for (int i = 0; i < characterConfigList.Count; i++)
{
var cConfig = characterConfigList[i];
var buildData = new CharacterBuildData(cConfig);
_characterBuildDataList.Add(buildData);
}
_npcBuildDataList = new List<NpcBuildData>();
var npcConfigList = EditorTableManager.instance.tables.MonsterClass.DataList;
for (int i = 0; i < npcConfigList.Count; i++)
{
var cConfig = npcConfigList[i];
var buildData = new NpcBuildData(cConfig);
_npcBuildDataList.Add(buildData);
}
_CheckAllConfigs();
_styleNormal = GUI.skin.label.Clone();
_styleNormal.normal.textColor = Color.white;
_styleNormal.focused.textColor = Color.white;
_styleNormal.hover.textColor = Color.white;
_styleNormal.active.textColor = Color.white;
_styleError = GUI.skin.label.Clone();
_styleError.normal.textColor = Color.red;
_styleError.focused.textColor = Color.red;
_styleError.hover.textColor = Color.red;
_styleError.active.textColor = Color.red;
}
private void OnGUI()
{
if (_characterBuildDataList == null)
{
_BuildDatas();
}
GUILayout.BeginHorizontal();
GUILayout.Label($"当前共有角色配置:{_characterBuildDataList.Count} 个, 敌人配置:{_npcBuildDataList.Count} 个");
if (GUILayout.Button("刷新"))
{
EditorTableManager.instance.ForceReload();
_characterBuildDataList = null;
GUILayout.EndHorizontal();
return;
}
GUILayout.EndHorizontal();
_ShowCharacters();
_ShowMonsters();
if (GUILayout.Button("开始构建"))
{
_Build();
}
}
private void _ShowMonsters()
{
GUILayout.Label("敌人配置");
var totalHeight = _npcBuildDataList.Count * 40;
var maxHeight = 300;
if (totalHeight < maxHeight)
{
maxHeight = totalHeight;
}
_scrollPos2 = EditorGUILayout.BeginScrollView(_scrollPos2, GUILayout.Height(maxHeight));
GUILayout.BeginVertical();
for (int i = 0; i < _npcBuildDataList.Count; i++)
{
var buildData = _npcBuildDataList[i];
var isError = !string.IsNullOrEmpty(buildData.errorInfo);
var style = isError ? _styleError : _styleNormal;
GUILayout.BeginHorizontal();
buildData.isChecked = GUILayout.Toggle(buildData.isChecked, "", GUILayout.Width(20));
var isChecked = buildData.isChecked;
var cConfig = buildData.mainConfig;
GUILayout.Label("ID:" + cConfig.NameId, GUILayout.Width(80));
GUILayout.Label("名称:" + cConfig.Name, style, GUILayout.Width(120));
GUILayout.Label("攻击动作:" + cConfig.AttackAnimOrder, GUILayout.Width(80));
GUILayout.Label("装填动作:" + cConfig.ReloadAnimOrder, GUILayout.Width(80));
GUILayout.Label("使用武器:" + buildData.weaponGroupName);
GUILayout.EndHorizontal();
_ShowEmojiInfo(buildData);
if (isError && isChecked)
{
GUILayout.BeginHorizontal();
GUILayout.Space(100);
GUILayout.Label(buildData.errorInfo, style);
GUILayout.EndHorizontal();
}
}
GUILayout.EndVertical();
EditorGUILayout.EndScrollView();
GUILayout.BeginHorizontal();
if (GUILayout.Button("全选"))
{
for (var i = 0; i < _npcBuildDataList.Count; ++i)
{
_npcBuildDataList[i].isChecked = true;
}
}
if (GUILayout.Button("全不选"))
{
for (var i = 0; i < _npcBuildDataList.Count; ++i)
{
_npcBuildDataList[i].isChecked = false;
}
}
GUILayout.EndHorizontal();
}
private void _ShowCharacters()
{
GUILayout.Label("角色配置");
var totalHeight = _characterBuildDataList.Count * 40;
var maxHeight = 300;
if (totalHeight < maxHeight)
{
maxHeight = totalHeight;
}
_scrollPos1 = EditorGUILayout.BeginScrollView(_scrollPos1, GUILayout.Height(maxHeight));
GUILayout.BeginVertical();
for (int i = 0; i < _characterBuildDataList.Count; i++)
{
var buildData = _characterBuildDataList[i];
var isError = !string.IsNullOrEmpty(buildData.errorInfo);
var style = isError ? _styleError : _styleNormal;
GUILayout.BeginHorizontal();
buildData.isChecked = GUILayout.Toggle(buildData.isChecked, "", GUILayout.Width(20));
var isChecked = buildData.isChecked;
var cConfig = buildData.mainConfig;
GUILayout.Label("ID:" + cConfig.NameID, GUILayout.Width(80));
GUILayout.Label("名称:" + cConfig.NameRead, style, GUILayout.Width(90));
GUILayout.Label("皮肤数量:" + buildData.skins.Count, GUILayout.Width(80));
GUILayout.Label("攻击动作:" + cConfig.AttackAnimOrder, GUILayout.Width(80));
GUILayout.Label("装填动作:" + cConfig.ReloadAnimOrder, GUILayout.Width(80));
GUILayout.Label("使用武器:" + buildData.weaponGroupName);
GUILayout.EndHorizontal();
_ShowEmojiInfo(buildData);
if (isError && isChecked)
{
GUILayout.BeginHorizontal();
GUILayout.Space(100);
GUILayout.Label(buildData.errorInfo, style);
GUILayout.EndHorizontal();
}
}
GUILayout.EndVertical();
EditorGUILayout.EndScrollView();
GUILayout.BeginHorizontal();
if (GUILayout.Button("全选"))
{
for (var i = 0; i < _characterBuildDataList.Count; ++i)
{
_characterBuildDataList[i].isChecked = true;
}
}
if (GUILayout.Button("全不选"))
{
for (var i = 0; i < _characterBuildDataList.Count; ++i)
{
_characterBuildDataList[i].isChecked = false;
}
}
GUILayout.EndHorizontal();
}
private void _ShowEmojiInfo(BaseRoleBuildData buildData)
{
GUILayout.BeginHorizontal();
GUILayout.Space(100);
GUILayout.Label("默认表情:" + buildData.emojiExt.emojiId, GUILayout.Width(120));
GUILayout.Label("眉毛类型:" + buildData.emojiExt.eyebowsType, GUILayout.Width(120));
var eyebowsColorStr = buildData.emojiExt.eyebowsColor;
var eyebowsColor = ColorEx.FromStr(eyebowsColorStr, Color.black);
var myStyle = new GUIStyle(GUI.skin.label);
myStyle.normal.textColor = eyebowsColor;
GUILayout.Label("眉毛颜色:" + buildData.emojiExt.eyebowsColor, myStyle, GUILayout.Width(120));
var eyesColorStr = buildData.emojiExt.eyesColor;
var eyesColor = ColorEx.FromStr(eyesColorStr, Color.black);
myStyle.normal.textColor = eyesColor;
GUILayout.Label("眼睛颜色:" + buildData.emojiExt.eyesColor, myStyle, GUILayout.Width(120));
GUILayout.EndHorizontal();
}
private void _Build()
{
for (int i = 0; i < _characterBuildDataList.Count; i++)
{
var buildData = _characterBuildDataList[i];
if (!buildData.isChecked)
{
continue;
}
buildData.RebuildAll(_animclipMap);
}
for (int i = 0; i < _npcBuildDataList.Count; i++)
{
var buildData = _npcBuildDataList[i];
if (!buildData.isChecked)
{
continue;
}
buildData.RebuildAll(_animclipMap);
}
_AddAllSotryUsedAssets();
AssetDatabase.Refresh();
}
private void _AddAllSotryUsedAssets()
{
var storyPlayerMapper = EditorTableManager.instance.tables.PlayerMapperConfig.DataList;
for (int i = 0; i < storyPlayerMapper.Count; i++)
{
var config = storyPlayerMapper[i];
var prefabPath = config.ModelPath;
if (string.IsNullOrEmpty(prefabPath))
{
continue;
}
// 判断资源是否存在
var loadPrefab = AssetDatabase.LoadAssetAtPath<GameObject>(prefabPath);
if (loadPrefab == null)
{
continue;
}
_AddToAddressables(prefabPath);
}
}
private void _AddToAddressables(string assetPath)
{
#if USE_ADDRESSABLES
// 获取 AddressableAssetSettings
var settings = AddressableAssetSettingsDefaultObject.Settings;
// 获取或创建一个资源组
var group = settings.FindGroup("SplitCharacter");
if (group == null)
{
Debug.LogError("找不到资源组:SplitCharacter");
return;
}
// 创建或移动条目
var guid = AssetDatabase.AssetPathToGUID(assetPath);
settings.CreateOrMoveEntry(guid, group);
#endif
}
}
}