修改
This commit is contained in:
parent
57f0375e47
commit
bc63b41e23
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
[submodule "Client/Packages/com.alicizax.unity.ui.extension"]
|
||||||
|
path = Client/Packages/com.alicizax.unity.ui.extension
|
||||||
|
url = http://101.34.252.46:3000/AlicizaX/com.alicizax.unity.ui.extension.git
|
||||||
1
Client/Packages/com.alicizax.unity.ui.extension
Submodule
1
Client/Packages/com.alicizax.unity.ui.extension
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit 555a0cbd4f829a38c6231681f42eeb6c3a756c9d
|
||||||
@ -1,8 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 8a54cd852459db2408146879dac8748e
|
|
||||||
folderAsset: yes
|
|
||||||
DefaultImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
@ -1,20 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "AlicizaX.UI.Editor",
|
|
||||||
"rootNamespace": "AlicizaX.UI.Editor",
|
|
||||||
"references": [
|
|
||||||
"GUID:acfef7cabed3b0a42b25edb1cd4fa259",
|
|
||||||
"GUID:e9c35c8938f782649bb7e670099ca425",
|
|
||||||
"GUID:75b6f2078d190f14dbda4a5b747d709c"
|
|
||||||
],
|
|
||||||
"includePlatforms": [
|
|
||||||
"Editor"
|
|
||||||
],
|
|
||||||
"excludePlatforms": [],
|
|
||||||
"allowUnsafeCode": true,
|
|
||||||
"overrideReferences": false,
|
|
||||||
"precompiledReferences": [],
|
|
||||||
"autoReferenced": true,
|
|
||||||
"defineConstraints": [],
|
|
||||||
"versionDefines": [],
|
|
||||||
"noEngineReferences": false
|
|
||||||
}
|
|
||||||
@ -1,7 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: e4779686214cb2842afa52039398a499
|
|
||||||
AssemblyDefinitionImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: d9940ca83fab4087ab1116f5a2ea01a4
|
|
||||||
timeCreated: 1739274233
|
|
||||||
@ -1,21 +0,0 @@
|
|||||||
using System.Linq;
|
|
||||||
using UnityEditor;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
namespace AlicizaX.UI.Editor
|
|
||||||
{
|
|
||||||
public static class UIGenerateEditorTool
|
|
||||||
{
|
|
||||||
[MenuItem("GameObject/UI工具/热更工程UI代码", priority = -1)]
|
|
||||||
public static void GenerateHotfixUIScript()
|
|
||||||
{
|
|
||||||
UIGenerateWindow.ShowWindow(Selection.gameObjects.FirstOrDefault(),UIGenerateConfiguration.Instance.UIScriptGenerateConfig.HotFixProjectUIScriptGenerateData);
|
|
||||||
}
|
|
||||||
|
|
||||||
[MenuItem("GameObject/UI工具/主工程UI代码", priority = -1)]
|
|
||||||
public static void GenerateMainUIScript()
|
|
||||||
{
|
|
||||||
UIGenerateWindow.ShowWindow(Selection.gameObjects.FirstOrDefault(),UIGenerateConfiguration.Instance.UIScriptGenerateConfig.MainProjectUIScriptGenerateData);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 8df5224864804bc3a206ab20e5024e5c
|
|
||||||
timeCreated: 1739274266
|
|
||||||
@ -1,42 +0,0 @@
|
|||||||
using UnityEditor;
|
|
||||||
using UnityEngine;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Reflection;
|
|
||||||
using AlicizaX.UI.Editor;
|
|
||||||
using AlicizaX.UI.Runtime;
|
|
||||||
using UnityEngine.UIElements;
|
|
||||||
|
|
||||||
public class UIGenerateWindow : EditorWindow
|
|
||||||
{
|
|
||||||
private GameObject targetObject;
|
|
||||||
|
|
||||||
|
|
||||||
public static GameObject GetTargetObject()
|
|
||||||
{
|
|
||||||
return GetWindow<UIGenerateWindow>().targetObject;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void ShowWindow(GameObject target, UIScriptGenerateData scriptGenerateData)
|
|
||||||
{
|
|
||||||
var window = GetWindow<UIGenerateWindow>(false, "UI Config Editor", false);
|
|
||||||
window.maxSize = Vector2.zero;
|
|
||||||
window.minSize = Vector2.zero;
|
|
||||||
window.rootVisualElement.style.display = DisplayStyle.None;
|
|
||||||
window.rootVisualElement.parent.style.display = DisplayStyle.None;
|
|
||||||
window.Initlize(target, scriptGenerateData);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void CloseWindow()
|
|
||||||
{
|
|
||||||
var window = GetWindow<UIGenerateWindow>(false, "UI Config Editor");
|
|
||||||
window.Close();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Initlize(GameObject target, UIScriptGenerateData scriptGenerateData)
|
|
||||||
{
|
|
||||||
targetObject = target;
|
|
||||||
UIScriptGeneratorHelper.GenerateAndAttachScript(targetObject, scriptGenerateData);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 7bfa0d164c11486cb3a133829d53dccf
|
|
||||||
timeCreated: 1739339632
|
|
||||||
@ -1,469 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Text;
|
|
||||||
using AlicizaX.UI.Editor;
|
|
||||||
using AlicizaX.UI.Runtime;
|
|
||||||
using Sirenix.Utilities.Editor;
|
|
||||||
using UnityEngine;
|
|
||||||
using UnityEditor;
|
|
||||||
using UnityEditor.Callbacks;
|
|
||||||
using UnityEngine.UI;
|
|
||||||
|
|
||||||
namespace AlicizaX.UI.Editor
|
|
||||||
{
|
|
||||||
enum EBindType
|
|
||||||
{
|
|
||||||
None,
|
|
||||||
Widget,
|
|
||||||
ListCom,
|
|
||||||
}
|
|
||||||
|
|
||||||
[Serializable]
|
|
||||||
class UIBindData
|
|
||||||
{
|
|
||||||
public string Name;
|
|
||||||
public List<Component> BindCom;
|
|
||||||
public EBindType BindType;
|
|
||||||
|
|
||||||
public UIBindData(string name, List<Component> bindCom, EBindType bindType = EBindType.None)
|
|
||||||
{
|
|
||||||
Name = name;
|
|
||||||
BindCom = bindCom;
|
|
||||||
BindType = bindType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public UIBindData(string name, Component bindCom, EBindType bindType = EBindType.None)
|
|
||||||
{
|
|
||||||
Name = name;
|
|
||||||
BindCom = new List<Component>() { bindCom };
|
|
||||||
BindType = bindType;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static class UIScriptGeneratorHelper
|
|
||||||
{
|
|
||||||
private static UIGenerateConfiguration _uiGenerateConfiguration;
|
|
||||||
|
|
||||||
static UIGenerateConfiguration UIGenerateConfiguration
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (_uiGenerateConfiguration == null)
|
|
||||||
{
|
|
||||||
_uiGenerateConfiguration = UIGenerateConfiguration.Instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
return _uiGenerateConfiguration;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string GetVerType(string uiName)
|
|
||||||
{
|
|
||||||
foreach (var pair in UIGenerateConfiguration.UIElementRegexConfigs)
|
|
||||||
{
|
|
||||||
if (uiName.StartsWith(pair.uiElementRegex))
|
|
||||||
{
|
|
||||||
return pair.componentType;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return string.Empty;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string[] SplitComName(string name)
|
|
||||||
{
|
|
||||||
bool hasCom = name.Contains(UIGenerateConfiguration.UIGenerateCommonData.ComCheckEndName);
|
|
||||||
if (!hasCom) return null;
|
|
||||||
|
|
||||||
string comStr = name.Substring(0, name.IndexOf(UIGenerateConfiguration.UIGenerateCommonData.ComCheckEndName));
|
|
||||||
return comStr.Split(UIGenerateConfiguration.UIGenerateCommonData.ComCheckSplitName);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private static string GetKeyName(string key, string componentName)
|
|
||||||
{
|
|
||||||
return $"{key}{componentName.Substring(componentName.IndexOf(UIGenerateConfiguration.UIGenerateCommonData.ComCheckEndName) + 1)}";
|
|
||||||
}
|
|
||||||
|
|
||||||
private static List<UIBindData> UIBindDatas = new List<UIBindData>();
|
|
||||||
private static string GenerateNameSpace = string.Empty;
|
|
||||||
|
|
||||||
private static List<string> ArrayComs = new List<string>();
|
|
||||||
|
|
||||||
private static void GetBindData(Transform root)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < root.childCount; ++i)
|
|
||||||
{
|
|
||||||
Transform child = root.GetChild(i);
|
|
||||||
|
|
||||||
bool hasWdiget = child.GetComponent<UIHolderObjectBase>() != null;
|
|
||||||
|
|
||||||
if (UIGenerateConfiguration.UIGenerateCommonData.ExcludeKeywords.Any(k => child.name.IndexOf(k, StringComparison.OrdinalIgnoreCase) >= 0)) continue;
|
|
||||||
|
|
||||||
bool isArrayComs = child.name.StartsWith(UIGenerateConfiguration.UIGenerateCommonData.ArrayComSplitName);
|
|
||||||
if (hasWdiget)
|
|
||||||
{
|
|
||||||
CollectWidget(child);
|
|
||||||
}
|
|
||||||
else if (isArrayComs)
|
|
||||||
{
|
|
||||||
string splitCode = UIGenerateConfiguration.UIGenerateCommonData.ArrayComSplitName;
|
|
||||||
int lastIndex = child.name.LastIndexOf(splitCode);
|
|
||||||
string text = child.name.Substring(child.name.IndexOf(splitCode) + 1, lastIndex - 1);
|
|
||||||
if (ArrayComs.Contains(text)) continue;
|
|
||||||
ArrayComs.Add(text);
|
|
||||||
List<Transform> arrayComs = new List<Transform>();
|
|
||||||
for (int j = 0; j < root.childCount; j++)
|
|
||||||
{
|
|
||||||
if (root.GetChild(j).name.Contains(text))
|
|
||||||
{
|
|
||||||
arrayComs.Add(root.GetChild(j));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CollectArrayComponent(arrayComs, text);
|
|
||||||
}
|
|
||||||
else if (!isArrayComs && !hasWdiget)
|
|
||||||
{
|
|
||||||
CollectComponent(child);
|
|
||||||
GetBindData(child);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void CollectComponent(Transform node)
|
|
||||||
{
|
|
||||||
string[] comArray = SplitComName(node.name);
|
|
||||||
if (comArray != null)
|
|
||||||
{
|
|
||||||
foreach (var com in comArray)
|
|
||||||
{
|
|
||||||
string typeName = GetVerType(com);
|
|
||||||
if (string.IsNullOrEmpty(typeName)) continue;
|
|
||||||
|
|
||||||
Component component = node.GetComponent(typeName);
|
|
||||||
if (component != null)
|
|
||||||
{
|
|
||||||
string keyName = GetKeyName(com, node.name);
|
|
||||||
if (UIBindDatas.Exists(a => a.Name == keyName))
|
|
||||||
{
|
|
||||||
Debug.LogError($"Duplicate key found: {keyName}");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
UIBindDatas.Add(new UIBindData(keyName, component));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Debug.LogError($"{node.name} does not have component of type {typeName}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void CollectWidget(Transform node)
|
|
||||||
{
|
|
||||||
if (node.name.IndexOf(UIGenerateConfiguration.UIGenerateCommonData.ComCheckEndName) != -1 && node.name.IndexOf(UIGenerateConfiguration.UIGenerateCommonData.ComCheckSplitName) != -1)
|
|
||||||
{
|
|
||||||
Debug.LogWarning($"{node.name} 子组件不能包含规则定义符号!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
UIHolderObjectBase component = node.GetComponent<UIHolderObjectBase>();
|
|
||||||
string keyName = node.name;
|
|
||||||
if (UIBindDatas.Exists(a => a.Name == keyName))
|
|
||||||
{
|
|
||||||
Debug.LogError($"Duplicate key found: {keyName}");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
UIBindDatas.Add(new UIBindData(keyName, component, EBindType.Widget));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void CollectArrayComponent(List<Transform> arrayNode, string nodeName)
|
|
||||||
{
|
|
||||||
string[] comArray = SplitComName(nodeName);
|
|
||||||
arrayNode = arrayNode.OrderBy(s => int.Parse(s.name.Split('*').Last())).ToList();
|
|
||||||
List<UIBindData> tempBindDatas = new List<UIBindData>(comArray.Length);
|
|
||||||
|
|
||||||
if (comArray != null)
|
|
||||||
{
|
|
||||||
int index = 0;
|
|
||||||
foreach (var com in comArray)
|
|
||||||
{
|
|
||||||
foreach (var node in arrayNode)
|
|
||||||
{
|
|
||||||
string typeName = GetVerType(com);
|
|
||||||
if (string.IsNullOrEmpty(typeName)) continue;
|
|
||||||
|
|
||||||
Component component = node.GetComponent(typeName);
|
|
||||||
if (component != null)
|
|
||||||
{
|
|
||||||
string keyName = GetKeyName(com, nodeName) + "List";
|
|
||||||
if (tempBindDatas.Count - 1 < index) tempBindDatas.Add(new UIBindData(keyName, new List<Component>(), EBindType.ListCom));
|
|
||||||
tempBindDatas[index].BindCom.Add(component);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Debug.LogError($"{node.name} does not have component of type {typeName}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
UIBindDatas.AddRange(tempBindDatas.ToArray());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private static string GetRefrenceNameSpace()
|
|
||||||
{
|
|
||||||
StringBuilder refrenceNameSpaceBuilder = new StringBuilder();
|
|
||||||
HashSet<string> nameSpaces = new HashSet<string>();
|
|
||||||
nameSpaces.Add("UnityEngine");
|
|
||||||
refrenceNameSpaceBuilder.Append($"using UnityEngine;\n");
|
|
||||||
foreach (var bindData in UIBindDatas)
|
|
||||||
{
|
|
||||||
string nameSpace = bindData.BindCom.FirstOrDefault().GetType().Namespace;
|
|
||||||
if (bindData.BindType == EBindType.ListCom)
|
|
||||||
{
|
|
||||||
if (!nameSpaces.Contains("using System.Collections.Generic;"))
|
|
||||||
{
|
|
||||||
refrenceNameSpaceBuilder.Append("using System.Collections.Generic;\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!nameSpaces.Contains(nameSpace) && !string.IsNullOrEmpty(nameSpace))
|
|
||||||
{
|
|
||||||
nameSpaces.Add(nameSpace);
|
|
||||||
refrenceNameSpaceBuilder.Append($"using {nameSpace};\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return refrenceNameSpaceBuilder.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string GetVarText(List<UIBindData> uiBindDatas)
|
|
||||||
{
|
|
||||||
StringBuilder varTextBuilder = new StringBuilder();
|
|
||||||
foreach (var bindData in uiBindDatas)
|
|
||||||
{
|
|
||||||
var varName = bindData.Name;
|
|
||||||
varTextBuilder.Append("\t\t[SerializeField]\n");
|
|
||||||
varTextBuilder.Append("\t\t[ReadOnly]\n");
|
|
||||||
varTextBuilder.Append("\t\t[HideLabel]\n");
|
|
||||||
|
|
||||||
if (bindData.BindType == EBindType.None)
|
|
||||||
{
|
|
||||||
varTextBuilder.Append($"\t\tprivate {bindData.BindCom.FirstOrDefault().GetType().Name} m{varName};\n");
|
|
||||||
varTextBuilder.Append($"\t\tpublic {bindData.BindCom.FirstOrDefault().GetType().Name} {varName} => m{varName};\n\n");
|
|
||||||
}
|
|
||||||
else if (bindData.BindType == EBindType.ListCom)
|
|
||||||
{
|
|
||||||
varTextBuilder.Append($"\t\tprivate {bindData.BindCom.FirstOrDefault().GetType().Name} [] m{varName} = new {bindData.BindCom.FirstOrDefault().GetType().Name}[{bindData.BindCom.Count}];\n");
|
|
||||||
varTextBuilder.Append($"\t\tpublic {bindData.BindCom.FirstOrDefault().GetType().Name} [] {varName} => m{varName};\n\n");
|
|
||||||
}
|
|
||||||
else if (bindData.BindType == EBindType.Widget)
|
|
||||||
{
|
|
||||||
varTextBuilder.Append($"\t\tprivate {bindData.BindCom.FirstOrDefault().GetType().Name} m{varName};\n");
|
|
||||||
varTextBuilder.Append($"\t\tpublic {bindData.BindCom.FirstOrDefault().GetType().Name} {varName} => m{varName};\n\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return varTextBuilder.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string GenerateScript(string className)
|
|
||||||
{
|
|
||||||
StringBuilder scriptBuilder = new StringBuilder();
|
|
||||||
scriptBuilder.Append(GetRefrenceNameSpace());
|
|
||||||
|
|
||||||
scriptBuilder.Append("using Sirenix.OdinInspector;\n");
|
|
||||||
scriptBuilder.Append("using AlicizaX.UI.Runtime;\n");
|
|
||||||
scriptBuilder.Append($"namespace {GenerateNameSpace}\n");
|
|
||||||
scriptBuilder.Append("{\n");
|
|
||||||
scriptBuilder.Append($"\t#Attribute#\n");
|
|
||||||
scriptBuilder.Append($"\tpublic class {className} : UIHolderObjectBase\n");
|
|
||||||
scriptBuilder.Append("\t{\n");
|
|
||||||
|
|
||||||
scriptBuilder.Append($"\t\tpublic const string ResTag = #Tag#;\n");
|
|
||||||
|
|
||||||
scriptBuilder.Append("\t\t#region Generated by Script Tool\n\n");
|
|
||||||
scriptBuilder.Append(GetVarText(UIBindDatas));
|
|
||||||
scriptBuilder.Append("\n\t\t#endregion\n");
|
|
||||||
|
|
||||||
scriptBuilder.Append("\t}\n");
|
|
||||||
scriptBuilder.Append("}\n");
|
|
||||||
|
|
||||||
return scriptBuilder.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void GenerateAndAttachScript(GameObject targetObject, UIScriptGenerateData scriptGenerateData)
|
|
||||||
{
|
|
||||||
UIBindDatas.Clear();
|
|
||||||
GenerateNameSpace = scriptGenerateData.NameSpace;
|
|
||||||
ArrayComs.Clear();
|
|
||||||
|
|
||||||
string className = $"{UIGenerateConfiguration.UIGenerateCommonData.GeneratePrefix}_{targetObject.name}";
|
|
||||||
|
|
||||||
string scriptSavePath = Path.Combine(scriptGenerateData.GenerateHolderCodePath, className + ".cs");
|
|
||||||
|
|
||||||
|
|
||||||
GetBindData(targetObject.transform);
|
|
||||||
|
|
||||||
string scriptContent = GenerateScript(className);
|
|
||||||
string TagName = $"\"{targetObject.name}\"";
|
|
||||||
if (scriptGenerateData.LoadType == EUIResLoadType.Resources)
|
|
||||||
{
|
|
||||||
string matchWords = string.Empty;
|
|
||||||
UIGenerateConfiguration.UIGenerateCommonData.CombineWords.Any(t =>
|
|
||||||
{
|
|
||||||
if (targetObject.name.IndexOf(t.Key) >= 0)
|
|
||||||
{
|
|
||||||
matchWords = t.Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
return targetObject.name.IndexOf(t.Key) >= 0;
|
|
||||||
});
|
|
||||||
string finalPath = Path.Combine(scriptGenerateData.UIPrefabRootPath.Replace("Assets/", "").Replace("Resources/", ""), matchWords);
|
|
||||||
string didc = Path.Combine(scriptGenerateData.UIPrefabRootPath, matchWords);
|
|
||||||
if (!Directory.Exists(didc))
|
|
||||||
{
|
|
||||||
Directory.CreateDirectory(didc);
|
|
||||||
}
|
|
||||||
|
|
||||||
finalPath = Utility.Path.GetRegularPath(finalPath);
|
|
||||||
TagName = $"\"{finalPath}/{targetObject.name}\"";
|
|
||||||
}
|
|
||||||
|
|
||||||
scriptContent = scriptContent.Replace("#Tag#", TagName);
|
|
||||||
|
|
||||||
|
|
||||||
//#Attribute#
|
|
||||||
string uiAttribute = $"[UIRes({className}.ResTag, EUIResLoadType.{scriptGenerateData.LoadType.ToString()})]";
|
|
||||||
|
|
||||||
scriptContent = scriptContent.Replace("#Attribute#", uiAttribute);
|
|
||||||
|
|
||||||
|
|
||||||
if (File.Exists(scriptSavePath))
|
|
||||||
{
|
|
||||||
string oldText = File.ReadAllText(scriptSavePath);
|
|
||||||
if (oldText.Equals(scriptContent))
|
|
||||||
{
|
|
||||||
EditorPrefs.SetString("Generate", className);
|
|
||||||
CheckHasAttach();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
File.WriteAllText(scriptSavePath, scriptContent);
|
|
||||||
EditorPrefs.SetString("Generate", className);
|
|
||||||
AssetDatabase.Refresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
[DidReloadScripts]
|
|
||||||
private static void CheckHasAttach()
|
|
||||||
{
|
|
||||||
bool has = EditorPrefs.HasKey("Generate");
|
|
||||||
if (has)
|
|
||||||
{
|
|
||||||
UIBindDatas.Clear();
|
|
||||||
ArrayComs.Clear();
|
|
||||||
var className = EditorPrefs.GetString("Generate");
|
|
||||||
var targetObject = UIGenerateWindow.GetTargetObject();
|
|
||||||
EditorPrefs.DeleteKey("Generate");
|
|
||||||
GetBindData(targetObject.transform);
|
|
||||||
AttachScriptToGameObject(targetObject, className);
|
|
||||||
Debug.Log($"Generate {className} Successfully attached to game object");
|
|
||||||
UIGenerateWindow.CloseWindow();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private static void AttachScriptToGameObject(GameObject targetObject, string scriptClassName)
|
|
||||||
{
|
|
||||||
Type scriptType = null;
|
|
||||||
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
|
|
||||||
{
|
|
||||||
if (assembly.FullName.Contains("Editor")) continue;
|
|
||||||
var types = assembly.GetTypes();
|
|
||||||
foreach (var type in types)
|
|
||||||
{
|
|
||||||
if (type.IsClass && !type.IsAbstract && type.Name.Contains(scriptClassName))
|
|
||||||
{
|
|
||||||
scriptType = type;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (scriptType != null)
|
|
||||||
{
|
|
||||||
Component component = targetObject.GetOrAddComponent(scriptType);
|
|
||||||
FieldInfo[] fields = scriptType.GetFields(BindingFlags.NonPublic | BindingFlags.Instance);
|
|
||||||
|
|
||||||
foreach (FieldInfo field in fields)
|
|
||||||
{
|
|
||||||
List<Component> componentInObjects = UIBindDatas.Find(data => "m" + data.Name == field.Name)?.BindCom;
|
|
||||||
if (componentInObjects != null)
|
|
||||||
{
|
|
||||||
if (field.FieldType.IsArray)
|
|
||||||
{
|
|
||||||
// 获取数组元素类型
|
|
||||||
Type elementType = field.FieldType.GetElementType();
|
|
||||||
// 创建对应类型的数组
|
|
||||||
Array array = Array.CreateInstance(elementType, componentInObjects.Count);
|
|
||||||
|
|
||||||
for (int i = 0; i < componentInObjects.Count; i++)
|
|
||||||
{
|
|
||||||
Component comp = componentInObjects[i];
|
|
||||||
// 检查元素类型是否匹配
|
|
||||||
if (elementType.IsInstanceOfType(comp))
|
|
||||||
{
|
|
||||||
array.SetValue(comp, i);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Debug.LogError($"元素 {i} 类型不匹配,期望 {elementType.Name},实际为 {comp.GetType().Name}");
|
|
||||||
// 处理错误,如跳过或终止赋值
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
field.SetValue(component, array);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// 非数组字段取第一个元素
|
|
||||||
if (componentInObjects.Count > 0)
|
|
||||||
{
|
|
||||||
// 同样检查类型兼容性
|
|
||||||
if (field.FieldType.IsInstanceOfType(componentInObjects[0]))
|
|
||||||
{
|
|
||||||
field.SetValue(component, componentInObjects[0]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Debug.LogError($"字段 {field.Name} 类型不匹配,无法赋值");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Debug.LogError($"字段 {field.Name} 未找到匹配的组件绑定");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Debug.LogError($"Could not find the class: {scriptClassName}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: f42fd09682fc40898bf7176dbb24d085
|
|
||||||
timeCreated: 1739273282
|
|
||||||
@ -1,104 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
using Sirenix.OdinInspector;
|
|
||||||
using Sirenix.OdinInspector.Editor;
|
|
||||||
using UnityEditor;
|
|
||||||
using UnityEngine;
|
|
||||||
using UnityEngine.Windows;
|
|
||||||
|
|
||||||
namespace AlicizaX.UI.Editor
|
|
||||||
{
|
|
||||||
public class UISettingEditorWindow : OdinEditorWindow
|
|
||||||
{
|
|
||||||
[MenuItem("Tools/AlicizaX/UI Setting Window")]
|
|
||||||
private static void OpenWindow()
|
|
||||||
{
|
|
||||||
GetWindow<UISettingEditorWindow>().Show();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
protected override void Initialize()
|
|
||||||
{
|
|
||||||
uiGenerateConfiguration = UIGenerateConfiguration.Instance;
|
|
||||||
UIGenerateCommonData = uiGenerateConfiguration.UIGenerateCommonData;
|
|
||||||
UIScriptGenerateConfig = uiGenerateConfiguration.UIScriptGenerateConfig;
|
|
||||||
UIElementRegexConfigs = uiGenerateConfiguration.UIElementRegexConfigs;
|
|
||||||
RefreshLabel();
|
|
||||||
}
|
|
||||||
|
|
||||||
// [Required] [InlineEditor(InlineEditorObjectFieldModes.CompletelyHidden)] [DisableInPlayMode] [HideLabel]
|
|
||||||
private UIGenerateConfiguration uiGenerateConfiguration;
|
|
||||||
|
|
||||||
[Required] [DisableInPlayMode] [HideLabel] [TabGroup("UI基础设置")] [SerializeField]
|
|
||||||
public UIGenerateCommonData UIGenerateCommonData;
|
|
||||||
|
|
||||||
[TabGroup("UI基础设置")] [LabelText("脚本生成预览")] [ShowInInspector] [ReadOnly] [OnValueChanged("RefreshLabel")]
|
|
||||||
private string previewLabel;
|
|
||||||
|
|
||||||
[TabGroup("UI基础设置")] [LabelText("组件生成预览")] [ShowInInspector] [ReadOnly] [OnValueChanged("RefreshLabel")] [SuffixLabel("(下标0开始)")]
|
|
||||||
private string previewCompLabel;
|
|
||||||
|
|
||||||
[Required] [DisableInPlayMode] [HideLabel] [TabGroup("UI构建配置")] [SerializeField]
|
|
||||||
public UIScriptGenerateConfig UIScriptGenerateConfig;
|
|
||||||
|
|
||||||
[Required] [DisableInPlayMode] [HideLabel] [TabGroup("UI元素映射")] [SerializeField] [TableList(ShowIndexLabels = false, DrawScrollView = true, AlwaysExpanded = true)]
|
|
||||||
public List<UIEelementRegexData> UIElementRegexConfigs;
|
|
||||||
|
|
||||||
private void RefreshLabel()
|
|
||||||
{
|
|
||||||
previewLabel = $"{UIGenerateCommonData.GeneratePrefix}_UITestWindow";
|
|
||||||
previewCompLabel = $"{UIGenerateCommonData.ArrayComSplitName}Text{UIGenerateCommonData.ComCheckSplitName}Img" +
|
|
||||||
$"{UIGenerateCommonData.ComCheckEndName}Test{UIGenerateCommonData.ArrayComSplitName}0";
|
|
||||||
}
|
|
||||||
|
|
||||||
[TabGroup("UI元素映射")]
|
|
||||||
[Sirenix.OdinInspector.Button("加载默认")]
|
|
||||||
private void LoadDefaultConfig()
|
|
||||||
{
|
|
||||||
const string Path = "Packages/com.alicizax.unity.ui/Editor/Res/default.txt";
|
|
||||||
string text = System.IO.File.ReadAllText(Path);
|
|
||||||
UIElementRegexConfigs = JsonConvert.DeserializeObject<List<UIEelementRegexData>>(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
[TabGroup("UI元素映射")]
|
|
||||||
[Sirenix.OdinInspector.Button("导出")]
|
|
||||||
private void ExportConfig()
|
|
||||||
{
|
|
||||||
var json = JsonConvert.SerializeObject(UIElementRegexConfigs);
|
|
||||||
System.IO.File.WriteAllText("Assets/uielementconfig.txt", json);
|
|
||||||
AssetDatabase.Refresh();
|
|
||||||
Debug.Log("Export UIElements Finished");
|
|
||||||
}
|
|
||||||
|
|
||||||
[TabGroup("UI元素映射")]
|
|
||||||
[Sirenix.OdinInspector.Button("导入")]
|
|
||||||
private void ImportConfig(TextAsset text)
|
|
||||||
{
|
|
||||||
UIElementRegexConfigs = JsonConvert.DeserializeObject<List<UIEelementRegexData>>(text.text);
|
|
||||||
Debug.Log("Import UIElements Finished");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
protected override void OnDisable()
|
|
||||||
{
|
|
||||||
base.OnDisable();
|
|
||||||
uiGenerateConfiguration.UIGenerateCommonData = UIGenerateCommonData;
|
|
||||||
uiGenerateConfiguration.UIScriptGenerateConfig = UIScriptGenerateConfig;
|
|
||||||
uiGenerateConfiguration.UIElementRegexConfigs = UIElementRegexConfigs;
|
|
||||||
EditorUtility.SetDirty(uiGenerateConfiguration);
|
|
||||||
AssetDatabase.SaveAssets();
|
|
||||||
UIGenerateConfiguration.Save();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnDestroy()
|
|
||||||
{
|
|
||||||
base.OnDestroy();
|
|
||||||
uiGenerateConfiguration.UIGenerateCommonData = UIGenerateCommonData;
|
|
||||||
uiGenerateConfiguration.UIScriptGenerateConfig = UIScriptGenerateConfig;
|
|
||||||
uiGenerateConfiguration.UIElementRegexConfigs = UIElementRegexConfigs;
|
|
||||||
EditorUtility.SetDirty(uiGenerateConfiguration);
|
|
||||||
AssetDatabase.SaveAssets();
|
|
||||||
UIGenerateConfiguration.Save();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: d6e004459b3645d4b3022bdde89795b9
|
|
||||||
timeCreated: 1741340568
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: c775eb6a6aca4533bc75c89ef7a219a1
|
|
||||||
timeCreated: 1737704983
|
|
||||||
@ -1,62 +0,0 @@
|
|||||||
using System;
|
|
||||||
using AlicizaX.Editor;
|
|
||||||
using AlicizaX.UI.Runtime;
|
|
||||||
using UnityEditor;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
namespace AlicizaX.UI.Editor
|
|
||||||
{
|
|
||||||
[CustomEditor(typeof(UIComponent))]
|
|
||||||
internal sealed class UIComponentInspector : GameFrameworkInspector
|
|
||||||
{
|
|
||||||
private SerializedProperty uiRoot;
|
|
||||||
private SerializedProperty _isOrthographic;
|
|
||||||
|
|
||||||
|
|
||||||
public override void OnInspectorGUI()
|
|
||||||
{
|
|
||||||
base.OnInspectorGUI();
|
|
||||||
serializedObject.Update();
|
|
||||||
|
|
||||||
EditorGUI.BeginDisabledGroup(EditorApplication.isPlayingOrWillChangePlaymode);
|
|
||||||
{
|
|
||||||
if (uiRoot.objectReferenceValue == null)
|
|
||||||
{
|
|
||||||
EditorGUILayout.HelpBox("uiroot can not be null!", MessageType.Error);
|
|
||||||
}
|
|
||||||
|
|
||||||
EditorGUILayout.BeginHorizontal();
|
|
||||||
|
|
||||||
GameObject rootPrefab = (GameObject)EditorGUILayout.ObjectField("UI根预设", uiRoot.objectReferenceValue, typeof(GameObject), false);
|
|
||||||
|
|
||||||
if (rootPrefab != uiRoot.objectReferenceValue)
|
|
||||||
{
|
|
||||||
uiRoot.objectReferenceValue = rootPrefab;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (uiRoot.objectReferenceValue == null)
|
|
||||||
{
|
|
||||||
if (GUILayout.Button("设置默认"))
|
|
||||||
{
|
|
||||||
GameObject defaultPrefab = AssetDatabase.LoadAssetAtPath<GameObject>("Packages/com.alicizax.unity.ui/Editor/Res/UIRoot.prefab");
|
|
||||||
uiRoot.objectReferenceValue = defaultPrefab;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
EditorGUILayout.EndHorizontal();
|
|
||||||
|
|
||||||
EditorGUILayout.PropertyField(_isOrthographic);
|
|
||||||
}
|
|
||||||
EditorGUI.EndDisabledGroup();
|
|
||||||
serializedObject.ApplyModifiedProperties();
|
|
||||||
Repaint();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void OnEnable()
|
|
||||||
{
|
|
||||||
uiRoot = serializedObject.FindProperty("uiRoot");
|
|
||||||
_isOrthographic = serializedObject.FindProperty("_isOrthographic");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 6c8dd72e28584576864a33af24255060
|
|
||||||
timeCreated: 1737704960
|
|
||||||
@ -1,8 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 1adcae2abd30deb478273eb8d2a4a1ac
|
|
||||||
folderAsset: yes
|
|
||||||
DefaultImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
@ -1,312 +0,0 @@
|
|||||||
%YAML 1.1
|
|
||||||
%TAG !u! tag:unity3d.com,2011:
|
|
||||||
--- !u!1 &500891838716286123
|
|
||||||
GameObject:
|
|
||||||
m_ObjectHideFlags: 0
|
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
|
||||||
m_PrefabInstance: {fileID: 0}
|
|
||||||
m_PrefabAsset: {fileID: 0}
|
|
||||||
serializedVersion: 6
|
|
||||||
m_Component:
|
|
||||||
- component: {fileID: 5373281001294974998}
|
|
||||||
- component: {fileID: 743195302492612381}
|
|
||||||
- component: {fileID: 7227605137039161963}
|
|
||||||
m_Layer: 0
|
|
||||||
m_Name: UICamera
|
|
||||||
m_TagString: Untagged
|
|
||||||
m_Icon: {fileID: 0}
|
|
||||||
m_NavMeshLayer: 0
|
|
||||||
m_StaticEditorFlags: 0
|
|
||||||
m_IsActive: 1
|
|
||||||
--- !u!4 &5373281001294974998
|
|
||||||
Transform:
|
|
||||||
m_ObjectHideFlags: 0
|
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
|
||||||
m_PrefabInstance: {fileID: 0}
|
|
||||||
m_PrefabAsset: {fileID: 0}
|
|
||||||
m_GameObject: {fileID: 500891838716286123}
|
|
||||||
serializedVersion: 2
|
|
||||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
|
||||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
|
||||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
|
||||||
m_ConstrainProportionsScale: 0
|
|
||||||
m_Children: []
|
|
||||||
m_Father: {fileID: 86062277508691697}
|
|
||||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
|
||||||
--- !u!20 &743195302492612381
|
|
||||||
Camera:
|
|
||||||
m_ObjectHideFlags: 0
|
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
|
||||||
m_PrefabInstance: {fileID: 0}
|
|
||||||
m_PrefabAsset: {fileID: 0}
|
|
||||||
m_GameObject: {fileID: 500891838716286123}
|
|
||||||
m_Enabled: 1
|
|
||||||
serializedVersion: 2
|
|
||||||
m_ClearFlags: 3
|
|
||||||
m_BackGroundColor: {r: 0, g: 0, b: 0, a: 0}
|
|
||||||
m_projectionMatrixMode: 1
|
|
||||||
m_GateFitMode: 2
|
|
||||||
m_FOVAxisMode: 0
|
|
||||||
m_Iso: 200
|
|
||||||
m_ShutterSpeed: 0.005
|
|
||||||
m_Aperture: 16
|
|
||||||
m_FocusDistance: 10
|
|
||||||
m_FocalLength: 50
|
|
||||||
m_BladeCount: 5
|
|
||||||
m_Curvature: {x: 2, y: 11}
|
|
||||||
m_BarrelClipping: 0.25
|
|
||||||
m_Anamorphism: 0
|
|
||||||
m_SensorSize: {x: 36, y: 24}
|
|
||||||
m_LensShift: {x: 0, y: 0}
|
|
||||||
m_NormalizedViewPortRect:
|
|
||||||
serializedVersion: 2
|
|
||||||
x: 0
|
|
||||||
y: 0
|
|
||||||
width: 1
|
|
||||||
height: 1
|
|
||||||
near clip plane: 10
|
|
||||||
far clip plane: 1000
|
|
||||||
field of view: 60
|
|
||||||
orthographic: 1
|
|
||||||
orthographic size: 5
|
|
||||||
m_Depth: 2
|
|
||||||
m_CullingMask:
|
|
||||||
serializedVersion: 2
|
|
||||||
m_Bits: 32
|
|
||||||
m_RenderingPath: -1
|
|
||||||
m_TargetTexture: {fileID: 0}
|
|
||||||
m_TargetDisplay: 0
|
|
||||||
m_TargetEye: 3
|
|
||||||
m_HDR: 0
|
|
||||||
m_AllowMSAA: 0
|
|
||||||
m_AllowDynamicResolution: 0
|
|
||||||
m_ForceIntoRT: 0
|
|
||||||
m_OcclusionCulling: 1
|
|
||||||
m_StereoConvergence: 10
|
|
||||||
m_StereoSeparation: 0.022
|
|
||||||
--- !u!114 &7227605137039161963
|
|
||||||
MonoBehaviour:
|
|
||||||
m_ObjectHideFlags: 0
|
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
|
||||||
m_PrefabInstance: {fileID: 0}
|
|
||||||
m_PrefabAsset: {fileID: 0}
|
|
||||||
m_GameObject: {fileID: 500891838716286123}
|
|
||||||
m_Enabled: 1
|
|
||||||
m_EditorHideFlags: 0
|
|
||||||
m_Script: {fileID: 11500000, guid: a79441f348de89743a2939f4d699eac1, type: 3}
|
|
||||||
m_Name:
|
|
||||||
m_EditorClassIdentifier:
|
|
||||||
m_RenderShadows: 0
|
|
||||||
m_RequiresDepthTextureOption: 0
|
|
||||||
m_RequiresOpaqueTextureOption: 0
|
|
||||||
m_CameraType: 0
|
|
||||||
m_Cameras: []
|
|
||||||
m_RendererIndex: -1
|
|
||||||
m_VolumeLayerMask:
|
|
||||||
serializedVersion: 2
|
|
||||||
m_Bits: 0
|
|
||||||
m_VolumeTrigger: {fileID: 0}
|
|
||||||
m_VolumeFrameworkUpdateModeOption: 2
|
|
||||||
m_RenderPostProcessing: 0
|
|
||||||
m_Antialiasing: 0
|
|
||||||
m_AntialiasingQuality: 2
|
|
||||||
m_StopNaN: 0
|
|
||||||
m_Dithering: 0
|
|
||||||
m_ClearDepth: 1
|
|
||||||
m_AllowXRRendering: 1
|
|
||||||
m_AllowHDROutput: 1
|
|
||||||
m_UseScreenCoordOverride: 0
|
|
||||||
m_ScreenSizeOverride: {x: 0, y: 0, z: 0, w: 0}
|
|
||||||
m_ScreenCoordScaleBias: {x: 0, y: 0, z: 0, w: 0}
|
|
||||||
m_RequiresDepthTexture: 0
|
|
||||||
m_RequiresColorTexture: 0
|
|
||||||
m_Version: 2
|
|
||||||
m_TaaSettings:
|
|
||||||
m_Quality: 3
|
|
||||||
m_FrameInfluence: 0.1
|
|
||||||
m_JitterScale: 1
|
|
||||||
m_MipBias: 0
|
|
||||||
m_VarianceClampScale: 0.9
|
|
||||||
m_ContrastAdaptiveSharpening: 0
|
|
||||||
--- !u!1 &1735351593002053547
|
|
||||||
GameObject:
|
|
||||||
m_ObjectHideFlags: 0
|
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
|
||||||
m_PrefabInstance: {fileID: 0}
|
|
||||||
m_PrefabAsset: {fileID: 0}
|
|
||||||
serializedVersion: 6
|
|
||||||
m_Component:
|
|
||||||
- component: {fileID: 3110666966229274110}
|
|
||||||
- component: {fileID: 4697108639102116370}
|
|
||||||
- component: {fileID: 3475475550181341661}
|
|
||||||
- component: {fileID: 6941144161958937340}
|
|
||||||
m_Layer: 5
|
|
||||||
m_Name: UICanvas
|
|
||||||
m_TagString: Untagged
|
|
||||||
m_Icon: {fileID: 0}
|
|
||||||
m_NavMeshLayer: 0
|
|
||||||
m_StaticEditorFlags: 0
|
|
||||||
m_IsActive: 1
|
|
||||||
--- !u!224 &3110666966229274110
|
|
||||||
RectTransform:
|
|
||||||
m_ObjectHideFlags: 0
|
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
|
||||||
m_PrefabInstance: {fileID: 0}
|
|
||||||
m_PrefabAsset: {fileID: 0}
|
|
||||||
m_GameObject: {fileID: 1735351593002053547}
|
|
||||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
|
||||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
|
||||||
m_LocalScale: {x: 0, y: 0, z: 0}
|
|
||||||
m_ConstrainProportionsScale: 0
|
|
||||||
m_Children: []
|
|
||||||
m_Father: {fileID: 86062277508691697}
|
|
||||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
|
||||||
m_AnchorMin: {x: 0, y: 0}
|
|
||||||
m_AnchorMax: {x: 0, y: 0}
|
|
||||||
m_AnchoredPosition: {x: 0, y: 0}
|
|
||||||
m_SizeDelta: {x: 0, y: 0}
|
|
||||||
m_Pivot: {x: 0, y: 0}
|
|
||||||
--- !u!223 &4697108639102116370
|
|
||||||
Canvas:
|
|
||||||
m_ObjectHideFlags: 0
|
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
|
||||||
m_PrefabInstance: {fileID: 0}
|
|
||||||
m_PrefabAsset: {fileID: 0}
|
|
||||||
m_GameObject: {fileID: 1735351593002053547}
|
|
||||||
m_Enabled: 1
|
|
||||||
serializedVersion: 3
|
|
||||||
m_RenderMode: 1
|
|
||||||
m_Camera: {fileID: 743195302492612381}
|
|
||||||
m_PlaneDistance: 100
|
|
||||||
m_PixelPerfect: 0
|
|
||||||
m_ReceivesEvents: 1
|
|
||||||
m_OverrideSorting: 0
|
|
||||||
m_OverridePixelPerfect: 0
|
|
||||||
m_SortingBucketNormalizedSize: 0
|
|
||||||
m_VertexColorAlwaysGammaSpace: 1
|
|
||||||
m_AdditionalShaderChannelsFlag: 27
|
|
||||||
m_UpdateRectTransformForStandalone: 0
|
|
||||||
m_SortingLayerID: 0
|
|
||||||
m_SortingOrder: 0
|
|
||||||
m_TargetDisplay: 0
|
|
||||||
--- !u!114 &3475475550181341661
|
|
||||||
MonoBehaviour:
|
|
||||||
m_ObjectHideFlags: 0
|
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
|
||||||
m_PrefabInstance: {fileID: 0}
|
|
||||||
m_PrefabAsset: {fileID: 0}
|
|
||||||
m_GameObject: {fileID: 1735351593002053547}
|
|
||||||
m_Enabled: 1
|
|
||||||
m_EditorHideFlags: 0
|
|
||||||
m_Script: {fileID: 11500000, guid: 0cd44c1031e13a943bb63640046fad76, type: 3}
|
|
||||||
m_Name:
|
|
||||||
m_EditorClassIdentifier:
|
|
||||||
m_UiScaleMode: 1
|
|
||||||
m_ReferencePixelsPerUnit: 100
|
|
||||||
m_ScaleFactor: 1
|
|
||||||
m_ReferenceResolution: {x: 1920, y: 1080}
|
|
||||||
m_ScreenMatchMode: 0
|
|
||||||
m_MatchWidthOrHeight: 0
|
|
||||||
m_PhysicalUnit: 3
|
|
||||||
m_FallbackScreenDPI: 96
|
|
||||||
m_DefaultSpriteDPI: 96
|
|
||||||
m_DynamicPixelsPerUnit: 1
|
|
||||||
m_PresetInfoIsWorld: 0
|
|
||||||
--- !u!114 &6941144161958937340
|
|
||||||
MonoBehaviour:
|
|
||||||
m_ObjectHideFlags: 0
|
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
|
||||||
m_PrefabInstance: {fileID: 0}
|
|
||||||
m_PrefabAsset: {fileID: 0}
|
|
||||||
m_GameObject: {fileID: 1735351593002053547}
|
|
||||||
m_Enabled: 1
|
|
||||||
m_EditorHideFlags: 0
|
|
||||||
m_Script: {fileID: 11500000, guid: dc42784cf147c0c48a680349fa168899, type: 3}
|
|
||||||
m_Name:
|
|
||||||
m_EditorClassIdentifier:
|
|
||||||
m_IgnoreReversedGraphics: 1
|
|
||||||
m_BlockingObjects: 0
|
|
||||||
m_BlockingMask:
|
|
||||||
serializedVersion: 2
|
|
||||||
m_Bits: 55
|
|
||||||
--- !u!1 &4612363183729467837
|
|
||||||
GameObject:
|
|
||||||
m_ObjectHideFlags: 0
|
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
|
||||||
m_PrefabInstance: {fileID: 0}
|
|
||||||
m_PrefabAsset: {fileID: 0}
|
|
||||||
serializedVersion: 6
|
|
||||||
m_Component:
|
|
||||||
- component: {fileID: 86062277508691697}
|
|
||||||
- component: {fileID: 2601148299080526511}
|
|
||||||
- component: {fileID: 4177649269856392400}
|
|
||||||
m_Layer: 0
|
|
||||||
m_Name: UIRoot
|
|
||||||
m_TagString: Untagged
|
|
||||||
m_Icon: {fileID: 0}
|
|
||||||
m_NavMeshLayer: 0
|
|
||||||
m_StaticEditorFlags: 0
|
|
||||||
m_IsActive: 1
|
|
||||||
--- !u!4 &86062277508691697
|
|
||||||
Transform:
|
|
||||||
m_ObjectHideFlags: 0
|
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
|
||||||
m_PrefabInstance: {fileID: 0}
|
|
||||||
m_PrefabAsset: {fileID: 0}
|
|
||||||
m_GameObject: {fileID: 4612363183729467837}
|
|
||||||
serializedVersion: 2
|
|
||||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
|
||||||
m_LocalPosition: {x: 1000, y: 1000, z: 0}
|
|
||||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
|
||||||
m_ConstrainProportionsScale: 0
|
|
||||||
m_Children:
|
|
||||||
- {fileID: 3110666966229274110}
|
|
||||||
- {fileID: 5373281001294974998}
|
|
||||||
m_Father: {fileID: 0}
|
|
||||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
|
||||||
--- !u!114 &2601148299080526511
|
|
||||||
MonoBehaviour:
|
|
||||||
m_ObjectHideFlags: 0
|
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
|
||||||
m_PrefabInstance: {fileID: 0}
|
|
||||||
m_PrefabAsset: {fileID: 0}
|
|
||||||
m_GameObject: {fileID: 4612363183729467837}
|
|
||||||
m_Enabled: 1
|
|
||||||
m_EditorHideFlags: 0
|
|
||||||
m_Script: {fileID: 11500000, guid: 76c392e42b5098c458856cdf6ecaaaa1, type: 3}
|
|
||||||
m_Name:
|
|
||||||
m_EditorClassIdentifier:
|
|
||||||
m_FirstSelected: {fileID: 0}
|
|
||||||
m_sendNavigationEvents: 1
|
|
||||||
m_DragThreshold: 10
|
|
||||||
--- !u!114 &4177649269856392400
|
|
||||||
MonoBehaviour:
|
|
||||||
m_ObjectHideFlags: 0
|
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
|
||||||
m_PrefabInstance: {fileID: 0}
|
|
||||||
m_PrefabAsset: {fileID: 0}
|
|
||||||
m_GameObject: {fileID: 4612363183729467837}
|
|
||||||
m_Enabled: 1
|
|
||||||
m_EditorHideFlags: 0
|
|
||||||
m_Script: {fileID: 11500000, guid: 01614664b831546d2ae94a42149d80ac, type: 3}
|
|
||||||
m_Name:
|
|
||||||
m_EditorClassIdentifier:
|
|
||||||
m_SendPointerHoverToParent: 1
|
|
||||||
m_MoveRepeatDelay: 0.5
|
|
||||||
m_MoveRepeatRate: 0.1
|
|
||||||
m_XRTrackingOrigin: {fileID: 0}
|
|
||||||
m_ActionsAsset: {fileID: -944628639613478452, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
|
|
||||||
m_PointAction: {fileID: -1654692200621890270, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
|
|
||||||
m_MoveAction: {fileID: -8784545083839296357, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
|
|
||||||
m_SubmitAction: {fileID: 392368643174621059, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
|
|
||||||
m_CancelAction: {fileID: 7727032971491509709, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
|
|
||||||
m_LeftClickAction: {fileID: 3001919216989983466, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
|
|
||||||
m_MiddleClickAction: {fileID: -2185481485913320682, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
|
|
||||||
m_RightClickAction: {fileID: -4090225696740746782, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
|
|
||||||
m_ScrollWheelAction: {fileID: 6240969308177333660, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
|
|
||||||
m_TrackedDevicePositionAction: {fileID: 6564999863303420839, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
|
|
||||||
m_TrackedDeviceOrientationAction: {fileID: 7970375526676320489, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
|
|
||||||
m_DeselectOnBackgroundClick: 1
|
|
||||||
m_PointerBehavior: 0
|
|
||||||
m_CursorLockBehavior: 0
|
|
||||||
m_ScrollDeltaPerTick: 6
|
|
||||||
@ -1,7 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 9368ff38b2090b2468f8358242026e4b
|
|
||||||
PrefabImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
@ -1 +0,0 @@
|
|||||||
[{"uiElementRegex":"Rect","componentType":"RectTransform"},{"uiElementRegex":"Obj","componentType":"GameObject"},{"uiElementRegex":"Tf","componentType":"Transform"},{"uiElementRegex":"Btn","componentType":"UXButton"},{"uiElementRegex":"Slider","componentType":"Slider"},{"uiElementRegex":"Img","componentType":"UXImage"},{"uiElementRegex":"RImg","componentType":"RawImage"},{"uiElementRegex":"Scrollbar","componentType":"Scrollbar"},{"uiElementRegex":"ScrollRect","componentType":"ScrollRect"},{"uiElementRegex":"GLayout","componentType":"GridLayoutGroup"},{"uiElementRegex":"HLayout","componentType":"HorizontalLayoutGroup"},{"uiElementRegex":"VLayout","componentType":"VerticalLayoutGroup"},{"uiElementRegex":"Text","componentType":"TMPro.TextMeshProUGUI"},{"uiElementRegex":"TogGroup","componentType":"UXGroup"},{"uiElementRegex":"Mask2D","componentType":"RectMask2D"},{"uiElementRegex":"Video","componentType":"Video.VideoPlayer"},{"uiElementRegex":"Input","componentType":"TMPro.TMP_InputField"},{"uiElementRegex":"CanvasGroup","componentType":"CanvasGroup"},{"uiElementRegex":"ScrollView","componentType":"RecyclerView"},{"uiElementRegex":"Drag","componentType":"UXDraggable"}]
|
|
||||||
@ -1,7 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 59f4e0b608fbfde488c05a9ab77746b8
|
|
||||||
TextScriptImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 2f54df36513f40bd80b00f7149741495
|
|
||||||
timeCreated: 1737704936
|
|
||||||
@ -1,99 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using AlicizaX.Editor.Setting;
|
|
||||||
using AlicizaX;
|
|
||||||
using AlicizaX.UI.Runtime;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
using Sirenix.OdinInspector;
|
|
||||||
using UnityEngine;
|
|
||||||
using UnityEngine.Serialization;
|
|
||||||
|
|
||||||
namespace AlicizaX.UI.Editor
|
|
||||||
{
|
|
||||||
[AlicizaX.Editor.Setting.FilePath("ProjectSettings/UIGenerateConfiguration.asset")]
|
|
||||||
internal class UIGenerateConfiguration : ScriptableSingleton<UIGenerateConfiguration>
|
|
||||||
{
|
|
||||||
public UIGenerateCommonData UIGenerateCommonData = new UIGenerateCommonData();
|
|
||||||
public UIScriptGenerateConfig UIScriptGenerateConfig = new UIScriptGenerateConfig();
|
|
||||||
public List<UIEelementRegexData> UIElementRegexConfigs = new List<UIEelementRegexData>();
|
|
||||||
}
|
|
||||||
|
|
||||||
[System.Serializable]
|
|
||||||
public class UIGenerateCommonData
|
|
||||||
{
|
|
||||||
[LabelText("组件检查分隔符")] public string ComCheckSplitName = "#";
|
|
||||||
[LabelText("组件结尾分隔符")] public string ComCheckEndName = "@";
|
|
||||||
[LabelText("数组组件检查分隔符")] public string ArrayComSplitName = "*";
|
|
||||||
[LabelText("生成脚本前缀")] public string GeneratePrefix = "ui";
|
|
||||||
[LabelText("排除表")] public string[] ExcludeKeywords = { "ViewHolder" };
|
|
||||||
|
|
||||||
[ShowInInspector] [LabelText("生成路径拼接")]
|
|
||||||
public Dictionary<string, string> CombineWords = new Dictionary<string, string>
|
|
||||||
{
|
|
||||||
{ "Window", "Window" },
|
|
||||||
{ "ViewHolder", "ViewHolder" },
|
|
||||||
{ "Widget", "Widget" },
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
[System.Serializable]
|
|
||||||
public class UIEelementRegexData
|
|
||||||
{
|
|
||||||
public string uiElementRegex;
|
|
||||||
|
|
||||||
|
|
||||||
[ShowInInspector] [ValueDropdown("GetFilteredTypeList", ExpandAllMenuItems = false)]
|
|
||||||
public string componentType;
|
|
||||||
|
|
||||||
|
|
||||||
private static List<string> cacheFilterType;
|
|
||||||
|
|
||||||
public IEnumerable<string> GetFilteredTypeList()
|
|
||||||
{
|
|
||||||
if (cacheFilterType == null)
|
|
||||||
{
|
|
||||||
cacheFilterType = AlicizaX.Utility.Assembly.GetTypes()
|
|
||||||
.Where(m => !m.FullName.Contains("Editor"))
|
|
||||||
.Where(x => !x.IsAbstract || x.IsInterface)
|
|
||||||
.Where(x => !x.IsGenericTypeDefinition)
|
|
||||||
.Where(x => !x.IsSubclassOf(typeof(UIHolderObjectBase)))
|
|
||||||
.Where(x => x.IsSubclassOf(typeof(Component)))
|
|
||||||
.Where(x => !x.FullName.Contains("YooAsset"))
|
|
||||||
.Where(x => !x.FullName.Contains(("Unity.VisualScripting")))
|
|
||||||
.Where(x => !x.FullName.Contains(("Cysharp.Threading")))
|
|
||||||
.Where(x => !x.FullName.Contains(("UnityEngine.Rendering.UI.Debug")))
|
|
||||||
.Where(x => !x.FullName.Contains(("Unity.PerformanceTesting")))
|
|
||||||
.Where(x => !x.FullName.Contains(("UnityEngine.TestTools")))
|
|
||||||
.Select(x => x.Name).ToList();
|
|
||||||
|
|
||||||
cacheFilterType.Add(typeof(GameObject).Name);
|
|
||||||
}
|
|
||||||
|
|
||||||
return cacheFilterType;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
[System.Serializable]
|
|
||||||
public class UIScriptGenerateConfig
|
|
||||||
{
|
|
||||||
[BoxGroup("主工程")] public UIScriptGenerateData MainProjectUIScriptGenerateData = new UIScriptGenerateData();
|
|
||||||
[BoxGroup("热更工程")] public UIScriptGenerateData HotFixProjectUIScriptGenerateData = new UIScriptGenerateData();
|
|
||||||
}
|
|
||||||
|
|
||||||
[System.Serializable]
|
|
||||||
public class UIScriptGenerateData
|
|
||||||
{
|
|
||||||
public string NameSpace;
|
|
||||||
|
|
||||||
[Sirenix.OdinInspector.FolderPath(RequireExistingPath = true, AbsolutePath = false)]
|
|
||||||
public string GenerateHolderCodePath;
|
|
||||||
|
|
||||||
[Sirenix.OdinInspector.FolderPath(RequireExistingPath = true, AbsolutePath = false)]
|
|
||||||
public string UIPrefabRootPath;
|
|
||||||
|
|
||||||
public EUIResLoadType LoadType;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,11 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: b212f141eb1bc7b4d97c4dc8b938bc5f
|
|
||||||
MonoImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
serializedVersion: 2
|
|
||||||
defaultReferences: []
|
|
||||||
executionOrder: 0
|
|
||||||
icon: {instanceID: 0}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
@ -1,201 +0,0 @@
|
|||||||
Apache License
|
|
||||||
Version 2.0, January 2004
|
|
||||||
http://www.apache.org/licenses/
|
|
||||||
|
|
||||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
||||||
|
|
||||||
1. Definitions.
|
|
||||||
|
|
||||||
"License" shall mean the terms and conditions for use, reproduction,
|
|
||||||
and distribution as defined by Sections 1 through 9 of this document.
|
|
||||||
|
|
||||||
"Licensor" shall mean the copyright owner or entity authorized by
|
|
||||||
the copyright owner that is granting the License.
|
|
||||||
|
|
||||||
"Legal Entity" shall mean the union of the acting entity and all
|
|
||||||
other entities that control, are controlled by, or are under common
|
|
||||||
control with that entity. For the purposes of this definition,
|
|
||||||
"control" means (i) the power, direct or indirect, to cause the
|
|
||||||
direction or management of such entity, whether by contract or
|
|
||||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
||||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
||||||
|
|
||||||
"You" (or "Your") shall mean an individual or Legal Entity
|
|
||||||
exercising permissions granted by this License.
|
|
||||||
|
|
||||||
"Source" form shall mean the preferred form for making modifications,
|
|
||||||
including but not limited to software source code, documentation
|
|
||||||
source, and configuration files.
|
|
||||||
|
|
||||||
"Object" form shall mean any form resulting from mechanical
|
|
||||||
transformation or translation of a Source form, including but
|
|
||||||
not limited to compiled object code, generated documentation,
|
|
||||||
and conversions to other media types.
|
|
||||||
|
|
||||||
"Work" shall mean the work of authorship, whether in Source or
|
|
||||||
Object form, made available under the License, as indicated by a
|
|
||||||
copyright notice that is included in or attached to the work
|
|
||||||
(an example is provided in the Appendix below).
|
|
||||||
|
|
||||||
"Derivative Works" shall mean any work, whether in Source or Object
|
|
||||||
form, that is based on (or derived from) the Work and for which the
|
|
||||||
editorial revisions, annotations, elaborations, or other modifications
|
|
||||||
represent, as a whole, an original work of authorship. For the purposes
|
|
||||||
of this License, Derivative Works shall not include works that remain
|
|
||||||
separable from, or merely link (or bind by name) to the interfaces of,
|
|
||||||
the Work and Derivative Works thereof.
|
|
||||||
|
|
||||||
"Contribution" shall mean any work of authorship, including
|
|
||||||
the original version of the Work and any modifications or additions
|
|
||||||
to that Work or Derivative Works thereof, that is intentionally
|
|
||||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
||||||
or by an individual or Legal Entity authorized to submit on behalf of
|
|
||||||
the copyright owner. For the purposes of this definition, "submitted"
|
|
||||||
means any form of electronic, verbal, or written communication sent
|
|
||||||
to the Licensor or its representatives, including but not limited to
|
|
||||||
communication on electronic mailing lists, source code control systems,
|
|
||||||
and issue tracking systems that are managed by, or on behalf of, the
|
|
||||||
Licensor for the purpose of discussing and improving the Work, but
|
|
||||||
excluding communication that is conspicuously marked or otherwise
|
|
||||||
designated in writing by the copyright owner as "Not a Contribution."
|
|
||||||
|
|
||||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
||||||
on behalf of whom a Contribution has been received by Licensor and
|
|
||||||
subsequently incorporated within the Work.
|
|
||||||
|
|
||||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
copyright license to reproduce, prepare Derivative Works of,
|
|
||||||
publicly display, publicly perform, sublicense, and distribute the
|
|
||||||
Work and such Derivative Works in Source or Object form.
|
|
||||||
|
|
||||||
3. Grant of Patent License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
(except as stated in this section) patent license to make, have made,
|
|
||||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
||||||
where such license applies only to those patent claims licensable
|
|
||||||
by such Contributor that are necessarily infringed by their
|
|
||||||
Contribution(s) alone or by combination of their Contribution(s)
|
|
||||||
with the Work to which such Contribution(s) was submitted. If You
|
|
||||||
institute patent litigation against any entity (including a
|
|
||||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
||||||
or a Contribution incorporated within the Work constitutes direct
|
|
||||||
or contributory patent infringement, then any patent licenses
|
|
||||||
granted to You under this License for that Work shall terminate
|
|
||||||
as of the date such litigation is filed.
|
|
||||||
|
|
||||||
4. Redistribution. You may reproduce and distribute copies of the
|
|
||||||
Work or Derivative Works thereof in any medium, with or without
|
|
||||||
modifications, and in Source or Object form, provided that You
|
|
||||||
meet the following conditions:
|
|
||||||
|
|
||||||
(a) You must give any other recipients of the Work or
|
|
||||||
Derivative Works a copy of this License; and
|
|
||||||
|
|
||||||
(b) You must cause any modified files to carry prominent notices
|
|
||||||
stating that You changed the files; and
|
|
||||||
|
|
||||||
(c) You must retain, in the Source form of any Derivative Works
|
|
||||||
that You distribute, all copyright, patent, trademark, and
|
|
||||||
attribution notices from the Source form of the Work,
|
|
||||||
excluding those notices that do not pertain to any part of
|
|
||||||
the Derivative Works; and
|
|
||||||
|
|
||||||
(d) If the Work includes a "NOTICE" text file as part of its
|
|
||||||
distribution, then any Derivative Works that You distribute must
|
|
||||||
include a readable copy of the attribution notices contained
|
|
||||||
within such NOTICE file, excluding those notices that do not
|
|
||||||
pertain to any part of the Derivative Works, in at least one
|
|
||||||
of the following places: within a NOTICE text file distributed
|
|
||||||
as part of the Derivative Works; within the Source form or
|
|
||||||
documentation, if provided along with the Derivative Works; or,
|
|
||||||
within a display generated by the Derivative Works, if and
|
|
||||||
wherever such third-party notices normally appear. The contents
|
|
||||||
of the NOTICE file are for informational purposes only and
|
|
||||||
do not modify the License. You may add Your own attribution
|
|
||||||
notices within Derivative Works that You distribute, alongside
|
|
||||||
or as an addendum to the NOTICE text from the Work, provided
|
|
||||||
that such additional attribution notices cannot be construed
|
|
||||||
as modifying the License.
|
|
||||||
|
|
||||||
You may add Your own copyright statement to Your modifications and
|
|
||||||
may provide additional or different license terms and conditions
|
|
||||||
for use, reproduction, or distribution of Your modifications, or
|
|
||||||
for any such Derivative Works as a whole, provided Your use,
|
|
||||||
reproduction, and distribution of the Work otherwise complies with
|
|
||||||
the conditions stated in this License.
|
|
||||||
|
|
||||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
||||||
any Contribution intentionally submitted for inclusion in the Work
|
|
||||||
by You to the Licensor shall be under the terms and conditions of
|
|
||||||
this License, without any additional terms or conditions.
|
|
||||||
Notwithstanding the above, nothing herein shall supersede or modify
|
|
||||||
the terms of any separate license agreement you may have executed
|
|
||||||
with Licensor regarding such Contributions.
|
|
||||||
|
|
||||||
6. Trademarks. This License does not grant permission to use the trade
|
|
||||||
names, trademarks, service marks, or product names of the Licensor,
|
|
||||||
except as required for reasonable and customary use in describing the
|
|
||||||
origin of the Work and reproducing the content of the NOTICE file.
|
|
||||||
|
|
||||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
||||||
agreed to in writing, Licensor provides the Work (and each
|
|
||||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
||||||
implied, including, without limitation, any warranties or conditions
|
|
||||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
||||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
||||||
appropriateness of using or redistributing the Work and assume any
|
|
||||||
risks associated with Your exercise of permissions under this License.
|
|
||||||
|
|
||||||
8. Limitation of Liability. In no event and under no legal theory,
|
|
||||||
whether in tort (including negligence), contract, or otherwise,
|
|
||||||
unless required by applicable law (such as deliberate and grossly
|
|
||||||
negligent acts) or agreed to in writing, shall any Contributor be
|
|
||||||
liable to You for damages, including any direct, indirect, special,
|
|
||||||
incidental, or consequential damages of any character arising as a
|
|
||||||
result of this License or out of the use or inability to use the
|
|
||||||
Work (including but not limited to damages for loss of goodwill,
|
|
||||||
work stoppage, computer failure or malfunction, or any and all
|
|
||||||
other commercial damages or losses), even if such Contributor
|
|
||||||
has been advised of the possibility of such damages.
|
|
||||||
|
|
||||||
9. Accepting Warranty or Additional Liability. While redistributing
|
|
||||||
the Work or Derivative Works thereof, You may choose to offer,
|
|
||||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
||||||
or other liability obligations and/or rights consistent with this
|
|
||||||
License. However, in accepting such obligations, You may act only
|
|
||||||
on Your own behalf and on Your sole responsibility, not on behalf
|
|
||||||
of any other Contributor, and only if You agree to indemnify,
|
|
||||||
defend, and hold each Contributor harmless for any liability
|
|
||||||
incurred by, or claims asserted against, such Contributor by reason
|
|
||||||
of your accepting any such warranty or additional liability.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
APPENDIX: How to apply the Apache License to your work.
|
|
||||||
|
|
||||||
To apply the Apache License to your work, attach the following
|
|
||||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
||||||
replaced with your own identifying information. (Don't include
|
|
||||||
the brackets!) The text should be enclosed in the appropriate
|
|
||||||
comment syntax for the file format. We also recommend that a
|
|
||||||
file or class name and description of purpose be included on the
|
|
||||||
same "printed page" as the copyright notice for easier
|
|
||||||
identification within third-party archives.
|
|
||||||
|
|
||||||
Copyright [2023] [ALianBlank of copyright owner][alianblank@outlook.com][https://alianblank.com/]
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
@ -1,7 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 0ca8dd70d34327149b2f7593c47f4ba5
|
|
||||||
TextScriptImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
@ -1,8 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 0d19cb13132847146b9b49bc8a8c47d8
|
|
||||||
folderAsset: yes
|
|
||||||
DefaultImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
Binary file not shown.
@ -1,52 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 4073667e4abebeb479ff5f9810398e92
|
|
||||||
labels:
|
|
||||||
- RoslynAnalyzer
|
|
||||||
PluginImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
serializedVersion: 3
|
|
||||||
iconMap: {}
|
|
||||||
executionOrder: {}
|
|
||||||
defineConstraints: []
|
|
||||||
isPreloaded: 0
|
|
||||||
isOverridable: 1
|
|
||||||
isExplicitlyReferenced: 0
|
|
||||||
validateReferences: 1
|
|
||||||
platformData:
|
|
||||||
Any:
|
|
||||||
enabled: 1
|
|
||||||
settings:
|
|
||||||
Exclude Editor: 1
|
|
||||||
Exclude Linux64: 1
|
|
||||||
Exclude OSXUniversal: 1
|
|
||||||
Exclude Win: 1
|
|
||||||
Exclude Win64: 1
|
|
||||||
Editor:
|
|
||||||
enabled: 0
|
|
||||||
settings:
|
|
||||||
CPU: AnyCPU
|
|
||||||
DefaultValueInitialized: true
|
|
||||||
OS: AnyOS
|
|
||||||
Linux64:
|
|
||||||
enabled: 0
|
|
||||||
settings:
|
|
||||||
CPU: AnyCPU
|
|
||||||
OSXUniversal:
|
|
||||||
enabled: 0
|
|
||||||
settings:
|
|
||||||
CPU: AnyCPU
|
|
||||||
Win:
|
|
||||||
enabled: 0
|
|
||||||
settings:
|
|
||||||
CPU: AnyCPU
|
|
||||||
Win64:
|
|
||||||
enabled: 0
|
|
||||||
settings:
|
|
||||||
CPU: AnyCPU
|
|
||||||
WindowsStoreApps:
|
|
||||||
enabled: 0
|
|
||||||
settings:
|
|
||||||
CPU: AnyCPU
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
@ -1,8 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 0493f0d8cd0bd0746a8d4d04bf6bcc1a
|
|
||||||
folderAsset: yes
|
|
||||||
DefaultImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
@ -1,22 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "AlicizaX.UI.Runtime",
|
|
||||||
"rootNamespace": "AlicizaX.UI.Runtime",
|
|
||||||
"references": [
|
|
||||||
"GUID:75b6f2078d190f14dbda4a5b747d709c",
|
|
||||||
"GUID:56115dc8e38144842823f4ee0dcad88b",
|
|
||||||
"GUID:be2f20a77f3232f44b9711ef43234aac",
|
|
||||||
"GUID:f51ebe6a0ceec4240a699833d6309b23",
|
|
||||||
"GUID:189d55e03d78888459720d730f4d2424",
|
|
||||||
"GUID:4041d17782e62754ba8777fe2dfb6b27",
|
|
||||||
"GUID:2393d135922de5c4ab12e74f1e397920"
|
|
||||||
],
|
|
||||||
"includePlatforms": [],
|
|
||||||
"excludePlatforms": [],
|
|
||||||
"allowUnsafeCode": true,
|
|
||||||
"overrideReferences": false,
|
|
||||||
"precompiledReferences": [],
|
|
||||||
"autoReferenced": true,
|
|
||||||
"defineConstraints": [],
|
|
||||||
"versionDefines": [],
|
|
||||||
"noEngineReferences": false
|
|
||||||
}
|
|
||||||
@ -1,7 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: e9c35c8938f782649bb7e670099ca425
|
|
||||||
AssemblyDefinitionImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 003872fc9d1944708cac097b45a8382a
|
|
||||||
timeCreated: 1737703086
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: f783b53bbb3de8e48a9127ffd6463454
|
|
||||||
timeCreated: 1724221459
|
|
||||||
@ -1,44 +0,0 @@
|
|||||||
namespace AlicizaX.UI.Runtime
|
|
||||||
{
|
|
||||||
public enum UILayer
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 最低层
|
|
||||||
/// 要显示的这个就是最低的层级
|
|
||||||
/// </summary>
|
|
||||||
Background = 0,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 场景层
|
|
||||||
/// 比如 血条飘字不是做在3D时 用2D实现时的层
|
|
||||||
/// 比如 头像 ...
|
|
||||||
/// </summary>
|
|
||||||
Scene = 1,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 普通面板层
|
|
||||||
/// 全屏界面
|
|
||||||
/// </summary>
|
|
||||||
UI = 2,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 弹窗层
|
|
||||||
/// 一般是非全屏界面,可同时存在的
|
|
||||||
/// </summary>
|
|
||||||
Popup = 3,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 提示层
|
|
||||||
/// 一般 提示飘字 确认弹窗 跑马灯之类的
|
|
||||||
/// </summary>
|
|
||||||
Tips = 4,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 最高层
|
|
||||||
/// 一般新手引导之类的
|
|
||||||
/// </summary>
|
|
||||||
Top = 5,
|
|
||||||
|
|
||||||
All = 6,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 2d4172fa9d8337340899edb34207e108
|
|
||||||
timeCreated: 1724221472
|
|
||||||
@ -1,31 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq.Expressions;
|
|
||||||
|
|
||||||
public static class InstanceFactory
|
|
||||||
{
|
|
||||||
private static readonly Dictionary<Type, Func<object>> _constructorCache = new();
|
|
||||||
|
|
||||||
public static object CreateInstanceOptimized(Type type)
|
|
||||||
{
|
|
||||||
if (!_constructorCache.TryGetValue(type, out var constructor))
|
|
||||||
{
|
|
||||||
// 验证是否存在公共无参构造函数
|
|
||||||
var ctor = type.GetConstructor(Type.EmptyTypes);
|
|
||||||
if (ctor == null)
|
|
||||||
{
|
|
||||||
throw new MissingMethodException($"类型 {type.Name} 缺少公共无参构造函数");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 构建表达式树:new T()
|
|
||||||
var newExpr = Expression.New(ctor);
|
|
||||||
var lambda = Expression.Lambda<Func<object>>(newExpr);
|
|
||||||
constructor = lambda.Compile();
|
|
||||||
|
|
||||||
// 缓存委托
|
|
||||||
_constructorCache[type] = constructor;
|
|
||||||
}
|
|
||||||
|
|
||||||
return constructor();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 195eee24a3e6423fbe4b9b537099a2d9
|
|
||||||
timeCreated: 1744176921
|
|
||||||
@ -1,78 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Linq;
|
|
||||||
using AlicizaX.Resource.Runtime;
|
|
||||||
using AlicizaX;
|
|
||||||
using Cysharp.Threading.Tasks;
|
|
||||||
using UnityEngine;
|
|
||||||
using Object = UnityEngine.Object;
|
|
||||||
|
|
||||||
namespace AlicizaX.UI.Runtime
|
|
||||||
{
|
|
||||||
public static class UIHolderFactory
|
|
||||||
{
|
|
||||||
private static readonly IResourceModule ResourceModule;
|
|
||||||
|
|
||||||
static UIHolderFactory()
|
|
||||||
{
|
|
||||||
ResourceModule = ModuleSystem.GetModule<IResourceModule>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static async UniTask<T> CreateUIHolder<T>(Transform parent) where T : UIHolderObjectBase
|
|
||||||
{
|
|
||||||
if (UIResRegistry.TryGet(typeof(T).TypeHandle, out UIResRegistry.UIResInfo resInfo))
|
|
||||||
{
|
|
||||||
GameObject obj = await LoadUIResourcesAsync(resInfo, parent);
|
|
||||||
|
|
||||||
return obj.GetComponent<T>();
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static async UniTask<GameObject> LoadUIResourcesAsync(UIResRegistry.UIResInfo resInfo, Transform parent)
|
|
||||||
{
|
|
||||||
return resInfo.LoadType == EUIResLoadType.AssetBundle
|
|
||||||
? await ResourceModule.LoadGameObjectAsync(resInfo.Location, parent)
|
|
||||||
: await InstantiateResourceAsync(resInfo.Location, parent);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static async UniTask CreateUIResource(UIMetadata meta, Transform parent, UIBase owner = null)
|
|
||||||
{
|
|
||||||
if (meta.State != UIState.CreatedUI) return;
|
|
||||||
GameObject obj = await LoadUIResourcesAsync(meta.ResInfo, parent);
|
|
||||||
ValidateAndBind(meta, obj, owner);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static void LoadUIResourcesSync(UIMetadata meta, Transform parent, UIBase owner = null)
|
|
||||||
{
|
|
||||||
if (meta.State != UIState.CreatedUI) return;
|
|
||||||
|
|
||||||
GameObject obj = meta.ResInfo.LoadType == EUIResLoadType.AssetBundle
|
|
||||||
? ResourceModule.LoadGameObject(meta.ResInfo.Location, parent)
|
|
||||||
: Object.Instantiate(Resources.Load<GameObject>(meta.ResInfo.Location), parent);
|
|
||||||
|
|
||||||
ValidateAndBind(meta, obj, owner);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private static void ValidateAndBind(UIMetadata meta, GameObject holderObject, UIBase owner)
|
|
||||||
{
|
|
||||||
if (!holderObject) throw new NullReferenceException($"UI resource load failed: {meta.ResInfo.Location}");
|
|
||||||
|
|
||||||
var holder = (UIHolderObjectBase)holderObject.GetComponent(meta.View.UIHolderType);
|
|
||||||
|
|
||||||
if (holder == null)
|
|
||||||
{
|
|
||||||
throw new InvalidCastException($"资源{holderObject.name}上不存在{meta.View.UIHolderType.FullName}");
|
|
||||||
}
|
|
||||||
|
|
||||||
meta.View?.BindUIHolder(holder, owner);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static async UniTask<GameObject> InstantiateResourceAsync(string location, Transform parent)
|
|
||||||
{
|
|
||||||
GameObject prefab = (GameObject)await Resources.LoadAsync<GameObject>(location);
|
|
||||||
return Object.Instantiate(prefab, parent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: d3cb20524d8440198708e90c56c76e38
|
|
||||||
timeCreated: 1739847047
|
|
||||||
@ -1,56 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Concurrent;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
|
|
||||||
namespace AlicizaX.UI.Runtime
|
|
||||||
{
|
|
||||||
public static class UIMetaRegistry
|
|
||||||
{
|
|
||||||
public readonly struct UIMetaInfo
|
|
||||||
{
|
|
||||||
public readonly RuntimeTypeHandle RuntimeTypeHandle;
|
|
||||||
public readonly RuntimeTypeHandle HolderRuntimeTypeHandle;
|
|
||||||
public readonly int UILayer;
|
|
||||||
public readonly bool FullScreen;
|
|
||||||
public readonly int CacheTime;
|
|
||||||
|
|
||||||
public UIMetaInfo(RuntimeTypeHandle runtimeTypeHandle, RuntimeTypeHandle holderRuntimeTypeHandle, UILayer windowLayer, bool fullScreen, int cacheTime)
|
|
||||||
{
|
|
||||||
RuntimeTypeHandle = runtimeTypeHandle;
|
|
||||||
HolderRuntimeTypeHandle = holderRuntimeTypeHandle;
|
|
||||||
UILayer = (int)windowLayer;
|
|
||||||
FullScreen = fullScreen;
|
|
||||||
CacheTime = cacheTime;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static readonly Dictionary<RuntimeTypeHandle, UIMetaInfo> _typeHandleMap = new();
|
|
||||||
private static readonly Dictionary<string, RuntimeTypeHandle> _stringHandleMap = new();
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static void Register(Type uiType, Type holderType, UILayer layer = UILayer.UI, bool fullScreen = false, int cacheTime = 0)
|
|
||||||
{
|
|
||||||
var holderHandle = holderType.TypeHandle;
|
|
||||||
var uiHandle = uiType.TypeHandle;
|
|
||||||
_typeHandleMap[uiHandle] = new UIMetaInfo(uiHandle, holderHandle, layer, fullScreen, cacheTime);
|
|
||||||
_stringHandleMap[uiType.Name] = uiHandle;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static bool TryGet(RuntimeTypeHandle handle, out UIMetaInfo info)
|
|
||||||
{
|
|
||||||
return _typeHandleMap.TryGetValue(handle, out info);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool TryGet(string type, out UIMetaInfo info)
|
|
||||||
{
|
|
||||||
RuntimeTypeHandle typeHandle;
|
|
||||||
if (_stringHandleMap.TryGetValue(type, out typeHandle))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
return _typeHandleMap.TryGetValue(typeHandle, out info);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: a9872b7a45da4d28b699bdf36ad792ca
|
|
||||||
timeCreated: 1744116849
|
|
||||||
@ -1,57 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
using AlicizaX;
|
|
||||||
using Cysharp.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace AlicizaX.UI.Runtime
|
|
||||||
{
|
|
||||||
internal sealed class UIMetadata
|
|
||||||
{
|
|
||||||
public UIBase View { get; private set; }
|
|
||||||
public readonly UIMetaRegistry.UIMetaInfo MetaInfo;
|
|
||||||
public readonly UIResRegistry.UIResInfo ResInfo;
|
|
||||||
public readonly Type UILogicType;
|
|
||||||
public bool InCache = false;
|
|
||||||
|
|
||||||
public UIState State
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (View == null) return UIState.Uninitialized;
|
|
||||||
return View.State;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public void CreateUI()
|
|
||||||
{
|
|
||||||
if (View is null)
|
|
||||||
{
|
|
||||||
View = (UIBase)InstanceFactory.CreateInstanceOptimized(UILogicType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
DisposeAsync().Forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
private async UniTask DisposeAsync()
|
|
||||||
{
|
|
||||||
if (State != UIState.Uninitialized && State != UIState.Destroying)
|
|
||||||
{
|
|
||||||
await View.InternalDestroy();
|
|
||||||
View = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public UIMetadata(Type uiType)
|
|
||||||
{
|
|
||||||
UILogicType = uiType;
|
|
||||||
|
|
||||||
UIMetaRegistry.TryGet(UILogicType.TypeHandle, out MetaInfo);
|
|
||||||
|
|
||||||
UIResRegistry.TryGet(MetaInfo.HolderRuntimeTypeHandle, out ResInfo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 9f48f37976fb440479f1d76953347817
|
|
||||||
timeCreated: 1724230882
|
|
||||||
@ -1,33 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using AlicizaX;
|
|
||||||
|
|
||||||
namespace AlicizaX.UI.Runtime
|
|
||||||
{
|
|
||||||
internal static class MetaTypeCache<T> where T : UIBase
|
|
||||||
{
|
|
||||||
public static readonly UIMetadata Metadata;
|
|
||||||
|
|
||||||
static MetaTypeCache()
|
|
||||||
{
|
|
||||||
var type = typeof(T);
|
|
||||||
Metadata = UIMetadataFactory.GetMetadata(type.TypeHandle);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static class UIMetadataFactory
|
|
||||||
{
|
|
||||||
private static readonly Dictionary<RuntimeTypeHandle, UIMetadata> UIWindowMetadata = new();
|
|
||||||
|
|
||||||
internal static UIMetadata GetMetadata(RuntimeTypeHandle handle)
|
|
||||||
{
|
|
||||||
if (!UIWindowMetadata.TryGetValue(handle, out var meta))
|
|
||||||
{
|
|
||||||
meta = new UIMetadata(Type.GetTypeFromHandle(handle));
|
|
||||||
UIWindowMetadata[handle] = meta;
|
|
||||||
}
|
|
||||||
|
|
||||||
return meta;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 908f3c05a3c74cc3aa0c35ec046e934d
|
|
||||||
timeCreated: 1739845718
|
|
||||||
@ -1,37 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Concurrent;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
using UnityEditor;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
namespace AlicizaX.UI.Runtime
|
|
||||||
{
|
|
||||||
public static class UIResRegistry
|
|
||||||
{
|
|
||||||
private static readonly Dictionary<RuntimeTypeHandle, UIResInfo> _typeHandleMap = new();
|
|
||||||
|
|
||||||
public readonly struct UIResInfo
|
|
||||||
{
|
|
||||||
public readonly string Location;
|
|
||||||
public readonly EUIResLoadType LoadType;
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public UIResInfo(string location, EUIResLoadType loadType)
|
|
||||||
{
|
|
||||||
Location = location;
|
|
||||||
LoadType = loadType;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static void Register(Type holderType, string location, EUIResLoadType loadType)
|
|
||||||
{
|
|
||||||
var handle = holderType.TypeHandle;
|
|
||||||
_typeHandleMap[handle] = new UIResInfo(location, loadType);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool TryGet(RuntimeTypeHandle handle, out UIResInfo info)
|
|
||||||
=> _typeHandleMap.TryGetValue(handle, out info);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 0132d28e3a4943a4acd10fbc7d35ad51
|
|
||||||
timeCreated: 1744113525
|
|
||||||
@ -1,57 +0,0 @@
|
|||||||
using System;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
namespace AlicizaX.UI.Runtime
|
|
||||||
{
|
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.Class)]
|
|
||||||
public class WindowAttribute : Attribute
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 窗口层级
|
|
||||||
/// </summary>
|
|
||||||
public readonly UILayer WindowLayer;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 全屏窗口标记。
|
|
||||||
/// </summary>
|
|
||||||
public readonly bool FullScreen;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 延时关闭
|
|
||||||
/// </summary>
|
|
||||||
public readonly int CacheTime;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="windowLayer">显示层级</param>
|
|
||||||
/// <param name="fullScreen">是否全屏遮挡</param>
|
|
||||||
/// <param name="cacheTime">缓存时间/s -1永久 0不 >=1生效</param>
|
|
||||||
public WindowAttribute(UILayer windowLayer, bool fullScreen = false, int cacheTime = 0)
|
|
||||||
{
|
|
||||||
WindowLayer = windowLayer;
|
|
||||||
FullScreen = fullScreen;
|
|
||||||
CacheTime = cacheTime;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.Class)]
|
|
||||||
public class UIResAttribute : Attribute
|
|
||||||
{
|
|
||||||
public readonly string ResLocation;
|
|
||||||
public readonly EUIResLoadType ResLoadType;
|
|
||||||
|
|
||||||
public UIResAttribute(string location, EUIResLoadType loadType)
|
|
||||||
{
|
|
||||||
ResLocation = location;
|
|
||||||
ResLoadType = loadType;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum EUIResLoadType:byte
|
|
||||||
{
|
|
||||||
Resources,
|
|
||||||
AssetBundle
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 8144120881e676f4cbdb6209550c7097
|
|
||||||
timeCreated: 1680511434
|
|
||||||
@ -1,66 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
using AlicizaX.Event.Runtime;
|
|
||||||
using AlicizaX.EventKit;
|
|
||||||
|
|
||||||
namespace AlicizaX
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 游戏事件管理器。
|
|
||||||
/// </summary>
|
|
||||||
public class EventListenerProxy : IMemory
|
|
||||||
{
|
|
||||||
private readonly bool _isInit = false;
|
|
||||||
private List<(string, EventHandler<GameEventArgs>)> eventMaps;
|
|
||||||
private List<EventRuntimeHandle> eventHandles;
|
|
||||||
|
|
||||||
public EventListenerProxy()
|
|
||||||
{
|
|
||||||
if (!_isInit)
|
|
||||||
{
|
|
||||||
eventMaps = new();
|
|
||||||
eventHandles = new();
|
|
||||||
}
|
|
||||||
|
|
||||||
_isInit = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 清理内存对象回收入池。
|
|
||||||
/// </summary>
|
|
||||||
public void Clear()
|
|
||||||
{
|
|
||||||
if (!_isInit)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < eventMaps.Count; ++i)
|
|
||||||
{
|
|
||||||
ModuleSystem.GetModule<IEventModule>().Unsubscribe(eventMaps[i].Item1, eventMaps[i].Item2);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = eventHandles.Count - 1; i > 0; i++)
|
|
||||||
{
|
|
||||||
eventHandles[i].Dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
eventHandles.Clear();
|
|
||||||
eventMaps.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Subscribe(string id, EventHandler<GameEventArgs> handler)
|
|
||||||
{
|
|
||||||
eventMaps.Add((id, handler));
|
|
||||||
ModuleSystem.GetModule<IEventModule>().Subscribe(id, handler);
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public void Subscribe<T>(Action<T> handler) where T : struct, IEventArgs
|
|
||||||
{
|
|
||||||
EventRuntimeHandle handle = EventContainer<T>.Subscribe(handler);
|
|
||||||
eventHandles.Add(handle);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: eb346bc3be28f89468e2c071e7ab9594
|
|
||||||
timeCreated: 1680273952
|
|
||||||
@ -1,8 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 0510a64b7f93de943ae13f097faf50d8
|
|
||||||
folderAsset: yes
|
|
||||||
DefaultImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
@ -1,24 +0,0 @@
|
|||||||
using System;
|
|
||||||
using AlicizaX.Resource.Runtime;
|
|
||||||
using AlicizaX;
|
|
||||||
using AlicizaX.Timer.Runtime;
|
|
||||||
using Cysharp.Threading.Tasks;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
namespace AlicizaX.UI.Runtime
|
|
||||||
{
|
|
||||||
public interface IUIModule : IModule, IModuleUpdate
|
|
||||||
{
|
|
||||||
void Initlize(Transform root,bool isOrthographic);
|
|
||||||
Camera UICamera { get; set; }
|
|
||||||
Transform UICanvasRoot { get; set; }
|
|
||||||
UniTask<UIBase> ShowUI<T>(params System.Object[] userDatas) where T : UIBase;
|
|
||||||
UniTask<UIBase>? ShowUI(string type, params object[] userDatas);
|
|
||||||
UniTask<T> ShowUIAsync<T>(params System.Object[] userDatas) where T : UIBase;
|
|
||||||
void CloseUI<T>(bool force = false) where T : UIBase;
|
|
||||||
T GetUI<T>() where T : UIBase;
|
|
||||||
|
|
||||||
void CloseUI(RuntimeTypeHandle handle, bool force = false);
|
|
||||||
protected internal void SetTimerManager(ITimerModule timerModule);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,2 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 4fc14a8ed26f89443b0844936e492514
|
|
||||||
@ -1,80 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
namespace AlicizaX.UI.Runtime
|
|
||||||
{
|
|
||||||
internal sealed partial class UIModule
|
|
||||||
{
|
|
||||||
private GameObject m_LayerBlock; //内部屏蔽对象 显示时之下的所有UI将不可操作
|
|
||||||
|
|
||||||
private int m_LastCountDownGuid; //倒计时的唯一ID
|
|
||||||
|
|
||||||
private void InitUIBlock()
|
|
||||||
{
|
|
||||||
m_LayerBlock = new GameObject("LayerBlock");
|
|
||||||
var rect = m_LayerBlock.AddComponent<RectTransform>();
|
|
||||||
m_LayerBlock.AddComponent<CanvasRenderer>();
|
|
||||||
m_LayerBlock.AddComponent<UIBlock>();
|
|
||||||
rect.SetParent(UICanvasRoot);
|
|
||||||
rect.SetAsLastSibling();
|
|
||||||
rect.ResetToFullScreen();
|
|
||||||
SetLayerBlockOption(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 设置UI遮挡
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="timeDuration">倒计时/s</param>
|
|
||||||
public void SetUIBlock(float timeDuration)
|
|
||||||
{
|
|
||||||
if (m_LastCountDownGuid != 0)
|
|
||||||
{
|
|
||||||
_timerModule.RemoveTimer(m_LastCountDownGuid);
|
|
||||||
}
|
|
||||||
|
|
||||||
SetLayerBlockOption(true);
|
|
||||||
m_LastCountDownGuid = _timerModule.AddTimer(OnBlockCountDown, timeDuration);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 强制退出UI遮挡
|
|
||||||
/// </summary>
|
|
||||||
public void ForceExitBlock()
|
|
||||||
{
|
|
||||||
if (m_LastCountDownGuid != 0)
|
|
||||||
{
|
|
||||||
_timerModule.RemoveTimer(m_LastCountDownGuid);
|
|
||||||
}
|
|
||||||
|
|
||||||
RecoverLayerOptionAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnBlockCountDown(object[] args)
|
|
||||||
{
|
|
||||||
RecoverLayerOptionAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 设置UI是否可以操作
|
|
||||||
/// 不能提供此API对外操作
|
|
||||||
/// 因为有人设置过后就会忘记恢复
|
|
||||||
/// 如果你确实需要你可以设置 禁止无限时间
|
|
||||||
/// 之后调用恢复操作也可以做到
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="value">true = 可以操作 = 屏蔽层会被隐藏</param>
|
|
||||||
private void SetLayerBlockOption(bool value)
|
|
||||||
{
|
|
||||||
m_LayerBlock.SetActive(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 强制恢复层级到可操作状态
|
|
||||||
/// 此方法会强制打断倒计时 根据需求调用
|
|
||||||
/// </summary>
|
|
||||||
public void RecoverLayerOptionAll()
|
|
||||||
{
|
|
||||||
SetLayerBlockOption(false);
|
|
||||||
m_LastCountDownGuid = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: e880f39de986cc142a161d678fd7fc84
|
|
||||||
timeCreated: 1724223150
|
|
||||||
@ -1,58 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using AlicizaX;
|
|
||||||
|
|
||||||
namespace AlicizaX.UI.Runtime
|
|
||||||
{
|
|
||||||
internal sealed partial class UIModule
|
|
||||||
{
|
|
||||||
private readonly Dictionary<RuntimeTypeHandle, (UIMetadata, int)> m_CacheWindow = new();
|
|
||||||
|
|
||||||
private void CacheWindow(UIMetadata uiMetadata, bool force)
|
|
||||||
{
|
|
||||||
if (uiMetadata == null || uiMetadata.View == null)
|
|
||||||
{
|
|
||||||
Log.Error(" ui not exist!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (force || uiMetadata.MetaInfo.CacheTime == 0)
|
|
||||||
{
|
|
||||||
uiMetadata.Dispose();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
RemoveFromCache(uiMetadata.MetaInfo.RuntimeTypeHandle);
|
|
||||||
int tiemrId = -1;
|
|
||||||
|
|
||||||
uiMetadata.View.Holder.transform.SetParent(UICacheLayer);
|
|
||||||
if (uiMetadata.MetaInfo.CacheTime > 0)
|
|
||||||
{
|
|
||||||
tiemrId = _timerModule.AddTimer(OnTimerDiposeWindow, uiMetadata.MetaInfo.CacheTime, false, true, uiMetadata);
|
|
||||||
}
|
|
||||||
|
|
||||||
uiMetadata.InCache = true;
|
|
||||||
m_CacheWindow.Add(uiMetadata.MetaInfo.RuntimeTypeHandle, (uiMetadata, tiemrId));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnTimerDiposeWindow(object[] args)
|
|
||||||
{
|
|
||||||
UIMetadata meta = args[0] as UIMetadata;
|
|
||||||
meta?.Dispose();
|
|
||||||
RemoveFromCache(meta.MetaInfo.RuntimeTypeHandle);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void RemoveFromCache(RuntimeTypeHandle typeHandle)
|
|
||||||
{
|
|
||||||
if (m_CacheWindow.TryGetValue(typeHandle, out var result))
|
|
||||||
{
|
|
||||||
m_CacheWindow.Remove(typeHandle);
|
|
||||||
result.Item1.InCache = false;
|
|
||||||
if (result.Item2 > 0)
|
|
||||||
{
|
|
||||||
_timerModule.RemoveTimer(result.Item2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: ae149a329f7523044a804e3fe6769cd6
|
|
||||||
timeCreated: 1724230178
|
|
||||||
@ -1,81 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
namespace AlicizaX.UI.Runtime
|
|
||||||
{
|
|
||||||
internal sealed partial class UIModule
|
|
||||||
{
|
|
||||||
public Camera UICamera { get; set; }
|
|
||||||
public Canvas UICanvas;
|
|
||||||
public Transform UICanvasRoot { get; set; }
|
|
||||||
public Transform UIRoot;
|
|
||||||
|
|
||||||
private const int UI_ROOT_OFFSET = 1000;
|
|
||||||
private const int LAYER_DISTANCE = 1000;
|
|
||||||
|
|
||||||
private const int LAYER_DEEP = 2000;
|
|
||||||
private const int WINDOW_DEEP = 100;
|
|
||||||
|
|
||||||
private readonly RectTransform[] m_AllWindowLayer = new RectTransform[(int)UILayer.All];
|
|
||||||
|
|
||||||
private RectTransform UICacheLayer;
|
|
||||||
private bool _isOrthographic;
|
|
||||||
|
|
||||||
public void Initlize(Transform root, bool isOrthographic)
|
|
||||||
{
|
|
||||||
UIRoot = root;
|
|
||||||
Object.DontDestroyOnLoad(root.gameObject);
|
|
||||||
|
|
||||||
UIRoot.transform.position = new Vector3(UI_ROOT_OFFSET, UI_ROOT_OFFSET, 0);
|
|
||||||
|
|
||||||
UICanvas = UIRoot.GetComponentInChildren<Canvas>();
|
|
||||||
UICamera = UICanvas.worldCamera;
|
|
||||||
UICanvasRoot = UICanvas.transform;
|
|
||||||
|
|
||||||
_isOrthographic = isOrthographic;
|
|
||||||
UICamera.orthographic = isOrthographic;
|
|
||||||
if (!isOrthographic)
|
|
||||||
{
|
|
||||||
UICamera.nearClipPlane = 10;
|
|
||||||
UICamera.farClipPlane = 1000;
|
|
||||||
}
|
|
||||||
|
|
||||||
const int len = (int)UILayer.All;
|
|
||||||
for (var i = len - 1; i >= 0; i--)
|
|
||||||
{
|
|
||||||
AddLayer(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
AddLayer((int)UILayer.All);
|
|
||||||
InitUIBlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AddLayer(int layer)
|
|
||||||
{
|
|
||||||
var layerObject = new GameObject($"Layer{layer}-{(UILayer)layer}");
|
|
||||||
var rect = layerObject.AddComponent<RectTransform>();
|
|
||||||
rect.SetParent(UICanvasRoot);
|
|
||||||
rect.localScale = Vector3.one;
|
|
||||||
rect.pivot = new Vector2(0.5f, 0.5f);
|
|
||||||
rect.anchorMax = Vector2.one;
|
|
||||||
rect.anchorMin = Vector2.zero;
|
|
||||||
rect.sizeDelta = Vector2.zero;
|
|
||||||
rect.localRotation = Quaternion.identity;
|
|
||||||
rect.localPosition = new Vector3(0, 0, layer * (_isOrthographic ? LAYER_DISTANCE : 0));
|
|
||||||
if (layer == (int)UILayer.All)
|
|
||||||
{
|
|
||||||
UICacheLayer = rect;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_AllWindowLayer[layer] = rect;
|
|
||||||
_openUI[layer] = new LayerData(16);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public RectTransform GetLayerRect(int layer)
|
|
||||||
{
|
|
||||||
return m_AllWindowLayer[layer];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: a857b714234e34545ac83be63c96147b
|
|
||||||
timeCreated: 1724154426
|
|
||||||
@ -1,167 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
using AlicizaX;
|
|
||||||
using Cysharp.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace AlicizaX.UI.Runtime
|
|
||||||
{
|
|
||||||
readonly struct LayerData
|
|
||||||
{
|
|
||||||
public readonly List<UIMetadata> OrderList; // 维护插入顺序
|
|
||||||
public readonly HashSet<RuntimeTypeHandle> HandleSet; // O(1)存在性检查
|
|
||||||
|
|
||||||
public LayerData(int initialCapacity)
|
|
||||||
{
|
|
||||||
OrderList = new List<UIMetadata>(initialCapacity);
|
|
||||||
HandleSet = new HashSet<RuntimeTypeHandle>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal sealed partial class UIModule
|
|
||||||
{
|
|
||||||
private readonly LayerData[] _openUI = new LayerData[(int)UILayer.All];
|
|
||||||
|
|
||||||
private async UniTask<UIBase> ShowUIImplAsync(UIMetadata meta, params object[] userDatas)
|
|
||||||
{
|
|
||||||
var metaInfo = GetOrCreateMeta(meta);
|
|
||||||
await UIHolderFactory.CreateUIResource(metaInfo, UICacheLayer);
|
|
||||||
return await FinalizeShow(metaInfo, userDatas);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async UniTask CloseUIImpl(UIMetadata meta, bool force)
|
|
||||||
{
|
|
||||||
if (meta.State == UIState.Uninitialized || meta.State == UIState.CreatedUI)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
await meta.View.InternalClose();
|
|
||||||
Pop(meta);
|
|
||||||
SortWindowVisible(meta.MetaInfo.UILayer);
|
|
||||||
SortWindowDepth(meta.MetaInfo.UILayer);
|
|
||||||
CacheWindow(meta, force);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private UIBase GetUIImpl(UIMetadata meta)
|
|
||||||
{
|
|
||||||
return meta.View;
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
private UIMetadata GetOrCreateMeta(UIMetadata meta)
|
|
||||||
{
|
|
||||||
if (meta.State == UIState.Uninitialized) meta.CreateUI();
|
|
||||||
return meta;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private async UniTask<UIBase> FinalizeShow(UIMetadata meta, object[] userDatas)
|
|
||||||
{
|
|
||||||
if (meta.InCache)
|
|
||||||
{
|
|
||||||
RemoveFromCache(meta.MetaInfo.RuntimeTypeHandle);
|
|
||||||
Push(meta);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
switch (meta.State)
|
|
||||||
{
|
|
||||||
case UIState.Loaded:
|
|
||||||
Push(meta);
|
|
||||||
break;
|
|
||||||
case UIState.Opened:
|
|
||||||
MoveToTop(meta);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
meta.View.RefreshParams(userDatas);
|
|
||||||
await UpdateVisualState(meta);
|
|
||||||
return meta.View;
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
private void Push(UIMetadata meta)
|
|
||||||
{
|
|
||||||
ref var layer = ref _openUI[meta.MetaInfo.UILayer];
|
|
||||||
if (layer.HandleSet.Add(meta.MetaInfo.RuntimeTypeHandle))
|
|
||||||
{
|
|
||||||
layer.OrderList.Add(meta);
|
|
||||||
UpdateLayerParent(meta);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
private void Pop(UIMetadata meta)
|
|
||||||
{
|
|
||||||
ref var layer = ref _openUI[meta.MetaInfo.UILayer];
|
|
||||||
if (layer.HandleSet.Remove(meta.MetaInfo.RuntimeTypeHandle))
|
|
||||||
{
|
|
||||||
layer.OrderList.Remove(meta);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
private void UpdateLayerParent(UIMetadata meta)
|
|
||||||
{
|
|
||||||
if (meta.View?.Holder)
|
|
||||||
{
|
|
||||||
var layerRect = GetLayerRect(meta.MetaInfo.UILayer);
|
|
||||||
meta.View.Holder.transform.SetParent(layerRect);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
private void MoveToTop(UIMetadata meta)
|
|
||||||
{
|
|
||||||
ref var layer = ref _openUI[meta.MetaInfo.UILayer];
|
|
||||||
int lastIdx = layer.OrderList.Count - 1;
|
|
||||||
int currentIdx = layer.OrderList.IndexOf(meta);
|
|
||||||
|
|
||||||
if (currentIdx != lastIdx && currentIdx >= 0)
|
|
||||||
{
|
|
||||||
layer.OrderList.RemoveAt(currentIdx);
|
|
||||||
layer.OrderList.Add(meta);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
private async UniTask UpdateVisualState(UIMetadata meta)
|
|
||||||
{
|
|
||||||
SortWindowVisible(meta.MetaInfo.UILayer);
|
|
||||||
SortWindowDepth(meta.MetaInfo.UILayer);
|
|
||||||
if (meta.State == UIState.Loaded)
|
|
||||||
{
|
|
||||||
await meta.View.InternalInitlized();
|
|
||||||
}
|
|
||||||
|
|
||||||
await meta.View.InternalOpen();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SortWindowVisible(int layer)
|
|
||||||
{
|
|
||||||
var list = _openUI[layer].OrderList;
|
|
||||||
bool shouldHide = false;
|
|
||||||
|
|
||||||
// 反向遍历避免GC分配
|
|
||||||
for (int i = list.Count - 1; i >= 0; i--)
|
|
||||||
{
|
|
||||||
var meta = list[i];
|
|
||||||
meta.View.Visible = !shouldHide;
|
|
||||||
shouldHide |= meta.MetaInfo.FullScreen && meta.State == UIState.Opened;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SortWindowDepth(int layer)
|
|
||||||
{
|
|
||||||
var list = _openUI[layer].OrderList;
|
|
||||||
int baseDepth = layer * LAYER_DEEP;
|
|
||||||
|
|
||||||
for (int i = 0; i < list.Count; i++)
|
|
||||||
{
|
|
||||||
list[i].View.Depth = baseDepth + i * WINDOW_DEEP;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 5374bef7b6c357f4ba05ae372ff262f6
|
|
||||||
timeCreated: 1724224258
|
|
||||||
@ -1,107 +0,0 @@
|
|||||||
using System;
|
|
||||||
using AlicizaX.Resource.Runtime;
|
|
||||||
using AlicizaX;
|
|
||||||
using AlicizaX.Timer.Runtime;
|
|
||||||
using Cysharp.Threading.Tasks;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
namespace AlicizaX.UI.Runtime
|
|
||||||
{
|
|
||||||
internal sealed partial class UIModule : IUIModule
|
|
||||||
{
|
|
||||||
public int Priority { get; }
|
|
||||||
|
|
||||||
private ITimerModule _timerModule;
|
|
||||||
|
|
||||||
void IModule.Dispose()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void IModuleUpdate.Update(float elapseSeconds, float realElapseSeconds)
|
|
||||||
{
|
|
||||||
// 遍历所有层级
|
|
||||||
for (int layerIndex = 0; layerIndex < _openUI.Length; layerIndex++)
|
|
||||||
{
|
|
||||||
var layer = _openUI[layerIndex];
|
|
||||||
int count = layer.OrderList.Count;
|
|
||||||
if (count == 0) continue; // 跳过空层级
|
|
||||||
for (int i = 0; i < count; i++)
|
|
||||||
{
|
|
||||||
if (layer.OrderList.Count != count)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
var window = layer.OrderList[i];
|
|
||||||
window.View.InternalUpdate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public UniTask<UIBase>? ShowUI(string type, params object[] userDatas)
|
|
||||||
{
|
|
||||||
if (UIMetaRegistry.TryGet(type, out var metaRegistry))
|
|
||||||
{
|
|
||||||
UIMetadata metadata = UIMetadataFactory.GetMetadata(metaRegistry.RuntimeTypeHandle);
|
|
||||||
return ShowUI(metadata, userDatas);
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public UniTask<UIBase> ShowUI<T>(params System.Object[] userDatas) where T : UIBase
|
|
||||||
{
|
|
||||||
return ShowUI(MetaTypeCache<T>.Metadata, userDatas);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async UniTask<T> ShowUIAsync<T>(params System.Object[] userDatas) where T : UIBase
|
|
||||||
{
|
|
||||||
return (T)await ShowUIAsync(MetaTypeCache<T>.Metadata, userDatas);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void CloseUI<T>(bool force = false) where T : UIBase
|
|
||||||
{
|
|
||||||
CloseUIImpl(MetaTypeCache<T>.Metadata, force).Forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
public T GetUI<T>() where T : UIBase
|
|
||||||
{
|
|
||||||
return (T)GetUI(MetaTypeCache<T>.Metadata);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private UniTask<UIBase> ShowUI(UIMetadata meta, params System.Object[] userDatas)
|
|
||||||
{
|
|
||||||
return ShowUIImplAsync(meta, userDatas);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async UniTask<UIBase> ShowUIAsync(UIMetadata meta, params System.Object[] userDatas)
|
|
||||||
{
|
|
||||||
return await ShowUIImplAsync(meta, userDatas);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void CloseUI(RuntimeTypeHandle handle, bool force = false)
|
|
||||||
{
|
|
||||||
var metadata = UIMetadataFactory.GetMetadata(handle);
|
|
||||||
if (metadata.State != UIState.Uninitialized && metadata.State != UIState.Destroying)
|
|
||||||
{
|
|
||||||
CloseUIImpl(metadata, force).Forget();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private UIBase GetUI(UIMetadata meta)
|
|
||||||
{
|
|
||||||
return (UIBase)GetUIImpl(meta);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void IUIModule.SetTimerManager(ITimerModule timerModule)
|
|
||||||
{
|
|
||||||
_timerModule = timerModule;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: ae16df1037186a64b922d60f431440ba
|
|
||||||
timeCreated: 1724154184
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: b963d3fe706c8a04cb734b28bac7f23a
|
|
||||||
timeCreated: 1724223096
|
|
||||||
@ -1,62 +0,0 @@
|
|||||||
using UnityEngine;
|
|
||||||
using UnityEngine.UI;
|
|
||||||
|
|
||||||
namespace AlicizaX.UI.Runtime
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 不可见的一个图,用来阻挡UI的投射。
|
|
||||||
/// </summary>
|
|
||||||
public class UIBlock : Graphic, ICanvasRaycastFilter
|
|
||||||
{
|
|
||||||
public override bool raycastTarget
|
|
||||||
{
|
|
||||||
get => true;
|
|
||||||
set { }
|
|
||||||
}
|
|
||||||
|
|
||||||
[System.Diagnostics.CodeAnalysis.SuppressMessage(
|
|
||||||
"StyleCop.CSharp.NamingRules",
|
|
||||||
"SA1300:ElementMustBeginWithUpperCaseLetter",
|
|
||||||
Justification = "Reviewed. Suppression is OK here.")]
|
|
||||||
public override Texture mainTexture
|
|
||||||
{
|
|
||||||
get { return null; }
|
|
||||||
}
|
|
||||||
|
|
||||||
[System.Diagnostics.CodeAnalysis.SuppressMessage(
|
|
||||||
"StyleCop.CSharp.NamingRules",
|
|
||||||
"SA1300:ElementMustBeginWithUpperCaseLetter",
|
|
||||||
Justification = "Reviewed. Suppression is OK here.")]
|
|
||||||
public override Material materialForRendering
|
|
||||||
{
|
|
||||||
get { return null; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsRaycastLocationValid(
|
|
||||||
Vector2 screenPoint, Camera eventCamera)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnPopulateMesh(VertexHelper vh)
|
|
||||||
{
|
|
||||||
vh.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void SetAllDirty()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void SetLayoutDirty()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void SetVerticesDirty()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void SetMaterialDirty()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,11 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: b95fd72d0c129af4fb87ef9802656ce1
|
|
||||||
MonoImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
serializedVersion: 2
|
|
||||||
defaultReferences: []
|
|
||||||
executionOrder: 0
|
|
||||||
icon: {instanceID: 0}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 1a64352099e341a0bedaf1a456d028a6
|
|
||||||
timeCreated: 1732264981
|
|
||||||
@ -1,124 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Buffers;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using AlicizaX;
|
|
||||||
using Cysharp.Threading.Tasks;
|
|
||||||
using UnityEngine;
|
|
||||||
using UnityEngine.Pool;
|
|
||||||
|
|
||||||
namespace AlicizaX.UI.Runtime
|
|
||||||
{
|
|
||||||
public abstract partial class UIBase
|
|
||||||
{
|
|
||||||
private readonly Dictionary<UIBase, UIMetadata> _children = new();
|
|
||||||
|
|
||||||
private void UpdateChildren()
|
|
||||||
{
|
|
||||||
var values = _children.Values;
|
|
||||||
foreach (var meta in values)
|
|
||||||
{
|
|
||||||
if (meta.View.State == UIState.Opened)
|
|
||||||
{
|
|
||||||
meta.View.InternalUpdate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async UniTask DestroyAllChildren()
|
|
||||||
{
|
|
||||||
var temp = ArrayPool<UIMetadata>.Shared.Rent(_children.Count);
|
|
||||||
try
|
|
||||||
{
|
|
||||||
int i = 0;
|
|
||||||
foreach (var kvp in _children)
|
|
||||||
{
|
|
||||||
temp[i++] = kvp.Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int j = 0; j < i; j++)
|
|
||||||
{
|
|
||||||
if (temp[j].View.Visible) await temp[j].View.InternalClose();
|
|
||||||
temp[j].Dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
ArrayPool<UIMetadata>.Shared.Return(temp);
|
|
||||||
}
|
|
||||||
|
|
||||||
_children.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ChildVisible(bool value)
|
|
||||||
{
|
|
||||||
foreach (var meta in _children.Values)
|
|
||||||
{
|
|
||||||
var view = meta.View;
|
|
||||||
if (view.State == UIState.Opened)
|
|
||||||
{
|
|
||||||
view.Visible = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal async UniTask<UIBase> CreateWidget(UIMetadata metadata, Transform parent, bool visible)
|
|
||||||
{
|
|
||||||
metadata.CreateUI();
|
|
||||||
await UIHolderFactory.CreateUIResource(metadata, parent, this);
|
|
||||||
await ProcessWidget(metadata, visible);
|
|
||||||
return (UIBase)metadata.View;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected async UniTask<UIBase> CreateWidget(string typeName, Transform parent, bool visible = true)
|
|
||||||
{
|
|
||||||
UIMetaRegistry.TryGet(typeName, out var metaRegistry);
|
|
||||||
UIMetadata metadata = UIMetadataFactory.GetMetadata(metaRegistry.RuntimeTypeHandle);
|
|
||||||
return await CreateWidget(metadata, parent, visible);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected async UniTask<T> CreateWidget<T>(Transform parent, bool visible = true) where T : UIBase
|
|
||||||
{
|
|
||||||
UIMetadata metadata = MetaTypeCache<T>.Metadata;
|
|
||||||
return (T)await CreateWidget(metadata, parent, visible);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected async UniTask<T> CreateWidget<T>(UIHolderObjectBase holder) where T : UIBase
|
|
||||||
{
|
|
||||||
UIMetadata metadata = MetaTypeCache<T>.Metadata;
|
|
||||||
metadata.CreateUI();
|
|
||||||
UIBase widget = (UIBase)metadata.View;
|
|
||||||
widget.BindUIHolder(holder, this);
|
|
||||||
await ProcessWidget(metadata, true);
|
|
||||||
return (T)widget;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async UniTask ProcessWidget(UIMetadata meta, bool visible)
|
|
||||||
{
|
|
||||||
AddWidget(meta);
|
|
||||||
await meta.View.InternalInitlized();
|
|
||||||
meta.View.Visible = visible;
|
|
||||||
if (meta.View.Visible)
|
|
||||||
{
|
|
||||||
await meta.View.InternalOpen();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AddWidget(UIMetadata meta)
|
|
||||||
{
|
|
||||||
if (!_children.TryAdd(meta.View, meta))
|
|
||||||
{
|
|
||||||
Log.Warning("Already has widget:{0}", meta.View);
|
|
||||||
meta.Dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public async UniTask RemoveWidget(UIBase widget)
|
|
||||||
{
|
|
||||||
if (_children.Remove(widget, out var meta))
|
|
||||||
{
|
|
||||||
await widget.InternalClose();
|
|
||||||
meta.Dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 5f25caf536134515b80acdc6709ad14d
|
|
||||||
timeCreated: 1739429626
|
|
||||||
@ -1,254 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using AlicizaX;
|
|
||||||
using Cysharp.Threading.Tasks;
|
|
||||||
using UnityEngine;
|
|
||||||
using UnityEngine.UI;
|
|
||||||
using Object = UnityEngine.Object;
|
|
||||||
|
|
||||||
namespace AlicizaX.UI.Runtime
|
|
||||||
{
|
|
||||||
public abstract partial class UIBase : IDisposable
|
|
||||||
{
|
|
||||||
protected UIBase()
|
|
||||||
{
|
|
||||||
_state = UIState.CreatedUI;
|
|
||||||
}
|
|
||||||
|
|
||||||
~UIBase() => Dispose(false);
|
|
||||||
private bool _disposed;
|
|
||||||
|
|
||||||
internal Canvas _canvas;
|
|
||||||
|
|
||||||
internal GraphicRaycaster _raycaster;
|
|
||||||
|
|
||||||
internal UIState _state = UIState.Uninitialized;
|
|
||||||
internal UIState State => _state;
|
|
||||||
|
|
||||||
|
|
||||||
private System.Object[] _userDatas;
|
|
||||||
protected System.Object UserData => _userDatas != null && _userDatas.Length >= 1 ? _userDatas[0] : null;
|
|
||||||
protected System.Object[] UserDatas => _userDatas;
|
|
||||||
|
|
||||||
private RuntimeTypeHandle _runtimeTypeHandle;
|
|
||||||
|
|
||||||
internal RuntimeTypeHandle RuntimeTypeHandler
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (_runtimeTypeHandle.Value == IntPtr.Zero)
|
|
||||||
{
|
|
||||||
_runtimeTypeHandle = GetType().TypeHandle;
|
|
||||||
}
|
|
||||||
|
|
||||||
return _runtimeTypeHandle;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual void OnInitialize()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual void OnDestroy()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual void OnOpen()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual void OnClose()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual void OnUpdate()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 如果重写当前方法 则同步OnInitialize不会调用
|
|
||||||
/// </summary>
|
|
||||||
protected virtual async UniTask OnInitializeAsync()
|
|
||||||
{
|
|
||||||
await UniTask.CompletedTask;
|
|
||||||
OnInitialize();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 如果重写当前方法 则同步OnOpen不会调用
|
|
||||||
/// </summary>
|
|
||||||
protected virtual async UniTask OnOpenAsync()
|
|
||||||
{
|
|
||||||
await UniTask.CompletedTask;
|
|
||||||
OnOpen();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 如果重写当前方法 则同步OnClose不会调用
|
|
||||||
/// </summary>
|
|
||||||
protected virtual async UniTask OnCloseAsync()
|
|
||||||
{
|
|
||||||
await UniTask.CompletedTask;
|
|
||||||
OnClose();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 事件在窗口销毁后会自动移除
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="proxy"></param>
|
|
||||||
protected virtual void OnRegisterEvent(EventListenerProxy proxy)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
Dispose(true);
|
|
||||||
GC.SuppressFinalize(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Dispose(bool disposing)
|
|
||||||
{
|
|
||||||
if (_disposed) return;
|
|
||||||
|
|
||||||
if (disposing)
|
|
||||||
{
|
|
||||||
// 托管资源释放
|
|
||||||
_canvas = null;
|
|
||||||
_raycaster = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
_userDatas = null;
|
|
||||||
|
|
||||||
// 非托管资源释放
|
|
||||||
if (Holder != null)
|
|
||||||
{
|
|
||||||
if (Application.isPlaying)
|
|
||||||
Object.Destroy(Holder.gameObject);
|
|
||||||
else
|
|
||||||
Object.DestroyImmediate(Holder.gameObject);
|
|
||||||
}
|
|
||||||
|
|
||||||
_disposed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal bool Visible
|
|
||||||
{
|
|
||||||
get => _canvas != null && _canvas.gameObject.layer == UIComponent.UIShowLayer;
|
|
||||||
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (_canvas != null)
|
|
||||||
{
|
|
||||||
int setLayer = value ? UIComponent.UIShowLayer : UIComponent.UIHideLayer;
|
|
||||||
if (_canvas.gameObject.layer == setLayer)
|
|
||||||
return;
|
|
||||||
|
|
||||||
_canvas.gameObject.layer = setLayer;
|
|
||||||
ChildVisible(value);
|
|
||||||
Interactable = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool Interactable
|
|
||||||
{
|
|
||||||
get => _raycaster.enabled && _raycaster != null;
|
|
||||||
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (_raycaster != null && _raycaster.enabled != value)
|
|
||||||
{
|
|
||||||
_raycaster.enabled = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 窗口深度值。
|
|
||||||
/// </summary>
|
|
||||||
internal int Depth
|
|
||||||
{
|
|
||||||
get => _canvas != null ? _canvas.sortingOrder : 0;
|
|
||||||
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (_canvas != null && _canvas.sortingOrder != value)
|
|
||||||
{
|
|
||||||
// 设置父类
|
|
||||||
_canvas.sortingOrder = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#region Event
|
|
||||||
|
|
||||||
private EventListenerProxy _eventListenerProxy;
|
|
||||||
|
|
||||||
private EventListenerProxy EventListenerProxy => _eventListenerProxy ??= MemoryPool.Acquire<EventListenerProxy>();
|
|
||||||
|
|
||||||
private void ReleaseEventListenerProxy()
|
|
||||||
{
|
|
||||||
if (!_eventListenerProxy.IsNull())
|
|
||||||
{
|
|
||||||
MemoryPool.Release(_eventListenerProxy);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region 管理器内部调用
|
|
||||||
|
|
||||||
internal UIHolderObjectBase Holder;
|
|
||||||
internal abstract Type UIHolderType { get; }
|
|
||||||
|
|
||||||
internal abstract void BindUIHolder(UIHolderObjectBase holder,UIBase owner);
|
|
||||||
|
|
||||||
internal async UniTask InternalInitlized()
|
|
||||||
{
|
|
||||||
_state = UIState.Initialized;
|
|
||||||
await OnInitializeAsync();
|
|
||||||
OnRegisterEvent(EventListenerProxy);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal async UniTask InternalOpen()
|
|
||||||
{
|
|
||||||
_state = UIState.Opened;
|
|
||||||
Visible = true;
|
|
||||||
await OnOpenAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
internal async UniTask InternalClose()
|
|
||||||
{
|
|
||||||
if (_state == UIState.Opened)
|
|
||||||
{
|
|
||||||
await OnCloseAsync();
|
|
||||||
_state = UIState.Closed;
|
|
||||||
Visible = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void InternalUpdate()
|
|
||||||
{
|
|
||||||
if (_state != UIState.Opened) return;
|
|
||||||
OnUpdate();
|
|
||||||
UpdateChildren();
|
|
||||||
}
|
|
||||||
|
|
||||||
internal async UniTask InternalDestroy()
|
|
||||||
{
|
|
||||||
_state = UIState.Destroying;
|
|
||||||
await DestroyAllChildren();
|
|
||||||
OnDestroy();
|
|
||||||
ReleaseEventListenerProxy();
|
|
||||||
Dispose();
|
|
||||||
_state = UIState.Destroyed;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void RefreshParams(params System.Object[] userDatas)
|
|
||||||
{
|
|
||||||
this._userDatas = userDatas;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 478527286cb74364a452b02eee2059e6
|
|
||||||
timeCreated: 1739272697
|
|
||||||
@ -1,80 +0,0 @@
|
|||||||
using Sirenix.OdinInspector;
|
|
||||||
using System;
|
|
||||||
using Cysharp.Threading.Tasks;
|
|
||||||
using UnityEngine;
|
|
||||||
using UnityEngine.UI;
|
|
||||||
|
|
||||||
namespace AlicizaX.UI.Runtime
|
|
||||||
{
|
|
||||||
[DisallowMultipleComponent]
|
|
||||||
[HideMonoScript]
|
|
||||||
public abstract class UIHolderObjectBase : UnityEngine.MonoBehaviour
|
|
||||||
{
|
|
||||||
#if UNITY_EDITOR
|
|
||||||
private void SetAnimtionFlow()
|
|
||||||
{
|
|
||||||
// 编辑器模式下自动重置状态
|
|
||||||
AnimationFlow = GetComponent<AnimationFlow.Runtime.AnimationFlow>();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
public async UniTask PlayAnimtion(string name)
|
|
||||||
{
|
|
||||||
await AnimationFlow.PlayAsync(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private GameObject _target;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// UI实例资源对象。
|
|
||||||
/// </summary>
|
|
||||||
public GameObject Target => _target ??= gameObject;
|
|
||||||
|
|
||||||
|
|
||||||
private RectTransform _rectTransform;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 窗口矩阵位置组件。
|
|
||||||
/// </summary>
|
|
||||||
public RectTransform RectTransform => _rectTransform ??= _target.transform as RectTransform;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 可见性
|
|
||||||
/// </summary>
|
|
||||||
public bool Visible
|
|
||||||
{
|
|
||||||
get => Target.activeSelf;
|
|
||||||
|
|
||||||
internal set { _target.SetActive(value); }
|
|
||||||
}
|
|
||||||
|
|
||||||
#if UNITY_EDITOR
|
|
||||||
[InlineButton("SetAnimtionFlow")]
|
|
||||||
#endif
|
|
||||||
[SerializeField]
|
|
||||||
[HideLabel]
|
|
||||||
private AnimationFlow.Runtime.AnimationFlow AnimationFlow;
|
|
||||||
|
|
||||||
private void Awake()
|
|
||||||
{
|
|
||||||
_target = gameObject;
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool IsAlive = true;
|
|
||||||
|
|
||||||
public static implicit operator bool(UIHolderObjectBase exists)
|
|
||||||
{
|
|
||||||
// 先检查Unity对象是否被销毁
|
|
||||||
if (exists == null) return false;
|
|
||||||
// 再返回自定义的生命状态
|
|
||||||
return exists.IsAlive;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnDestroy()
|
|
||||||
{
|
|
||||||
IsAlive = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: f8df68ea1a364571a8c7b9ae2e2cb29b
|
|
||||||
timeCreated: 1732171853
|
|
||||||
@ -1,14 +0,0 @@
|
|||||||
namespace AlicizaX.UI.Runtime
|
|
||||||
{
|
|
||||||
public enum UIState:byte
|
|
||||||
{
|
|
||||||
Uninitialized,
|
|
||||||
CreatedUI,
|
|
||||||
Loaded,
|
|
||||||
Initialized,
|
|
||||||
Opened,
|
|
||||||
Closed,
|
|
||||||
Destroying,
|
|
||||||
Destroyed,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: cadb58b2c31543a0aa9db1e995ab6dfe
|
|
||||||
timeCreated: 1739450978
|
|
||||||
@ -1,142 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using AlicizaX;
|
|
||||||
using Cysharp.Threading.Tasks;
|
|
||||||
using UnityEngine;
|
|
||||||
using UnityEngine.UI;
|
|
||||||
|
|
||||||
namespace AlicizaX.UI.Runtime
|
|
||||||
{
|
|
||||||
public abstract class UITabWindow<T> : UIBase where T : UIHolderObjectBase
|
|
||||||
{
|
|
||||||
// 当前激活的Tab页
|
|
||||||
private UIWidget _activeTab;
|
|
||||||
|
|
||||||
// 类型顺序索引(根据初始化顺序)
|
|
||||||
private readonly List<RuntimeTypeHandle> _typeOrder = new();
|
|
||||||
|
|
||||||
// 页面缓存字典(类型 - 父节点)
|
|
||||||
private readonly Dictionary<RuntimeTypeHandle, Transform> _tabCache = new();
|
|
||||||
|
|
||||||
// 已加载的Tab实例缓存
|
|
||||||
private readonly Dictionary<RuntimeTypeHandle, UIWidget> _loadedTabs = new();
|
|
||||||
|
|
||||||
// 加载状态字典
|
|
||||||
private readonly Dictionary<RuntimeTypeHandle, bool> _loadingFlags = new();
|
|
||||||
|
|
||||||
protected T baseui => (T)Holder;
|
|
||||||
|
|
||||||
internal sealed override Type UIHolderType => typeof(T);
|
|
||||||
|
|
||||||
protected void CloseSelf(bool forceClose = false)
|
|
||||||
{
|
|
||||||
ModuleSystem.GetModule<IUIModule>().CloseUI(RuntimeTypeHandler, forceClose);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal sealed override void BindUIHolder(UIHolderObjectBase holder, UIBase owner)
|
|
||||||
{
|
|
||||||
if (_state != UIState.CreatedUI)
|
|
||||||
throw new InvalidOperationException("UI already Created");
|
|
||||||
|
|
||||||
Holder = holder;
|
|
||||||
_canvas = Holder.transform.GetComponent<Canvas>();
|
|
||||||
_canvas.overrideSorting = true;
|
|
||||||
_raycaster = Holder.transform.GetComponent<GraphicRaycaster>();
|
|
||||||
Holder.RectTransform.localPosition = Vector3.zero;
|
|
||||||
Holder.RectTransform.pivot = new Vector2(0.5f, 0.5f);
|
|
||||||
Holder.RectTransform.anchorMin = Vector2.zero;
|
|
||||||
Holder.RectTransform.anchorMax = Vector2.one;
|
|
||||||
Holder.RectTransform.offsetMin = Vector2.zero;
|
|
||||||
Holder.RectTransform.offsetMax = Vector2.zero;
|
|
||||||
Holder.RectTransform.localScale = Vector3.one;
|
|
||||||
_state = UIState.Loaded;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 初始化方法(泛型版本)
|
|
||||||
protected void InitTabVirtuallyView<TTab>(Transform parent = null) where TTab : UIWidget
|
|
||||||
{
|
|
||||||
var metadata = MetaTypeCache<TTab>.Metadata;
|
|
||||||
CacheTabMetadata(metadata, parent);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 初始化方法(类型名版本)
|
|
||||||
protected void InitTabVirtuallyView(string typeName, Transform parent = null)
|
|
||||||
{
|
|
||||||
if (UIMetaRegistry.TryGet(typeName, out var metaRegistry))
|
|
||||||
{
|
|
||||||
var metadata = UIMetadataFactory.GetMetadata(metaRegistry.RuntimeTypeHandle);
|
|
||||||
CacheTabMetadata(metadata, parent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void CacheTabMetadata(UIMetadata metadata, Transform parent)
|
|
||||||
{
|
|
||||||
var typeHandle = metadata.MetaInfo.RuntimeTypeHandle;
|
|
||||||
|
|
||||||
if (!_tabCache.ContainsKey(typeHandle))
|
|
||||||
{
|
|
||||||
_typeOrder.Add(typeHandle);
|
|
||||||
_tabCache[typeHandle] = parent ?? baseui.RectTransform;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SwitchTab(int index, params System.Object[] userDatas)
|
|
||||||
{
|
|
||||||
if (!ValidateIndex(index)) return;
|
|
||||||
|
|
||||||
var typeHandle = _typeOrder[index];
|
|
||||||
if (_loadingFlags.TryGetValue(typeHandle, out var isLoading) && isLoading) return;
|
|
||||||
|
|
||||||
if (_loadedTabs.TryGetValue(typeHandle, out var loadedTab))
|
|
||||||
{
|
|
||||||
SwitchToLoadedTab(loadedTab, userDatas);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
StartAsyncLoading(typeHandle, userDatas).Forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
private async UniTaskVoid StartAsyncLoading(RuntimeTypeHandle typeHandle, params System.Object[] userDatas)
|
|
||||||
{
|
|
||||||
_loadingFlags[typeHandle] = true;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var metadata = UIMetadataFactory.GetMetadata(typeHandle);
|
|
||||||
var parent = _tabCache[typeHandle];
|
|
||||||
|
|
||||||
var widget = await CreateWidget(metadata, parent, false);
|
|
||||||
if (widget is not UIWidget tabWidget) return;
|
|
||||||
|
|
||||||
_loadedTabs[typeHandle] = tabWidget;
|
|
||||||
SwitchToLoadedTab(tabWidget, userDatas);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
Debug.LogError($"Tab load failed: {e}");
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
_loadingFlags.Remove(typeHandle);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SwitchToLoadedTab(UIWidget targetTab, params System.Object[] userDatas)
|
|
||||||
{
|
|
||||||
if (_activeTab == targetTab) return;
|
|
||||||
|
|
||||||
_activeTab?.Close();
|
|
||||||
_activeTab = targetTab;
|
|
||||||
targetTab.Open(userDatas);
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool ValidateIndex(int index)
|
|
||||||
{
|
|
||||||
if (index >= 0 && index < _typeOrder.Count) return true;
|
|
||||||
|
|
||||||
Debug.LogError($"Invalid tab index: {index}");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 8e10ab6cf87043638060ea5f933f6d80
|
|
||||||
timeCreated: 1744200054
|
|
||||||
@ -1,48 +0,0 @@
|
|||||||
using System;
|
|
||||||
using Cysharp.Threading.Tasks;
|
|
||||||
using UnityEngine;
|
|
||||||
using UnityEngine.UI;
|
|
||||||
|
|
||||||
namespace AlicizaX.UI.Runtime
|
|
||||||
{
|
|
||||||
public abstract class UIWidget : UIBase
|
|
||||||
{
|
|
||||||
internal UIBase _parent;
|
|
||||||
internal UIBase Parent => _parent;
|
|
||||||
|
|
||||||
public void Open(params System.Object[] userDatas)
|
|
||||||
{
|
|
||||||
RefreshParams(userDatas);
|
|
||||||
InternalOpen().Forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Close()
|
|
||||||
{
|
|
||||||
InternalClose().Forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Destroy()
|
|
||||||
{
|
|
||||||
Parent.RemoveWidget(this).Forget();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract class UIWidget<T> : UIWidget where T : UIHolderObjectBase
|
|
||||||
{
|
|
||||||
protected T baseui => (T)Holder;
|
|
||||||
internal sealed override Type UIHolderType => typeof(T);
|
|
||||||
|
|
||||||
internal sealed override void BindUIHolder(UIHolderObjectBase holder, UIBase owner)
|
|
||||||
{
|
|
||||||
if (_state != UIState.CreatedUI)
|
|
||||||
throw new InvalidOperationException("UI already Created");
|
|
||||||
|
|
||||||
Holder = holder;
|
|
||||||
_parent = owner;
|
|
||||||
_canvas = Holder.transform.GetComponent<Canvas>();
|
|
||||||
_raycaster = Holder.transform.GetComponent<GraphicRaycaster>();
|
|
||||||
Depth = owner.Depth + 5;
|
|
||||||
_state = UIState.Loaded;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: ed07f96c90414e28bb7ed820e88157ca
|
|
||||||
timeCreated: 1732240802
|
|
||||||
@ -1,38 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Reflection;
|
|
||||||
using AlicizaX;
|
|
||||||
using UnityEngine;
|
|
||||||
using UnityEngine.UI;
|
|
||||||
|
|
||||||
namespace AlicizaX.UI.Runtime
|
|
||||||
{
|
|
||||||
public abstract class UIWindow<T> : UIBase where T : UIHolderObjectBase
|
|
||||||
{
|
|
||||||
protected T baseui => (T)Holder;
|
|
||||||
|
|
||||||
internal sealed override Type UIHolderType => typeof(T);
|
|
||||||
|
|
||||||
protected void CloseSelf(bool forceClose = false)
|
|
||||||
{
|
|
||||||
ModuleSystem.GetModule<IUIModule>().CloseUI(RuntimeTypeHandler, forceClose);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal sealed override void BindUIHolder(UIHolderObjectBase holder, UIBase owner)
|
|
||||||
{
|
|
||||||
if (_state != UIState.CreatedUI)
|
|
||||||
throw new InvalidOperationException("UI already Created");
|
|
||||||
Holder = holder;
|
|
||||||
_canvas = Holder.transform.GetComponent<Canvas>();
|
|
||||||
_canvas.overrideSorting = true;
|
|
||||||
_raycaster = Holder.transform.GetComponent<GraphicRaycaster>();
|
|
||||||
Holder.RectTransform.localPosition = Vector3.zero;
|
|
||||||
Holder.RectTransform.pivot = new Vector2(0.5f, 0.5f);
|
|
||||||
Holder.RectTransform.anchorMin = Vector2.zero;
|
|
||||||
Holder.RectTransform.anchorMax = Vector2.one;
|
|
||||||
Holder.RectTransform.offsetMin = Vector2.zero;
|
|
||||||
Holder.RectTransform.offsetMax = Vector2.zero;
|
|
||||||
Holder.RectTransform.localScale = Vector3.one;
|
|
||||||
_state = UIState.Loaded;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 43a865d7e0cd461aa06c458815dce483
|
|
||||||
timeCreated: 1732172584
|
|
||||||
@ -1,112 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq.Expressions;
|
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
using AlicizaX.Resource.Runtime;
|
|
||||||
using AlicizaX;
|
|
||||||
using AlicizaX.Timer.Runtime;
|
|
||||||
using Cysharp.Threading.Tasks;
|
|
||||||
using UnityEngine;
|
|
||||||
using UnityEngine.UI;
|
|
||||||
using Object = UnityEngine.Object;
|
|
||||||
|
|
||||||
namespace AlicizaX.UI.Runtime
|
|
||||||
{
|
|
||||||
[DisallowMultipleComponent]
|
|
||||||
[AddComponentMenu("Game Framework/UI")]
|
|
||||||
[UnityEngine.Scripting.Preserve]
|
|
||||||
public sealed partial class UIComponent : MonoBehaviour
|
|
||||||
{
|
|
||||||
[SerializeField] private GameObject uiRoot = null;
|
|
||||||
[SerializeField] private bool _isOrthographic = true;
|
|
||||||
private Transform _instanceRoot = null;
|
|
||||||
|
|
||||||
private IUIModule _uiModule;
|
|
||||||
|
|
||||||
public const int UIHideLayer = 2; // Ignore Raycast
|
|
||||||
public const int UIShowLayer = 5; // UI
|
|
||||||
|
|
||||||
|
|
||||||
private void Awake()
|
|
||||||
{
|
|
||||||
_uiModule = ModuleSystem.RegisterModule<IUIModule,UIModule>();
|
|
||||||
if (uiRoot == null)
|
|
||||||
{
|
|
||||||
throw new GameFrameworkException("UIRoot Prefab is invalid.");
|
|
||||||
}
|
|
||||||
GameObject obj = Instantiate(uiRoot, Vector3.zero, Quaternion.identity);
|
|
||||||
obj.name = "------UI Root------";
|
|
||||||
_instanceRoot = obj.transform;
|
|
||||||
Object.DontDestroyOnLoad(_instanceRoot);
|
|
||||||
_uiModule.Initlize(_instanceRoot,_isOrthographic);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Start()
|
|
||||||
{
|
|
||||||
_uiModule.SetTimerManager(ModuleSystem.GetModule<ITimerModule>());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#region 设置安全区域
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 设置屏幕安全区域(异形屏支持)。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="safeRect">安全区域</param>
|
|
||||||
public void ApplyScreenSafeRect(Rect safeRect)
|
|
||||||
{
|
|
||||||
CanvasScaler scaler = _uiModule.UICanvasRoot.GetComponent<CanvasScaler>();
|
|
||||||
if (scaler == null)
|
|
||||||
{
|
|
||||||
Log.Error($"Not found {nameof(CanvasScaler)} !");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert safe area rectangle from absolute pixels to UGUI coordinates
|
|
||||||
float rateX = scaler.referenceResolution.x / Screen.width;
|
|
||||||
float rateY = scaler.referenceResolution.y / Screen.height;
|
|
||||||
float posX = (int)(safeRect.position.x * rateX);
|
|
||||||
float posY = (int)(safeRect.position.y * rateY);
|
|
||||||
float width = (int)(safeRect.size.x * rateX);
|
|
||||||
float height = (int)(safeRect.size.y * rateY);
|
|
||||||
|
|
||||||
float offsetMaxX = scaler.referenceResolution.x - width - posX;
|
|
||||||
float offsetMaxY = scaler.referenceResolution.y - height - posY;
|
|
||||||
|
|
||||||
// 注意:安全区坐标系的原点为左下角
|
|
||||||
var rectTrans = _uiModule.UICanvasRoot.transform as RectTransform;
|
|
||||||
if (rectTrans != null)
|
|
||||||
{
|
|
||||||
rectTrans.offsetMin = new Vector2(posX, posY); //锚框状态下的屏幕左下角偏移向量
|
|
||||||
rectTrans.offsetMax = new Vector2(-offsetMaxX, -offsetMaxY); //锚框状态下的屏幕右上角偏移向量
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 模拟IPhoneX异形屏
|
|
||||||
/// </summary>
|
|
||||||
public void SimulateIPhoneXNotchScreen()
|
|
||||||
{
|
|
||||||
Rect rect;
|
|
||||||
if (Screen.height > Screen.width)
|
|
||||||
{
|
|
||||||
// 竖屏Portrait
|
|
||||||
float deviceWidth = 1125;
|
|
||||||
float deviceHeight = 2436;
|
|
||||||
rect = new Rect(0f / deviceWidth, 102f / deviceHeight, 1125f / deviceWidth, 2202f / deviceHeight);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// 横屏Landscape
|
|
||||||
float deviceWidth = 2436;
|
|
||||||
float deviceHeight = 1125;
|
|
||||||
rect = new Rect(132f / deviceWidth, 63f / deviceHeight, 2172f / deviceWidth, 1062f / deviceHeight);
|
|
||||||
}
|
|
||||||
|
|
||||||
Rect safeArea = new Rect(Screen.width * rect.x, Screen.height * rect.y, Screen.width * rect.width, Screen.height * rect.height);
|
|
||||||
ApplyScreenSafeRect(safeArea);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 028204b1d2277bd4782816ee91aeed81
|
|
||||||
timeCreated: 1724156799
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
<linker>
|
|
||||||
<assembly fullname="AlicizaX.UI.Runtime" preserve="all" />
|
|
||||||
</linker>
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: cb214b5e4d2dd094b95d111669559268
|
|
||||||
timeCreated: 1737098208
|
|
||||||
@ -1,20 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "com.alicizax.unity.ui",
|
|
||||||
"displayName": "Aliciza X UI",
|
|
||||||
"category": "Aliciza X",
|
|
||||||
"description": "Aliciza X UI Component",
|
|
||||||
"version": "1.0.1",
|
|
||||||
"unity": "2025.1",
|
|
||||||
"keywords": [
|
|
||||||
"Aliciza X"
|
|
||||||
],
|
|
||||||
"repository": {
|
|
||||||
"name": "com.alicizax.unity",
|
|
||||||
"url": "http://101.34.252.46:3000/AlicizaX/",
|
|
||||||
"type": "git"
|
|
||||||
},
|
|
||||||
"author": {
|
|
||||||
"name": "Yuliuren",
|
|
||||||
"email": "yuliuren00@gmail.com"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,7 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: f80730b3963bc8f4abaa5c35c5d3a64b
|
|
||||||
PackageManifestImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
Loading…
Reference in New Issue
Block a user