diff --git a/EintooAR/.gitignore b/EintooAR/.gitignore new file mode 100644 index 00000000..739f2470 --- /dev/null +++ b/EintooAR/.gitignore @@ -0,0 +1,98 @@ +# UnityProject + +/[Ll]ibrary/ +/[Tt]emp/ +/[Oo]bj/ +/[Bb]uild/ +/[Bb]uilds/ +/[Ll]ogs/ +/[Mm]emoryCaptures/ +/EditorBuild/ +/[Aa]ssets/StreamingAssets +/[Aa]ssets/StreamingAssets.meta +/BuildBundleInfo/ +/[AR]FoundationRemoteCompanionApp + +# Asset meta data should only be ignored when the corresponding asset is also ignored +!/[Aa]ssets/**/*.meta + +# Uncomment this line if you wish to ignore the asset store tools plugin +# /[Aa]ssets/AssetStoreTools* + +# Autogenerated Jetbrains Rider plugin +[Aa]ssets/Plugins/Editor/JetBrains* + +# Visual Studio cache directory +.vs/ + +# Gradle cache directory +.gradle/ + +# Autogenerated VS/MD/Consulo solution and project files +ExportedObj/ +.consulo/ +*.csproj +*.unityproj +*.sln +*.suo +*.tmp +*.user +*.userprefs +*.pidb +*.booproj +*.svd +*.pdb +*.mdb +*.opendb +*.VC.db + +# Unity3D generated meta files +*.pidb.meta +*.pdb.meta +*.mdb.meta + +# Unity3D generated file on crash reports +sysinfo.txt + +# Builds +*.apk + +# Crashlytics generated file +crashlytics-build.properties + +#HybirdCLR(HuaTuo) +/HybirdCLRData/ +[Hh]ybridCLRData/ +[Aa]ssets/HybridCLRGenerate/ +[Aa]ssets/HybridCLRGenerate.meta + +#AATemp +[Aa]ssets/AATemp/ +[Aa]ssets/AATemp.meta + +# Custom AATest +[Aa]ssets/AATest/ +[Aa]ssets/AATest.meta + +#Bundles +Bundles/ + +#Sandbox +Sandbox/ + +#MAC +.DS_Store + +#Rider +.idea/ + +#Odin Inspector +# [Aa]ssets/Plugins/Sirenix/ +# [Aa]ssets/Plugins/Sirenix.meta + +#YooAssets +package/ +yoo/ +[Aa]ssets/TEngine/AssetSetting/Resources/BuiltinFileManifest.asset +[Aa]ssets/TEngine/AssetSetting/Resources/BuiltinFileManifest.asset.meta +ARFoundationRemoteInstaller diff --git a/EintooAR/.vsconfig b/EintooAR/.vsconfig new file mode 100644 index 00000000..d70cd98b --- /dev/null +++ b/EintooAR/.vsconfig @@ -0,0 +1,6 @@ +{ + "version": "1.0", + "components": [ + "Microsoft.VisualStudio.Workload.ManagedGame" + ] +} diff --git a/EintooAR/Packages/GAS/CHANGELOG.md b/EintooAR/Packages/GAS/CHANGELOG.md new file mode 100644 index 00000000..957a293a --- /dev/null +++ b/EintooAR/Packages/GAS/CHANGELOG.md @@ -0,0 +1,239 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [1.1.8] - 2024-07-30 + +进行了一系列的优化。(From: BCC @kenkinky) + +### Changed + +- 进行了一系列的优化 + +## [1.1.6] - 2024-06-26 + +修复了AbilitySpec中CheckCost时,modifier为减法时的计算错误;追加了Attribute的钳制功能。 + +### Changed + +- 追加了Attribute的钳制功能(From: BCC @kenkinky) + +### Fixed + +- 修复了AbilitySpec中CheckCost时,modifier为减法时的计算错误。 + + +## [1.1.6] - 2024-06-26 + +修复了由于优化GE创建流程时导致的Granted Ability生成错误;优化了period的边界问题 + +### Changed + +- 优化了period的边界问题(From: BCC @kenkinky) + +### Fixed + +- 修复了由于优化GE创建流程时导致的Granted Ability生成错误。 + + +## [1.1.5] - 2024-06-19 + +修复了AttrBasedMMC的快照读取错误;Modifier新增了减法,除法操作类型。 + +### Changed + +- Modifier新增了减法,除法操作类型。(From: BCC @kenkinky) + +### Fixed + +- 修复了AttrBasedMMC的快照读取错误。 + + +## [1.1.4] - 2024-06-14 + +重新整理了ASC的ApplyGameplayEffect方法的逻辑,现在GE的Tag相关判断是在实例化之后。允许用户在GameplayEffectSpec生效前对GE进行修改和操作。 + +### Changed + +- 重新整理了ASC的ApplyGameplayEffectTo(GameplayEffect gameplayEffect, AbilitySystemComponent target)方法的逻辑 +- ASC新增:ApplyGameplayEffectTo(GameplayEffectSpec gameplayEffectSpec, AbilitySystemComponent target) 和 + ApplyGameplayEffectToSelf(GameplayEffectSpec gameplayEffectSpec) + +## [1.1.3] - 2024-06-13 + +添加了带level形参的ApplyGE方法。 + +### Changed + +- 添加了带level形参的ApplyGE方法。 + + +## [1.1.2] - 2024-06-12 + +修复了部分bug。编辑器界面部分优化 + +### Changed + +- 编辑器界面部分优化(From: BCC @kenkinky) + +### Fixed + +- 修复了时间轴能力的durational cue重复调用OnRemove()的错误 +- 修复了时间轴编辑器的TargetCatcher的Inspector不更新的错误 + + +## [1.1.1] - 2024-05-31 + +补充了Stacking相关功能。 + +### Changed + +- 添加Stack相关MMC +- 补充stack刷新计算current value逻辑 +- 添加stack count变化监听事件 + +### Fixed + +- 修复了Attribute Aggregator的事件注册逻辑错误。 + +## [1.1.0] - 2024-05-30 + +补充了Granted Ability和GameplayEffect Stacking两个功能;优化了部分GC;优化了编辑器界面操作等;修复了部分bug。 + +### Changed + +- 补充了Granted Ability,详情可见README文档的2.8.c +- 补充了GameplayEffect Stacking,详情可见README文档的2.7中Stacking部分 +- 优化了部分GC。(From: BCC @kenkinky) +- 优化了部分执行逻辑,增强了代码可读性。 + +### Fixed + +- 修复了部分逻辑bug。(From: BCC @kenkinky) + +## [1.0.9] - 2024-04-25 + +优化type查找,优化GAS的项目级配置文件管理。 + +### Changed + +- 新增TimelineAbilityT, 方便继承和扩展TimelineAbility.(From: BCC @kenkinky) + +### Fixed + +- 修正TryAddDynamicAddedTag添加不同类型Source时类型转换失败异常(From: BCC @kenkinky) +- 修复了Setting中生成配置目录后,未调用AssetDatabase.Refresh()导致配置文件目录未及时更新的问题。 +## [1.0.8] - 2024-04-23 + +优化了部分GC。 + +### Fixed + +- AttributeSetContainer的TryGetAttributeSet方法中,Type.Name存在GC。 + - 新增了预缓存接口:GasCache.CacheAttributeSetName。 + - 使用方法:在GAS初始化时,调用GasCache.CacheAttributeSetName(GAttrSetLib.TypeToName); +- GameplayTagAggregator的Tag判断相关方法存在GC。GC来源是LINQ表达式的过程匿名方法产生的GC。已经把LINQ表达式改成了普通循环做法。 +- 新增了Pool工具类,优化了部分GC。(From: BCC @kenkinky) + +## [1.0.7] - 2024-04-17 + +修复全局配置保存失败问题;修复Editor代码不该编译问题 + +### Fixed + +- 修复全局配置保存失败问题,Tag,Attribute,AttributeSet,Setting的配置文件保存不该使用AssetDataBase。 +- 修正无法打包编译异常 #11 (From: BCC @kenkinky) + +## [1.0.6] - 2024-04-16 + +优化type查找,优化GAS的项目级配置文件管理。 + +### Changed + +- 修改了Tag,Attribute,AttributeSet,Setting的配置文件路径,调整至ProjectSettings,并且为单例配置文件。 +- 优化了TypeUtil,Editor环境下类型查找范围改为全程序集。 + +### Fixed + +- 修复一个严重bug: 修复AttributeBasedModCalculation不能正确保存的问题, 还有一些小优化.(From: BCC @kenkinky) + +## [1.0.5] - 2024-04-12 + +修复了部分bug;优化编辑器操作。 + +### Added + +- 优化编辑器操作。(From: BCC @kenkinky) + +### Fixed + +- 修复了TryActivateAbility的返回值逻辑错误。 + + +## [1.0.4] - 2024-04-11 + +修复了部分bug;测试通过了推导属性设计;优化了GE容器的管理,增强代码可读性。 + +### Added + +- 添加了GAS内部的子Event系统,为方便之后用上事件系统做准备。 + +### Fixed + +- 推导属性的实时更新错误。补上了AttributeBasedMMC的Track类修改器属性变化监听。 +- 修复GASHost销毁时的错误逻辑,Host的静态单例改为饿汉式,同步GAS的初始化只会执行一次。 + +### Changed + +- 优化GameplayEffectContainer结构,现在只维护一个GameplayEffect列表 + +### Removed + +- 移除DerivedAttribute和MetaAttribute脚本,弃用。这两个属性式设计方式,而不是实际存在的类。 + +## [1.0.3] - 2024-04-09 + +删除SetByCallerModCalculation,弃用。 + +### Removed + +- 删除SetByCallerModCalculation,弃用。 + +## [1.0.2] - 2024-04-08 + +优化Editor使用体验(From: BCC @kenkinky) + +### Changed + +- 优化Editor使用体验(From: BCC @kenkinky) + + +## [1.0.1] - 2024-03-29 + +删除Instant类型GameplayCue的Apply Target参数。 + +### Removed + +- Instant类型GameplayCue的Apply Target弃用。 + +## [1.0.0] - 2024-03-13 + +EX-GAS 1.0.0 发布 + +### Added + + +### Fixed + +- none + +### Changed + +- none + +### Removed + +- none \ No newline at end of file diff --git a/EintooAR/Packages/GAS/CHANGELOG.md.meta b/EintooAR/Packages/GAS/CHANGELOG.md.meta new file mode 100644 index 00000000..59268e95 --- /dev/null +++ b/EintooAR/Packages/GAS/CHANGELOG.md.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 34ae97a0d741c5844a4fac12ff8e1c45 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/EintooAR/Packages/GAS/Editor.meta b/EintooAR/Packages/GAS/Editor.meta new file mode 100644 index 00000000..f160b877 --- /dev/null +++ b/EintooAR/Packages/GAS/Editor.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: ceb70b71a95f4810bb22c72560de1755 +timeCreated: 1701928918 \ No newline at end of file diff --git a/EintooAR/Packages/GAS/Editor/Ability.meta b/EintooAR/Packages/GAS/Editor/Ability.meta new file mode 100644 index 00000000..b22e0f24 --- /dev/null +++ b/EintooAR/Packages/GAS/Editor/Ability.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 916ae4e58ce74ba2b0686ddc372419d9 +timeCreated: 1703772158 \ No newline at end of file diff --git a/EintooAR/Packages/GAS/Editor/Ability/AbilityCollectionGenerator.cs b/EintooAR/Packages/GAS/Editor/Ability/AbilityCollectionGenerator.cs new file mode 100644 index 00000000..be74ab81 --- /dev/null +++ b/EintooAR/Packages/GAS/Editor/Ability/AbilityCollectionGenerator.cs @@ -0,0 +1,135 @@ +using System; +using System.IO; +using System.Linq; +using GAS.Runtime; +using UnityEditor; +using UnityEngine; + +namespace GAS.Editor +{ + public class AbilityCollectionGenerator + { + public static void Gen() + { + string pathWithoutAssets = Application.dataPath.Substring(0, Application.dataPath.Length - 6); + var filePath = + $"{pathWithoutAssets}/{GASSettingAsset.CodeGenPath}/{GasDefine.GAS_ABILITY_LIB_CSHARP_SCRIPT_NAME}"; + GenerateAbilityCollection(filePath); + } + + private static void GenerateAbilityCollection(string filePath) + { + using var writer = new IndentedWriter(new StreamWriter(filePath)); + writer.WriteLine("///////////////////////////////////"); + writer.WriteLine("//// This is a generated file. ////"); + writer.WriteLine("//// Do not modify it. ////"); + writer.WriteLine("///////////////////////////////////"); + + writer.WriteLine(""); + + writer.WriteLine("using System;"); + writer.WriteLine("using System.Collections.Generic;"); + + writer.WriteLine(""); + + writer.WriteLine("namespace GAS.Runtime"); + writer.WriteLine("{"); + writer.Indent++; + { + writer.WriteLine("public static class GAbilityLib"); + writer.WriteLine("{"); + writer.Indent++; + { + writer.WriteLine("public struct AbilityInfo"); + writer.WriteLine("{"); + writer.Indent++; + { + writer.WriteLine("public string Name;"); + writer.WriteLine("public string AssetPath;"); + writer.WriteLine("public Type AbilityClassType;"); + //writer.WriteLine("public AbilityAsset Asset()"); + // writer.WriteLine("{"); + // writer.Indent++; + // { + // string loadAbilityAssetCode = string.Format(loadMethodCodeString, "AssetPath"); + // writer.WriteLine($"return {loadAbilityAssetCode};"); + // } + // writer.Indent--; + // writer.WriteLine("}"); + } + writer.Indent--; + writer.WriteLine("}"); + + writer.WriteLine(""); + + var abilityAssets = EditorUtil + .FindAssetsByType(GASSettingAsset.GameplayAbilityLibPath) + .OrderBy(x => x.UniqueName) + .ThenBy(x => x.name) + .ToArray(); + + foreach (var ability in abilityAssets) + { + var path = AssetDatabase.GetAssetPath(ability); +#if true + writer.WriteLine( + $"public static AbilityInfo {ability.UniqueName} = " + + $"new AbilityInfo {{ " + + $"Name = \"{ability.UniqueName}\", " + + $"AssetPath = \"{path}\"," + + $"AbilityClassType = typeof({ability.InstanceAbilityClassFullName}) }};"); +#else + writer.WriteLine($"public static AbilityInfo {ability.UniqueName} = new AbilityInfo"); + writer.WriteLine("{"); + writer.Indent++; + { + writer.WriteLine($"Name = \"{ability.UniqueName}\","); + writer.WriteLine($"AssetPath = \"{path}\","); + writer.WriteLine($"AbilityClassType = typeof({ability.InstanceAbilityClassFullName})"); + } + writer.Indent--; + writer.WriteLine("};"); +#endif + // writer.WriteLine($"private static {ability.InstanceAbilityClassFullName} _{validName};"); + // writer.WriteLine($"public static {ability.InstanceAbilityClassFullName} {validName}()"); + // writer.WriteLine("{"); + // writer.Indent++; + // { + // writer.WriteLine($"if (_{validName} == null) _{validName} = new {ability.InstanceAbilityClassFullName}({validName}_Info.Asset());"); + // writer.Indent++; + // { + // writer.WriteLine($"return _{validName};"); + // } + // writer.Indent--; + // } + // writer.Indent--; + // writer.WriteLine("}"); + + writer.WriteLine(""); + } + + writer.WriteLine(""); + + writer.WriteLine( + "public static Dictionary AbilityMap = new Dictionary"); + writer.WriteLine("{"); + writer.Indent++; + { + foreach (var ability in abilityAssets) + { + writer.WriteLine($"[\"{ability.UniqueName}\"] = {ability.UniqueName},"); + } + } + writer.Indent--; + writer.WriteLine("};"); + } + writer.Indent--; + writer.WriteLine("}"); + } + writer.Indent--; + writer.Write("}"); + + Console.WriteLine($"Generated GTagLib at path: {filePath}"); + } + } +} \ No newline at end of file diff --git a/EintooAR/Packages/GAS/Editor/Ability/AbilityCollectionGenerator.cs.meta b/EintooAR/Packages/GAS/Editor/Ability/AbilityCollectionGenerator.cs.meta new file mode 100644 index 00000000..dd707b5f --- /dev/null +++ b/EintooAR/Packages/GAS/Editor/Ability/AbilityCollectionGenerator.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 499ab276139746f595dbcfc5fc935f68 +timeCreated: 1705071386 \ No newline at end of file diff --git a/EintooAR/Packages/GAS/Editor/Ability/AbilityEditorUtil.cs b/EintooAR/Packages/GAS/Editor/Ability/AbilityEditorUtil.cs new file mode 100644 index 00000000..9e5b3559 --- /dev/null +++ b/EintooAR/Packages/GAS/Editor/Ability/AbilityEditorUtil.cs @@ -0,0 +1,37 @@ +#if UNITY_EDITOR +namespace GAS.Editor +{ + using System.Collections.Generic; + using System; + using System.Reflection; + using Runtime; + + public static class AbilityEditorUtil + { + public static List GetAbilityClassNames() + { + var classNames = new List(); + var assemblies = AppDomain.CurrentDomain.GetAssemblies(); + foreach (var assembly in assemblies) + { + try + { + var types = assembly.GetTypes(); + foreach (var type in types) + { + if (type.IsSubclassOf(typeof(AbstractAbility))) + { + classNames.Add(type.FullName); + } + } + } + catch (ReflectionTypeLoadException) + { + continue; + } + } + return classNames; + } + } +} +#endif \ No newline at end of file diff --git a/EintooAR/Packages/GAS/Editor/Ability/AbilityEditorUtil.cs.meta b/EintooAR/Packages/GAS/Editor/Ability/AbilityEditorUtil.cs.meta new file mode 100644 index 00000000..12c39bec --- /dev/null +++ b/EintooAR/Packages/GAS/Editor/Ability/AbilityEditorUtil.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 3f6afbd9c3ac4e958729c82c6ef46146 +timeCreated: 1704263269 \ No newline at end of file diff --git a/EintooAR/Packages/GAS/Editor/Ability/AbilityOverview.cs b/EintooAR/Packages/GAS/Editor/Ability/AbilityOverview.cs new file mode 100644 index 00000000..56833aa0 --- /dev/null +++ b/EintooAR/Packages/GAS/Editor/Ability/AbilityOverview.cs @@ -0,0 +1,141 @@ +using System.Collections.Generic; +using System.Linq; +using GAS.General.Validation; +using GAS.Runtime; +using Sirenix.OdinInspector; +using UnityEditor; +using UnityEngine; + +namespace GAS.Editor +{ + public class AbilityOverview + { + [BoxGroup("Warning", order: -1)] + [HideLabel] + [ShowIf("ExistAbilityWithEmptyUniqueName")] + [DisplayAsString(TextAlignment.Left, true)] + public string Warning_AbilityUniqueNameIsNull = + "The Unique Name of the ability must not be EMPTY! " + + "Please check!"; + + [BoxGroup("Warning", order: -1)] + [HideLabel] + [ShowIf("ExistAbilityWithDuplicatedUniqueName")] + [DisplayAsString(TextAlignment.Left, true)] + public string Warning_AbilityUniqueNameRepeat = + "The Unique Name of the ability must not be DUPLICATED! " + + "The duplicated abilities are as follows: Move,Attack ."; + + [VerticalGroup("Abilities", order: 1)] + [ListDrawerSettings(ShowFoldout = true, ShowIndexLabels = false, ShowItemCount = true, IsReadOnly = true)] + [DisplayAsString] + public List Abilities = new List(); + + public AbilityOverview() + { + Refresh(); + } + + [HorizontalGroup("Buttons", order: 0, MarginRight = 0.2f)] + [GUIColor(0, 0.9f, 0.1f, 1)] + [Button("Generate Ability Collection", ButtonSizes.Large, ButtonStyle.Box, Expanded = true)] + void GenerateAbilityCollection() + { + if (ExistAbilityWithEmptyUniqueName() || ExistAbilityWithDuplicatedUniqueName()) + { + EditorUtility.DisplayDialog("Warning", "Please check the warning message!\n" + + "Fix the Unique Name Error!\n" + + "(If you have fixed all and the warning still exist," + + " try to refresh the abilities with the REFRESH button.)", "OK"); + return; + } + + AbilityCollectionGenerator.Gen(); + AssetDatabase.Refresh(); + } + + private bool _orderByUniqueName = true; + + [HorizontalGroup("Buttons", width: 180)] + [Button(SdfIconType.SortAlphaDown, "@_orderByUniqueName?\"Sort By AssetName\":\"Sort By UniqueName\"", + ButtonHeight = 30)] + public void ToggleOrderByUniqueName() + { + _orderByUniqueName = !_orderByUniqueName; + Refresh(); + } + + private bool _showDetail = false; + + [HorizontalGroup("Buttons", width: 120)] + [Button(SdfIconType.TicketDetailed, "@_showDetail?\"Hide Detail\":\"Show Detail\"", ButtonHeight = 30)] + public void ToggleShowDetail() + { + _showDetail = !_showDetail; + Refresh(); + } + + [HorizontalGroup("Buttons", width: 50)] + [GUIColor(1, 1f, 0)] + [Button(SdfIconType.ArrowRepeat, "", ButtonHeight = 30)] + [HideLabel] + public void Refresh() + { + Abilities.Clear(); + var abilityAssets = EditorUtil.FindAssetsByType(GASSettingAsset.GameplayAbilityLibPath); + var orderedAbilityAssets = _orderByUniqueName + ? abilityAssets + .OrderBy(x => x.UniqueName) + .ThenBy(x => x.name) + : abilityAssets.OrderBy(x => x.name); + + Abilities = orderedAbilityAssets.Select(ability => + { + var text = Validations.ValidateVariableName(ability.UniqueName).IsValid + ? ability.UniqueName + : $"{ability.UniqueName}(非法UniqueName)"; + + if (_showDetail) + { + text += $" - asset: {ability.name}, type: {ability.GetType().FullName}"; + } + + return text; + }).ToList(); + } + + bool ExistAbilityWithEmptyUniqueName() + { + bool existEmpty = Abilities.Exists(string.IsNullOrEmpty); + return existEmpty; + } + + bool ExistAbilityWithDuplicatedUniqueName() + { + var duplicateStrings = FindDuplicateStrings(Abilities); + bool existDuplicated = duplicateStrings.Length > 0; + if (existDuplicated) + { + string duplicatedUniqueName = duplicateStrings.Aggregate("", (current, d) => current + (d + ",")); + duplicatedUniqueName = duplicatedUniqueName.Remove(duplicatedUniqueName.Length - 1, 1); + Warning_AbilityUniqueNameRepeat = + "The Unique Name of the ability must not be DUPLICATED! " + + $"The duplicated abilities are as follows: \n {duplicatedUniqueName} ."; + } + + return existDuplicated; + } + + static string[] FindDuplicateStrings(IEnumerable names) + { + var duplicates = names + .Where(name => !string.IsNullOrEmpty(name)) + .GroupBy(name => name) + .Where(group => group.Count() > 1) + .Select(group => group.Key) + .ToArray(); + + return duplicates; + } + } +} \ No newline at end of file diff --git a/EintooAR/Packages/GAS/Editor/Ability/AbilityOverview.cs.meta b/EintooAR/Packages/GAS/Editor/Ability/AbilityOverview.cs.meta new file mode 100644 index 00000000..d9cee79e --- /dev/null +++ b/EintooAR/Packages/GAS/Editor/Ability/AbilityOverview.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 3209fb75be944c36b4f2b9d347aee120 +timeCreated: 1705290851 \ No newline at end of file diff --git a/EintooAR/Packages/GAS/Editor/Ability/AbilityTimelineEditor.meta b/EintooAR/Packages/GAS/Editor/Ability/AbilityTimelineEditor.meta new file mode 100644 index 00000000..68f03be7 --- /dev/null +++ b/EintooAR/Packages/GAS/Editor/Ability/AbilityTimelineEditor.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 0f637cff7efc48542be2b4138fe99108 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/EintooAR/Packages/GAS/Editor/Ability/AbilityTimelineEditor/EditorWindow.meta b/EintooAR/Packages/GAS/Editor/Ability/AbilityTimelineEditor/EditorWindow.meta new file mode 100644 index 00000000..ff2934aa --- /dev/null +++ b/EintooAR/Packages/GAS/Editor/Ability/AbilityTimelineEditor/EditorWindow.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 55f35a69d4a54054d96e7cc375d25246 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/EintooAR/Packages/GAS/Editor/Ability/AbilityTimelineEditor/EditorWindow/AbilityTimelineContent.uxml b/EintooAR/Packages/GAS/Editor/Ability/AbilityTimelineEditor/EditorWindow/AbilityTimelineContent.uxml new file mode 100644 index 00000000..6d559192 --- /dev/null +++ b/EintooAR/Packages/GAS/Editor/Ability/AbilityTimelineEditor/EditorWindow/AbilityTimelineContent.uxml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/EintooAR/Packages/GAS/Editor/Ability/AbilityTimelineEditor/EditorWindow/AbilityTimelineContent.uxml.meta b/EintooAR/Packages/GAS/Editor/Ability/AbilityTimelineEditor/EditorWindow/AbilityTimelineContent.uxml.meta new file mode 100644 index 00000000..cb125194 --- /dev/null +++ b/EintooAR/Packages/GAS/Editor/Ability/AbilityTimelineEditor/EditorWindow/AbilityTimelineContent.uxml.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 3f6767c7cb94e1940bb9595b5fba5d45 +ScriptedImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 2 + userData: + assetBundleName: + assetBundleVariant: + script: {fileID: 13804, guid: 0000000000000000e000000000000000, type: 0} diff --git a/EintooAR/Packages/GAS/Editor/Ability/AbilityTimelineEditor/EditorWindow/AbilityTimelineEditorConfig.cs b/EintooAR/Packages/GAS/Editor/Ability/AbilityTimelineEditor/EditorWindow/AbilityTimelineEditorConfig.cs new file mode 100644 index 00000000..4baf5bdb --- /dev/null +++ b/EintooAR/Packages/GAS/Editor/Ability/AbilityTimelineEditor/EditorWindow/AbilityTimelineEditorConfig.cs @@ -0,0 +1,15 @@ +#if UNITY_EDITOR +namespace GAS.Editor +{ + using GAS.General; + + public class AbilityTimelineEditorConfig + { + public int FrameUnitWidth = 10; + public const int StandardFrameUnitWidth = 1; + public const int MaxFrameUnitLevel= 20; + public const float MinTimerShaftFrameDrawStep = 5; + public int DefaultFrameRate => GASTimer.FrameRate; + } +} +#endif \ No newline at end of file diff --git a/EintooAR/Packages/GAS/Editor/Ability/AbilityTimelineEditor/EditorWindow/AbilityTimelineEditorConfig.cs.meta b/EintooAR/Packages/GAS/Editor/Ability/AbilityTimelineEditor/EditorWindow/AbilityTimelineEditorConfig.cs.meta new file mode 100644 index 00000000..56eac869 --- /dev/null +++ b/EintooAR/Packages/GAS/Editor/Ability/AbilityTimelineEditor/EditorWindow/AbilityTimelineEditorConfig.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 51b96cc42da3453c9db1934582d0a8c2 +timeCreated: 1708482904 \ No newline at end of file diff --git a/EintooAR/Packages/GAS/Editor/Ability/AbilityTimelineEditor/EditorWindow/AbilityTimelineEditorWindow.cs b/EintooAR/Packages/GAS/Editor/Ability/AbilityTimelineEditor/EditorWindow/AbilityTimelineEditorWindow.cs new file mode 100644 index 00000000..8bd2f8a1 --- /dev/null +++ b/EintooAR/Packages/GAS/Editor/Ability/AbilityTimelineEditor/EditorWindow/AbilityTimelineEditorWindow.cs @@ -0,0 +1,397 @@ +using System; +using GAS.Runtime; +using UnityEditor; +using UnityEditor.SceneManagement; +using UnityEditor.UIElements; +using UnityEngine; +using UnityEngine.SceneManagement; +using UnityEngine.UIElements; +using Object = UnityEngine.Object; + +namespace GAS.Editor +{ + /// + /// 这个类被反射引用到, 重构请小心!! + /// + public class AbilityTimelineEditorWindow : EditorWindow + { + [SerializeField] + private VisualTreeAsset m_VisualTreeAsset; + + private VisualElement _root; + + + public static AbilityTimelineEditorWindow Instance { get; private set; } + public TimelineTrackView TrackView { get; private set; } + + public TimelineInspector TimelineInspector { get; private set; } + + private static EditorWindow _childInspector; + + public void CreateGUI() + { + Instance = this; + _root = rootVisualElement; + + // Instantiate UXML + VisualElement labelFromUxml = m_VisualTreeAsset.Instantiate(); + _root.Add(labelFromUxml); + + InitAbilityAssetBar(); + InitTopBar(); + InitController(); + TimerShaftView = new TimerShaftView(_root); + TrackView = new TimelineTrackView(_root); + TimelineInspector = new TimelineInspector(_root); + } + + /// + /// 这个方法被反射引用到, 重构请小心!! + /// + public static void ShowWindow(TimelineAbilityAssetBase asset) + { + var wnd = GetWindow(); + wnd.titleContent = new GUIContent("AbilityTimelineEditorWindow"); + wnd.InitAbility(asset); + + // 打开子Inspector + EditorApplication.delayCall += () => wnd.ShowChildInspector(); + } + + public void Save() + { + AbilityAsset.Save(); + } + + private void InitAbility(TimelineAbilityAssetBase asset) + { + _abilityAsset.value = asset; + MaxFrame.value = AbilityAsset.FrameCount; + CurrentSelectFrameIndex = 0; + TimerShaftView.RefreshTimerDraw(); + TrackView.RefreshTrackDraw(); + } + + private void SaveAsset() + { + EditorUtility.SetDirty(AbilityAsset); + AssetDatabase.SaveAssetIfDirty(AbilityAsset); + } + + #region Config + + public AbilityTimelineEditorConfig Config { get; } = new(); + + private ObjectField _abilityAsset; + private Button _btnShowAbilityAssetDetail; + public TimelineAbilityAssetBase AbilityAsset => _abilityAsset.value as TimelineAbilityAssetBase; + + // private TimelineAbilityEditorWindow AbilityAssetEditor => AbilityAsset != null + // ? UnityEditor.Editor.CreateEditor(AbilityAsset) as TimelineAbilityEditorWindow + // : null; + + private void InitAbilityAssetBar() + { + _abilityAsset = _root.Q("SequentialAbilityAsset"); + _abilityAsset.RegisterValueChangedCallback(OnSequentialAbilityAssetChanged); + + _btnShowAbilityAssetDetail = _root.Q