using System; using System.IO; using UnityEditor; using UnityEngine; using UnityEngine.UI; using Framework.Manager; using Sirenix.Utilities; using Framework.GameBuild; using Sirenix.OdinInspector; using Sirenix.Utilities.Editor; using System.Collections.Generic; using UnityEngine.SceneManagement; using UnityEditor.SceneManagement; using Sirenix.OdinInspector.Editor; public class GameBuildWindow : OdinEditorWindow { [Serializable] public class NodeEditor { [LabelText("挂点")] [ReadOnly] public string name; [LabelText("选项数量")] [ReadOnly] public int count; [LabelText("选项实例")] public List optionObj; [LabelText("选项资源路径")] [FolderPath] public string optionPath = "Assets/Art/GameBuild/Texture"; [HideInInspector] public BuildData.BuildNode BuildNode; public NodeEditor(string name, int count) { this.name = name; this.count = count; optionObj = new List(); } } private const string NodeRootPath = "BuildRoot"; private const string NodeTemplatePath = "Assets/Art/GameBuild/Prefab/Node.prefab"; private const string OptionTemplatePath = "Option"; private const string NodeName = "Node{0}"; private const string OptionName = "Option{0}"; private const string BtnBubble = "Btn"; private const int BuildItemLayer = 10; /// /// 当前窗口 /// private static GameBuildWindow _curWindow; /// /// 当前建造编辑器数据 /// private BuildEditor _buildEditor; private List _tempNodeObj = new List(); [LabelText("当前建造数据")] [VerticalGroup("BuildInfo")] public BuildData curBuildData; /// /// 打开窗口 /// public static void OpenWindow(BuildEditor buildEditor) { _curWindow = GetWindow(); _curWindow.position = GUIHelper.GetEditorWindowRect().AlignCenter(800, 600); _curWindow._buildEditor = buildEditor; _curWindow.LoadBuildData(buildEditor.BuildData); } private void LoadBuildData(BuildData buildData) { _curWindow.curBuildData = buildData; curBuildData.buildID = GameBuildUtils.GetFileNameWithoutExtension(_buildEditor.BuildDataJson.name); var root = GameObject.Find(NodeRootPath); if (buildData.NodeInfos == null) { DebugUtil.LogError("需要重启该场景"); return; } editorNodes = new List(buildData.nodeCount); foreach (var node in buildData.NodeInfos) { var nodeObj = root.transform.Find(node.Name).gameObject; if (nodeObj != null) { var editorNode = new NodeEditor(node.Name, buildData.thematicCount); foreach (Transform child in nodeObj.transform) { if (!child.gameObject.name.Equals(BtnBubble)) { editorNode.optionObj.Add(child.gameObject); } } editorNode.BuildNode = node; if (!string.IsNullOrEmpty(node.IconPath)) editorNode.optionPath = node.IconPath.Replace("Icon/{0}.png", "Normal"); editorNodes.Add(editorNode); } } _tempNodeObj.Clear(); foreach (Transform child in root.transform) { _tempNodeObj.Add(child.gameObject); } } [VerticalGroup("BuildInfo/Create")] [Button("创建/更新 节点实例")] [InfoBox("会重新创建物体!!!")] public void UpdateNode() { editorNodeResource = false; if (editorNodes != null) editorNodes.Clear(); switch (curBuildData.unlockType) { case UnlockType.ForGroup: InitBuildInfo(curBuildData.nodeCount); break; case UnlockType.ForThematic: InitBuildInfo(curBuildData.thematicCount); break; default: DebugUtil.LogError("解锁条件错误"); break; } CreateNodeObj(); } /// /// 初始化建造数据 /// private void InitBuildInfo(int count) { //挂点初始化 curBuildData.NodeInfos = new List(curBuildData.nodeCount); for (int i = 0; i < curBuildData.nodeCount; i++) { var node = new BuildData.BuildNode { Name = string.Format(NodeName, i + 1) }; curBuildData.NodeInfos.Add(node); } //解锁条件初始化 curBuildData.unlockInfos = new List(count); for (int i = 0; i < count; i++) { var unlock = new BuildData.UnlockInfo(); curBuildData.unlockInfos.Add(unlock); } } /// /// 创建实例 /// private void CreateNodeObj() { //清除 DeleteNode(); var root = GameObject.Find(NodeRootPath); editorNodes = new List(curBuildData.nodeCount); var nodeTemplate = AssetDatabase.LoadAssetAtPath(NodeTemplatePath); foreach (var node in curBuildData.NodeInfos) { //生成节点 var nodeObj = Instantiate(nodeTemplate, root.transform); nodeObj.name = node.Name; _tempNodeObj.Add(nodeObj); //生成选项 node.Options = new List(curBuildData.thematicCount); var optionTemplate = nodeObj.transform.Find(OptionTemplatePath).gameObject; var tempEditorNode = new NodeEditor(node.Name, curBuildData.thematicCount); for (int i = 0; i < curBuildData.thematicCount; i++) { var optionObj = Instantiate(optionTemplate, nodeObj.transform); optionObj.name = string.Format(OptionName, i + 1); tempEditorNode.optionObj.Add(optionObj); node.Options.Add(optionObj.name); if (i != 0) optionObj.SetActive(false); } tempEditorNode.BuildNode = node; editorNodes.Add(tempEditorNode); DestroyImmediate(optionTemplate); //置顶泡泡按钮 UI操作 /*var btn = nodeObj.transform.Find(BtnBubble); btn.transform.SetSiblingIndex(curBuildData.thematicCount);*/ } } [VerticalGroup("Node")] [LabelText("编辑挂点资源")] public bool editorNodeResource; [VerticalGroup("Node/Info")] [LabelText("挂点资源")] [ShowIf("@editorNodeResource")] public List editorNodes; [VerticalGroup("Node/NodeCreate")] [Button("创建选项资源")] [ShowIf("@editorNodeResource")] public void CreateNodeResource() { var root = GameObject.Find(NodeRootPath); var sortingOrder = 1; foreach (var editorNode in editorNodes) { //加载路径下的资源 var fileEntries = Directory.GetFiles(editorNode.optionPath, "*.png"); var spriteList = new List(); foreach (var filePath in fileEntries) { var assetPath = filePath.Replace(Application.dataPath, "").Replace('\\', '/'); var sprite = AssetDatabase.LoadAssetAtPath(assetPath); if (sprite != null) { spriteList.Add(sprite); } } //应用资源 for (var i = 0; i < editorNode.optionObj.Count; i++) { if (i < spriteList.Count) { var spriteSize = new Vector2(spriteList[i].texture.width, spriteList[i].texture.height); var option = editorNode.optionObj[i]; //UI处理 /*var normalObj = option.transform.Find("Normal").gameObject.GetComponent(); normalObj.sprite = spriteList[i]; var rect = normalObj.GetComponent(); rect.sizeDelta = spriteSize;*/ var normalObj = option.transform.Find("Normal").gameObject; var normalSprite = normalObj.GetComponent(); normalSprite.sortingOrder = sortingOrder; normalSprite.sprite = spriteList[i]; normalObj.AddComponent(); normalObj.layer = BuildItemLayer; var btn = option.transform.parent.Find(BtnBubble); btn.GetComponent().sortingOrder = sortingOrder; } } sortingOrder++; //初始化Icon资源路径 editorNode.BuildNode.IconPath = editorNode.optionPath.Replace("Normal", "Icon/{0}.png"); } } [VerticalGroup("Save")] [Button("保存")] public void Save() { _buildEditor.SaveData(); //保存场景 var activeScene = SceneManager.GetActiveScene(); var saveResult = EditorSceneManager.SaveScene(activeScene); if (!saveResult) DebugUtil.LogError("保存失败!!!"); } private void DeleteNode() { foreach (var obj in _tempNodeObj) { DestroyImmediate(obj); } _tempNodeObj.Clear(); } }