diff --git a/JEX_GAS/.gitignore b/JEX_GAS/.gitignore new file mode 100644 index 00000000..8a224650 --- /dev/null +++ b/JEX_GAS/.gitignore @@ -0,0 +1,75 @@ +# This .gitignore file should be placed at the root of your Unity project directory +# +# Get latest from https://github.com/github/gitignore/blob/main/Unity.gitignore +# +/[Ll]ibrary/ +/[Tt]emp/ +/[Oo]bj/ +/[Bb]uild/ +/[Bb]uilds/ +/[Ll]ogs/ +/[Uu]ser[Ss]ettings/ + +# MemoryCaptures can get excessive in size. +# They also could contain extremely sensitive data +/[Mm]emoryCaptures/ + +# Recordings can get excessive in size +/[Rr]ecordings/ + +# 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 +*.aab +*.unitypackage +*.app + +# Crashlytics generated file +crashlytics-build.properties + +# Packed Addressables +/[Aa]ssets/[Aa]ddressable[Aa]ssets[Dd]ata/*/*.bin* + +# Temporary auto-generated Android Assets +/[Aa]ssets/[Ss]treamingAssets/aa.meta +/[Aa]ssets/[Ss]treamingAssets/aa/* + +# idea +.idea/* \ No newline at end of file diff --git a/JEX_GAS/Assets/Demo.meta b/JEX_GAS/Assets/Demo.meta new file mode 100644 index 00000000..a50d3c6f --- /dev/null +++ b/JEX_GAS/Assets/Demo.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: ebc3cec6713633742ae15cc9e8038ab1 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/JEX_GAS/Assets/Demo/GAS.meta b/JEX_GAS/Assets/Demo/GAS.meta new file mode 100644 index 00000000..7119cfeb --- /dev/null +++ b/JEX_GAS/Assets/Demo/GAS.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 532d49ae398deae46a5142c91296a7bd +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/JEX_GAS/Assets/Demo/GAS/Config.meta b/JEX_GAS/Assets/Demo/GAS/Config.meta new file mode 100644 index 00000000..1f4a3a48 --- /dev/null +++ b/JEX_GAS/Assets/Demo/GAS/Config.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 4f75f19949948aa40b2fe17f99229781 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/JEX_GAS/Assets/Demo/GAS/Config/AbilitySystemComponentLib.meta b/JEX_GAS/Assets/Demo/GAS/Config/AbilitySystemComponentLib.meta new file mode 100644 index 00000000..57a63cf7 --- /dev/null +++ b/JEX_GAS/Assets/Demo/GAS/Config/AbilitySystemComponentLib.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 0522d1120d0b15c468bd2c4cd52d6093 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/JEX_GAS/Assets/Demo/GAS/Config/AbilityTaskLib.meta b/JEX_GAS/Assets/Demo/GAS/Config/AbilityTaskLib.meta new file mode 100644 index 00000000..3c53f821 --- /dev/null +++ b/JEX_GAS/Assets/Demo/GAS/Config/AbilityTaskLib.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 575d526145ecdc747a602b69084e933d +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/JEX_GAS/Assets/Demo/GAS/Config/GameplayAbilityLib.meta b/JEX_GAS/Assets/Demo/GAS/Config/GameplayAbilityLib.meta new file mode 100644 index 00000000..413d8572 --- /dev/null +++ b/JEX_GAS/Assets/Demo/GAS/Config/GameplayAbilityLib.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 1b4779482b24f6c4d8ebeac4c1ac7bba +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/JEX_GAS/Assets/Demo/GAS/Config/GameplayAbilityLib/JisolDemo1.asset b/JEX_GAS/Assets/Demo/GAS/Config/GameplayAbilityLib/JisolDemo1.asset new file mode 100644 index 00000000..1022f02b --- /dev/null +++ b/JEX_GAS/Assets/Demo/GAS/Config/GameplayAbilityLib/JisolDemo1.asset @@ -0,0 +1,50 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d763af469c524557946c477b9bea3a46, type: 3} + m_Name: JisolDemo1 + m_EditorClassIdentifier: + Description: + UniqueName: JisolDemo1 + Cost: {fileID: 0} + Cooldown: {fileID: 0} + CooldownTime: 0 + AssetTags: [] + CancelAbilityTags: [] + BlockAbilityTags: [] + ActivationOwnedTags: [] + ActivationRequiredTags: [] + ActivationBlockedTags: [] + Speed: 1 + ManualEndAbility: 1 + FrameCount: 60 + DurationalCues: + - trackName: + clipEvents: [] + InstantCues: + - trackName: + markEvents: [] + ReleaseGameplayEffect: + - trackName: + markEvents: [] + BuffGameplayEffects: + - trackName: Buff + clipEvents: [] + InstantTasks: + - trackName: + markEvents: [] + OngoingTasks: + - trackName: Task Clips + clipEvents: [] + - trackName: Task Clips + clipEvents: [] + PassiveGameplayEffects: [] + PassiveTasks: [] diff --git a/JEX_GAS/Assets/Demo/GAS/Config/GameplayAbilityLib/JisolDemo1.asset.meta b/JEX_GAS/Assets/Demo/GAS/Config/GameplayAbilityLib/JisolDemo1.asset.meta new file mode 100644 index 00000000..01aa24f0 --- /dev/null +++ b/JEX_GAS/Assets/Demo/GAS/Config/GameplayAbilityLib/JisolDemo1.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: b78ae002fbbf510419a39987f22201f1 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/JEX_GAS/Assets/Demo/GAS/Config/GameplayCueLib.meta b/JEX_GAS/Assets/Demo/GAS/Config/GameplayCueLib.meta new file mode 100644 index 00000000..bccf34bc --- /dev/null +++ b/JEX_GAS/Assets/Demo/GAS/Config/GameplayCueLib.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 27a7bb5d47b5c4641870fe3d03243802 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/JEX_GAS/Assets/Demo/GAS/Config/GameplayEffectLib.meta b/JEX_GAS/Assets/Demo/GAS/Config/GameplayEffectLib.meta new file mode 100644 index 00000000..5ef11bbd --- /dev/null +++ b/JEX_GAS/Assets/Demo/GAS/Config/GameplayEffectLib.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: ea0e8fd86f27d314289050bd4507cf6a +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/JEX_GAS/Assets/Demo/GAS/Config/ModMagnitudeCalculationLib.meta b/JEX_GAS/Assets/Demo/GAS/Config/ModMagnitudeCalculationLib.meta new file mode 100644 index 00000000..fb993828 --- /dev/null +++ b/JEX_GAS/Assets/Demo/GAS/Config/ModMagnitudeCalculationLib.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: ce52a1fda69211e45997126c7036bf7b +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/JEX_GAS/Assets/Demo/Scripts.meta b/JEX_GAS/Assets/Demo/Scripts.meta new file mode 100644 index 00000000..1000baea --- /dev/null +++ b/JEX_GAS/Assets/Demo/Scripts.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 07d357ab8ac95864b80f9b54e729abe8 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/JEX_GAS/Assets/Demo/Scripts/Gen.meta b/JEX_GAS/Assets/Demo/Scripts/Gen.meta new file mode 100644 index 00000000..126e19a5 --- /dev/null +++ b/JEX_GAS/Assets/Demo/Scripts/Gen.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 27ed906aca80d874b9138a6559c7835e +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/JEX_GAS/Assets/Demo/Scripts/Gen/AbilitySystemComponentExtension.gen.cs b/JEX_GAS/Assets/Demo/Scripts/Gen/AbilitySystemComponentExtension.gen.cs new file mode 100644 index 00000000..99a386eb --- /dev/null +++ b/JEX_GAS/Assets/Demo/Scripts/Gen/AbilitySystemComponentExtension.gen.cs @@ -0,0 +1,44 @@ +/////////////////////////////////// +//// This is a generated file. //// +//// Do not modify it. //// +/////////////////////////////////// + +using System; +using System.Linq; +using UnityEngine; + +namespace GAS.Runtime +{ + public static class AbilitySystemComponentExtension + { + public static Type[] PresetAttributeSetTypes(this AbilitySystemComponent asc) + { + if (asc.Preset == null) return null; + var attrSetTypes = new Type[asc.Preset.AttributeSets.Length]; + for (var i = 0; i < asc.Preset.AttributeSets.Length; i++) + attrSetTypes[i] = GAttrSetLib.AttrSetTypeDict[asc.Preset.AttributeSets[i]]; + return attrSetTypes; + } + + public static GameplayTag[] PresetBaseTags(this AbilitySystemComponent asc) + { + if (asc.Preset == null) return null; + return asc.Preset.BaseTags; + } + + public static void InitWithPreset(this AbilitySystemComponent asc, int level, AbilitySystemComponentPreset preset = null) + { + if (preset != null) asc.SetPreset(preset); + if (asc.Preset == null) return; + +#if UNITY_EDITOR + if (asc.Preset.BaseAbilities != null && asc.Preset.BaseAbilities.Any(x => x == null)) + { + Debug.LogWarning($"BaseAbilities contains null in preset: {asc.Preset.name}"); + } +#endif + + asc.Init(asc.PresetBaseTags(), asc.PresetAttributeSetTypes(), asc.Preset.BaseAbilities, level); + } + } +} \ No newline at end of file diff --git a/JEX_GAS/Assets/Demo/Scripts/Gen/AbilitySystemComponentExtension.gen.cs.meta b/JEX_GAS/Assets/Demo/Scripts/Gen/AbilitySystemComponentExtension.gen.cs.meta new file mode 100644 index 00000000..c214a166 --- /dev/null +++ b/JEX_GAS/Assets/Demo/Scripts/Gen/AbilitySystemComponentExtension.gen.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a829f1acecbd5d348800bcbf18fb138e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/JEX_GAS/Assets/Demo/Scripts/Gen/GAttrLib.gen.cs b/JEX_GAS/Assets/Demo/Scripts/Gen/GAttrLib.gen.cs new file mode 100644 index 00000000..817eb09f --- /dev/null +++ b/JEX_GAS/Assets/Demo/Scripts/Gen/GAttrLib.gen.cs @@ -0,0 +1,18 @@ +/////////////////////////////////// +//// This is a generated file. //// +//// Do not modify it. //// +/////////////////////////////////// + +using System.Collections.Generic; + +namespace GAS.Runtime +{ + public static class GAttrLib + { + + // For facilitating the creation of a Value Dropdown in the editor. + public static readonly IReadOnlyList AttributeNames = new List + { + }; + } +} \ No newline at end of file diff --git a/JEX_GAS/Assets/Demo/Scripts/Gen/GAttrLib.gen.cs.meta b/JEX_GAS/Assets/Demo/Scripts/Gen/GAttrLib.gen.cs.meta new file mode 100644 index 00000000..4fe69e07 --- /dev/null +++ b/JEX_GAS/Assets/Demo/Scripts/Gen/GAttrLib.gen.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d2db3b0427abaab4c9c8ec9df6c351e8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/JEX_GAS/Assets/Demo/Scripts/Gen/GAttrSetLib.gen.cs b/JEX_GAS/Assets/Demo/Scripts/Gen/GAttrSetLib.gen.cs new file mode 100644 index 00000000..d4e671e2 --- /dev/null +++ b/JEX_GAS/Assets/Demo/Scripts/Gen/GAttrSetLib.gen.cs @@ -0,0 +1,25 @@ +/////////////////////////////////// +//// This is a generated file. //// +//// Do not modify it. //// +/////////////////////////////////// + +using System; +using System.Collections.Generic; + +namespace GAS.Runtime +{ + public static class GAttrSetLib + { + public static readonly IReadOnlyDictionary AttrSetTypeDict = new Dictionary + { + }; + + public static readonly IReadOnlyDictionary TypeToName = new Dictionary + { + }; + + public static readonly IReadOnlyList AttributeFullNames = new List + { + }; + } +} \ No newline at end of file diff --git a/JEX_GAS/Assets/Demo/Scripts/Gen/GAttrSetLib.gen.cs.meta b/JEX_GAS/Assets/Demo/Scripts/Gen/GAttrSetLib.gen.cs.meta new file mode 100644 index 00000000..3d2620ed --- /dev/null +++ b/JEX_GAS/Assets/Demo/Scripts/Gen/GAttrSetLib.gen.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e232dda0e81c76c4ba33b4b47af0644a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/JEX_GAS/Assets/Demo/Scripts/Gen/GTagLib.gen.cs b/JEX_GAS/Assets/Demo/Scripts/Gen/GTagLib.gen.cs new file mode 100644 index 00000000..47d88584 --- /dev/null +++ b/JEX_GAS/Assets/Demo/Scripts/Gen/GTagLib.gen.cs @@ -0,0 +1,20 @@ +/////////////////////////////////// +//// This is a generated file. //// +//// Do not modify it. //// +/////////////////////////////////// + +using System.Collections.Generic; + +namespace GAS.Runtime +{ + public static class GTagLib + { + /// Ability + public static GameplayTag Ability { get; } = new("Ability"); + + public static readonly IReadOnlyDictionary TagMap = new Dictionary + { + ["Ability"] = Ability, + }; + } +} \ No newline at end of file diff --git a/JEX_GAS/Assets/Demo/Scripts/Gen/GTagLib.gen.cs.meta b/JEX_GAS/Assets/Demo/Scripts/Gen/GTagLib.gen.cs.meta new file mode 100644 index 00000000..6d4e11ed --- /dev/null +++ b/JEX_GAS/Assets/Demo/Scripts/Gen/GTagLib.gen.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 77b03860d4e223243838914f3e9fee1c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/JEX_GAS/Assets/GAS.meta b/JEX_GAS/Assets/GAS.meta new file mode 100644 index 00000000..bae8b55e --- /dev/null +++ b/JEX_GAS/Assets/GAS.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d551dd2e1aafab741ac2ebf771ce0dd7 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/JEX_GAS/Assets/GAS/CHANGELOG.md b/JEX_GAS/Assets/GAS/CHANGELOG.md new file mode 100644 index 00000000..957a293a --- /dev/null +++ b/JEX_GAS/Assets/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/JEX_GAS/Assets/GAS/CHANGELOG.md.meta b/JEX_GAS/Assets/GAS/CHANGELOG.md.meta new file mode 100644 index 00000000..59268e95 --- /dev/null +++ b/JEX_GAS/Assets/GAS/CHANGELOG.md.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 34ae97a0d741c5844a4fac12ff8e1c45 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/JEX_GAS/Assets/GAS/Editor.meta b/JEX_GAS/Assets/GAS/Editor.meta new file mode 100644 index 00000000..f160b877 --- /dev/null +++ b/JEX_GAS/Assets/GAS/Editor.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: ceb70b71a95f4810bb22c72560de1755 +timeCreated: 1701928918 \ No newline at end of file diff --git a/JEX_GAS/Assets/GAS/Editor/Ability.meta b/JEX_GAS/Assets/GAS/Editor/Ability.meta new file mode 100644 index 00000000..b22e0f24 --- /dev/null +++ b/JEX_GAS/Assets/GAS/Editor/Ability.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 916ae4e58ce74ba2b0686ddc372419d9 +timeCreated: 1703772158 \ No newline at end of file diff --git a/JEX_GAS/Assets/GAS/Editor/Ability/AbilityCollectionGenerator.cs b/JEX_GAS/Assets/GAS/Editor/Ability/AbilityCollectionGenerator.cs new file mode 100644 index 00000000..be74ab81 --- /dev/null +++ b/JEX_GAS/Assets/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/JEX_GAS/Assets/GAS/Editor/Ability/AbilityCollectionGenerator.cs.meta b/JEX_GAS/Assets/GAS/Editor/Ability/AbilityCollectionGenerator.cs.meta new file mode 100644 index 00000000..dd707b5f --- /dev/null +++ b/JEX_GAS/Assets/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/JEX_GAS/Assets/GAS/Editor/Ability/AbilityEditorUtil.cs b/JEX_GAS/Assets/GAS/Editor/Ability/AbilityEditorUtil.cs new file mode 100644 index 00000000..9e5b3559 --- /dev/null +++ b/JEX_GAS/Assets/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/JEX_GAS/Assets/GAS/Editor/Ability/AbilityEditorUtil.cs.meta b/JEX_GAS/Assets/GAS/Editor/Ability/AbilityEditorUtil.cs.meta new file mode 100644 index 00000000..12c39bec --- /dev/null +++ b/JEX_GAS/Assets/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/JEX_GAS/Assets/GAS/Editor/Ability/AbilityOverview.cs b/JEX_GAS/Assets/GAS/Editor/Ability/AbilityOverview.cs new file mode 100644 index 00000000..56833aa0 --- /dev/null +++ b/JEX_GAS/Assets/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/JEX_GAS/Assets/GAS/Editor/Ability/AbilityOverview.cs.meta b/JEX_GAS/Assets/GAS/Editor/Ability/AbilityOverview.cs.meta new file mode 100644 index 00000000..d9cee79e --- /dev/null +++ b/JEX_GAS/Assets/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/JEX_GAS/Assets/GAS/Editor/Ability/AbilityTimelineEditor.meta b/JEX_GAS/Assets/GAS/Editor/Ability/AbilityTimelineEditor.meta new file mode 100644 index 00000000..68f03be7 --- /dev/null +++ b/JEX_GAS/Assets/GAS/Editor/Ability/AbilityTimelineEditor.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 0f637cff7efc48542be2b4138fe99108 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/JEX_GAS/Assets/GAS/Editor/Ability/AbilityTimelineEditor/EditorWindow.meta b/JEX_GAS/Assets/GAS/Editor/Ability/AbilityTimelineEditor/EditorWindow.meta new file mode 100644 index 00000000..ff2934aa --- /dev/null +++ b/JEX_GAS/Assets/GAS/Editor/Ability/AbilityTimelineEditor/EditorWindow.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 55f35a69d4a54054d96e7cc375d25246 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/JEX_GAS/Assets/GAS/Editor/Ability/AbilityTimelineEditor/EditorWindow/AbilityTimelineContent.uxml b/JEX_GAS/Assets/GAS/Editor/Ability/AbilityTimelineEditor/EditorWindow/AbilityTimelineContent.uxml new file mode 100644 index 00000000..6d559192 --- /dev/null +++ b/JEX_GAS/Assets/GAS/Editor/Ability/AbilityTimelineEditor/EditorWindow/AbilityTimelineContent.uxml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/JEX_GAS/Assets/GAS/Editor/Ability/AbilityTimelineEditor/EditorWindow/AbilityTimelineContent.uxml.meta b/JEX_GAS/Assets/GAS/Editor/Ability/AbilityTimelineEditor/EditorWindow/AbilityTimelineContent.uxml.meta new file mode 100644 index 00000000..cb125194 --- /dev/null +++ b/JEX_GAS/Assets/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/JEX_GAS/Assets/GAS/Editor/Ability/AbilityTimelineEditor/EditorWindow/AbilityTimelineEditorConfig.cs b/JEX_GAS/Assets/GAS/Editor/Ability/AbilityTimelineEditor/EditorWindow/AbilityTimelineEditorConfig.cs new file mode 100644 index 00000000..4baf5bdb --- /dev/null +++ b/JEX_GAS/Assets/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/JEX_GAS/Assets/GAS/Editor/Ability/AbilityTimelineEditor/EditorWindow/AbilityTimelineEditorConfig.cs.meta b/JEX_GAS/Assets/GAS/Editor/Ability/AbilityTimelineEditor/EditorWindow/AbilityTimelineEditorConfig.cs.meta new file mode 100644 index 00000000..56eac869 --- /dev/null +++ b/JEX_GAS/Assets/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/JEX_GAS/Assets/GAS/Editor/Ability/AbilityTimelineEditor/EditorWindow/AbilityTimelineEditorWindow.cs b/JEX_GAS/Assets/GAS/Editor/Ability/AbilityTimelineEditor/EditorWindow/AbilityTimelineEditorWindow.cs new file mode 100644 index 00000000..8bd2f8a1 --- /dev/null +++ b/JEX_GAS/Assets/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