临时提交

This commit is contained in:
PC-20230316NUNE\Administrator
2024-10-21 20:02:19 +08:00
parent 930911e7df
commit e9c01842f0
206 changed files with 14468 additions and 21348 deletions

View File

@@ -2,6 +2,7 @@
using System.Collections.Concurrent;
using System.Runtime.CompilerServices;
using System.Threading;
using GAS.Runtime;
using UnityEngine;
using UnityEngine.Profiling;
@@ -14,24 +15,31 @@ namespace GAS.General
public class JexGasObjectPool
{
private static JexGasObjectPool _singleton;
public static JexGasObjectPool Instance => _singleton ??= new JexGasObjectPool();
// private static JexGasObjectPool _singleton;
//
// public static JexGasObjectPool Instance => _singleton ??= new JexGasObjectPool();
public JexGasManager Manager;
public JexGasObjectPool(JexGasManager manager)
{
Manager = manager;
}
private readonly ConcurrentDictionary<Type, Pool> _objPool = new();
private readonly Func<Type, Pool> _addPoolFunc = type => new Pool(type, 1024);
public static void Awake()
{
_singleton = null;
_singleton = new JexGasObjectPool();
}
public static void Destroy()
{
_singleton = null;
}
// public static void Awake()
// {
// _singleton = null;
// _singleton = new JexGasObjectPool();
// }
//
// public static void Destroy()
// {
// _singleton = null;
// }
public T Fetch<T>() where T : class
{

View File

@@ -16,7 +16,7 @@ namespace GAS.Runtime
public void Tick(int dt)
{
var abilitySpecs = JexGasObjectPool.Instance.Fetch<List<AbilitySpec>>();
var abilitySpecs = _owner.GetManager().ObjectPool.Fetch<List<AbilitySpec>>();
abilitySpecs.AddRange(_abilities.Values);
foreach (var abilitySpec in abilitySpecs)
@@ -25,7 +25,7 @@ namespace GAS.Runtime
}
abilitySpecs.Clear();
JexGasObjectPool.Instance.Recycle(abilitySpecs);
_owner.GetManager().ObjectPool.Recycle(abilitySpecs);
}
public void GrantAbility(AbstractAbility ability)

View File

@@ -1,10 +0,0 @@
using System;
namespace GAS.Runtime
{
public struct AbilityInstanceInfo
{
public AbilityAsset abilityAsset;
public Type abilityType;
}
}

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 99ad85c3caba4604b9950ae1105e85b4
timeCreated: 1706090943

View File

@@ -28,8 +28,8 @@ namespace GAS.Runtime
Tag = new AbilityTagContainer(
DataReference.AssetTags, DataReference.CancelAbilityTags, DataReference.BlockAbilityTags,
DataReference.ActivationOwnedTags, DataReference.ActivationRequiredTags, DataReference.ActivationBlockedTags);
Cooldown = DataReference.Cooldown ? DataReference.Cooldown.SharedInstance : default;
Cost = DataReference.Cost ? DataReference.Cost.SharedInstance: default;
Cooldown = DataReference.Cooldown?.SharedInstance();
Cost = DataReference.Cost?.SharedInstance();
CooldownTime = DataReference.CooldownTime;
}

View File

@@ -1,18 +0,0 @@
using System;
using GAS.Runtime;
using UnityEngine;
namespace GAS.Runtime
{
[Serializable]
public abstract class CatchAreaBase : TargetCatcherBase
{
public LayerMask checkLayer;
public void Init(AbilitySystemComponent owner, LayerMask checkLayer)
{
base.Init(owner);
this.checkLayer = checkLayer;
}
}
}

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 58b4935f7a5a43d69506e28666032462
timeCreated: 1709451834

View File

@@ -0,0 +1,14 @@
namespace GAS.Runtime
{
/// <summary>
/// 目标捕获器类型枚举
/// </summary>
public enum EnumTargetCatcherType
{
CatchSelf = 1, // 捕获Ability的施法者自身
CatchTarget, // 捕获Ability的目标
EnumBuiltinCount = 10, // 内建捕获器类型枚举的上限控制,上层业务派生由此开始
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 388df5b7ba124ee3b97a2380e1e8800d
timeCreated: 1729498857

View File

@@ -0,0 +1,45 @@
using System.Collections.Generic;
using UnityEngine;
namespace GAS.Runtime
{
public partial class TargetCatcherFactory
{
public delegate TargetCatcherBase NodeCreateFunc();
private static readonly Dictionary<ushort, NodeCreateFunc> s_TypeId2FactoryFunc;
static TargetCatcherFactory()
{
s_TypeId2FactoryFunc = new Dictionary<ushort, NodeCreateFunc>();
Register((ushort)EnumTargetCatcherType.CatchSelf, () => new CatchSelf());
Register((ushort)EnumTargetCatcherType.CatchTarget, () => new CatchTarget());
}
/// <summary>
/// 注册TargetCatcher构造方法
/// </summary>
/// <param name="typeId"></param>
/// <param name="func"></param>
public static void Register(ushort typeId, NodeCreateFunc func)
{
s_TypeId2FactoryFunc[typeId] = func;
}
/// <summary>
/// 通过节点类型创建TargetCatcher
/// </summary>
/// <param name="typeId">Timeline节点类型</param>
/// <returns></returns>
public static TargetCatcherBase CreateNode(ushort typeId)
{
if (!s_TypeId2FactoryFunc.ContainsKey(typeId))
{
Debug.LogError($"Can Not Find TargetCatcher Factory Function Id={typeId}");
return null;
}
return s_TypeId2FactoryFunc[typeId]();
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: e8c940b523ae4eb79010981381e33212
timeCreated: 1729505456

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: f8f62af330f4460b865fdcf0a2786d1b
timeCreated: 1729505957

View File

@@ -0,0 +1,97 @@
using System.Collections.Generic;
using UnityEngine;
namespace GAS.Runtime
{
/// <summary>
/// AbilityTask构造工厂
/// </summary>
public static class AbilityTaskFactory
{
public delegate AbilityTaskBase NodeCreateFunc();
/// <summary>
/// TypeID映射构造方法
/// </summary>
private static readonly Dictionary<ushort, NodeCreateFunc> s_TypeId2FactoryFunc;
static AbilityTaskFactory()
{
s_TypeId2FactoryFunc = new Dictionary<ushort, NodeCreateFunc>();
Register((ushort)EnumAbilityTaskType.InstantTaskStart, () => new DefaultInstantAbilityTask());
Register((ushort)EnumAbilityTaskType.OngoingTaskStart, () => new DefaultOngoingAbilityTask());
Register((ushort)EnumAbilityTaskType.PassiveTaskStart, () => new DefaultPassiveAbilityTask());
}
/// <summary>
/// 注册Timeline节点类型构造方法
/// </summary>
/// <param name="typeId"></param>
/// <param name="func"></param>
public static void Register(ushort typeId, NodeCreateFunc func)
{
s_TypeId2FactoryFunc[typeId] = func;
}
/// <summary>
/// 通过节点类型创建InstantAbilityTask实例
/// </summary>
/// <param name="typeId">AbilityTask类型</param>
/// <returns></returns>
public static InstantAbilityTask CreateInstantTask(ushort typeId)
{
if (typeId < (ushort)EnumAbilityTaskType.InstantTaskStart && typeId >= (ushort)EnumAbilityTaskType.OngoingTaskStart)
{
Debug.LogError($"TypeId不是InstantTask派生的TypeId={typeId}");
return null;
}
return CreateTask(typeId) as InstantAbilityTask;
}
/// <summary>
/// 通过节点类型创建OngoingAbilityTask实例
/// </summary>
/// <param name="typeId">AbilityTask类型</param>
/// <returns></returns>
public static OngoingAbilityTask CreateOngoingTask(ushort typeId)
{
if (typeId < (ushort)EnumAbilityTaskType.OngoingTaskStart && typeId >= (ushort)EnumAbilityTaskType.PassiveTaskStart)
{
Debug.LogError($"TypeId不是OngoingTask派生的TypeId={typeId}");
return null;
}
return CreateTask(typeId) as OngoingAbilityTask;
}
/// <summary>
/// 通过节点类型创建PassiveAbilityTask实例
/// </summary>
/// <param name="typeId">AbilityTask类型</param>
/// <returns></returns>
public static PassiveAbilityTask CreatePassiveTask(ushort typeId)
{
if (typeId < (ushort)EnumAbilityTaskType.PassiveTaskStart)
{
Debug.LogError($"TypeId不是PassiveTask派生的TypeId={typeId}");
return null;
}
return CreateTask(typeId) as PassiveAbilityTask;
}
/// <summary>
/// 通过节点类型创建AbilityTask实例
/// </summary>
/// <param name="typeId">AbilityTask类型</param>
/// <returns></returns>
public static AbilityTaskBase CreateTask(ushort typeId)
{
if (!s_TypeId2FactoryFunc.ContainsKey(typeId))
{
Debug.LogError($"没有注册的AbilityTask, TypeId={typeId}");
return null;
}
return s_TypeId2FactoryFunc[typeId]();
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 57d9e528d18245f386608d8853b6b8ea
timeCreated: 1729505585

View File

@@ -0,0 +1,15 @@
namespace GAS.Runtime
{
/// <summary>
/// AbilityTask的类型枚举
/// </summary>
public enum EnumAbilityTaskType : ushort
{
InstantTaskStart = 10000, // InstantTask派生的起始Type索引上层派生由此递增
OngoingTaskStart = 20000, // OngoingTask派生的起始Type索引上层派生由此递增
PassiveTaskStart = 30000, // PassiveTask派生的起始Type索引上层派生由此递增
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 57d5671cf20243c1b81d2754324ca1eb
timeCreated: 1729497043

View File

@@ -81,7 +81,7 @@ namespace GAS.Runtime
{
if (modifier.AttributeName == _processedAttribute.Name)
{
var modifierSpec = JexGasObjectPool.Instance.Fetch<ModifierSpec>();
var modifierSpec = _owner.GetManager().ObjectPool.Fetch<ModifierSpec>();
modifierSpec.Init(geSpec, modifier);
_modifierCache.Add(modifierSpec);
TryRegisterAttributeChangedListen(geSpec, modifier);
@@ -105,7 +105,7 @@ namespace GAS.Runtime
foreach (var modifierSpec in _modifierCache)
{
modifierSpec.Release();
JexGasObjectPool.Instance.Recycle(modifierSpec);
_owner.GetManager().ObjectPool.Recycle(modifierSpec);
}
_modifierCache.Clear();
@@ -240,9 +240,9 @@ namespace GAS.Runtime
private void TryUnregisterAttributeChangedListen(GameplayEffectSpec ge, GameplayEffectModifier modifier)
{
if (modifier.MMC is AttributeBasedModCalculation { captureType: AttributeBasedModCalculation.GEAttributeCaptureType.Track } mmc)
if (modifier.MMC is AttributeBasedModCalculation { captureType: GEAttributeCaptureType.Track } mmc)
{
if (mmc.attributeFromType == AttributeBasedModCalculation.AttributeFrom.Target)
if (mmc.attributeFromType == AttributeFrom.Target)
{
if (ge.Owner != null)
ge.Owner.AttributeSetContainer.Sets[mmc.attributeSetName][mmc.attributeShortName]
@@ -259,9 +259,9 @@ namespace GAS.Runtime
private void TryRegisterAttributeChangedListen(GameplayEffectSpec ge, GameplayEffectModifier modifier)
{
if (modifier.MMC is AttributeBasedModCalculation { captureType: AttributeBasedModCalculation.GEAttributeCaptureType.Track } mmc)
if (modifier.MMC is AttributeBasedModCalculation { captureType: GEAttributeCaptureType.Track } mmc)
{
if (mmc.attributeFromType == AttributeBasedModCalculation.AttributeFrom.Target)
if (mmc.attributeFromType == AttributeFrom.Target)
{
if (ge.Owner != null)
ge.Owner.AttributeSetContainer.Sets[mmc.attributeSetName][mmc.attributeShortName]
@@ -286,12 +286,12 @@ namespace GAS.Runtime
{
foreach (var modifierSpec in _modifierCache)
{
if (modifierSpec.Modifier.MMC is not AttributeBasedModCalculation { captureType: AttributeBasedModCalculation.GEAttributeCaptureType.Track } mmc) continue;
if (modifierSpec.Modifier.MMC is not AttributeBasedModCalculation { captureType: GEAttributeCaptureType.Track } mmc) continue;
if (attribute.Name != mmc.attributeName) continue;
var geSpec = modifierSpec.SpecRef.Value;
if (geSpec == null) continue;
if ((mmc.attributeFromType == AttributeBasedModCalculation.AttributeFrom.Target && attribute.Owner == geSpec.Owner) ||
(mmc.attributeFromType == AttributeBasedModCalculation.AttributeFrom.Source && attribute.Owner == geSpec.Source))
if ((mmc.attributeFromType == AttributeFrom.Target && attribute.Owner == geSpec.Owner) ||
(mmc.attributeFromType == AttributeFrom.Source && attribute.Owner == geSpec.Source))
{
return true;
}

View File

@@ -113,7 +113,7 @@ namespace GAS.Runtime
public Dictionary<string, LFloat> Snapshot()
{
var snapshot = JexGasObjectPool.Instance.Fetch<Dictionary<string, LFloat>>();
var snapshot = _owner.GetManager().ObjectPool.Fetch<Dictionary<string, LFloat>>();
foreach (var kv in _attributeSets)
{
var attributeSet = kv.Value;

View File

@@ -2,11 +2,12 @@ using System;
using System.Collections.Generic;
using GAS.General;
using JNGame.Math;
using JNGame.Runtime.GAS;
using UnityEngine;
namespace GAS.Runtime
{
public class AbilitySystemComponent : IAbilitySystemComponent
public class AbilitySystemComponent : IAbilitySystemComponent,IJexGASObject
{
private AbilitySystemComponentPreset preset;
@@ -399,5 +400,20 @@ namespace GAS.Runtime
{
GameplayEffectContainer.ClearGameplayEffect();
}
#if UNITY_EDITOR
private JexGasManager _manager = JexGasManager.Editor;
#else
private JexGasManager _manager = null;
#endif
public JexGasManager GetManager()
{
return _manager;
}
public void SetManager(JexGasManager manager)
{
_manager = manager;
}
}
}

View File

@@ -75,7 +75,7 @@ namespace GAS.Runtime
LFloat level,
object userData = null)
{
var spec = JexGasObjectPool.Instance.Fetch<GameplayEffectSpec>();
var spec = new GameplayEffectSpec();
spec.Awake(this, userData);
spec.Init(creator, owner, level);
return spec;
@@ -87,7 +87,7 @@ namespace GAS.Runtime
/// <returns></returns>
public EntityRef<GameplayEffectSpec> CreateSpec(object userData = null)
{
var spec = JexGasObjectPool.Instance.Fetch<GameplayEffectSpec>();
var spec = new GameplayEffectSpec();
spec.Awake(this, userData);
return spec;
}
@@ -141,7 +141,7 @@ namespace GAS.Runtime
return Array.Empty<GrantedAbilityFromEffect>();
}
var grantedAbilityFromEffects = JexGasObjectPool.Instance.Fetch<List<GrantedAbilityFromEffect>>();
var grantedAbilityFromEffects = new List<GrantedAbilityFromEffect>();
foreach (var grantedAbilityConfig in grantedAbilities)
{
if (grantedAbilityConfig.AbilityAsset != null)
@@ -151,7 +151,7 @@ namespace GAS.Runtime
var ret = GrantedAbilityFromEffectArrayPool.Fetch(grantedAbilityFromEffects.Count);
grantedAbilityFromEffects.CopyTo(ret);
grantedAbilityFromEffects.Clear();
JexGasObjectPool.Instance.Recycle(grantedAbilityFromEffects);
// JexGasObjectPool.Instance.Recycle(grantedAbilityFromEffects);
return ret;
}

View File

@@ -31,6 +31,8 @@ namespace GAS.Runtime
#region Base Info
public string Name => name;
[TitleGroup(GRP_BASE)]
[HorizontalGroup(GRP_BASE_H, Width = 1 - 0.618f)]
[TabGroup(GRP_BASE_H_LEFT, "Summary", SdfIconType.InfoSquareFill, TextColor = "#0BFFC5")]
@@ -320,7 +322,6 @@ namespace GAS.Runtime
bool IsGrantedAbilitiesInvalid() => IsDurationalPolicy() && GrantedAbilities != null && GrantedAbilities.Any(abilityConfig => abilityConfig.AbilityAsset == null);
#region IGameplayEffectData
public string GetDisplayName() => name;
public EffectsDurationPolicy GetDurationPolicy() => DurationPolicy;
@@ -378,16 +379,13 @@ namespace GAS.Runtime
/// <para>缺点: Editor下实时修改GameplayEffectAsset无法实时生效, 因为共享实例一旦创建, 就不会再改变, 可以设置GasRuntimeSettings.DisableGameplayEffectSharedInstance来禁用Editor模式下的SharedInstance</para>
/// </remarks>
/// </summary>
public GameplayEffect SharedInstance
public GameplayEffect SharedInstance()
{
get
{
#if UNITY_EDITOR
if (GasRuntimeSettings.DisableGameplayEffectSharedInstance)
return new GameplayEffect(this);
if (GasRuntimeSettings.DisableGameplayEffectSharedInstance)
return new GameplayEffect(this);
#endif
return _sharedInstance ??= new GameplayEffect(this);
}
return _sharedInstance ??= new GameplayEffect(this);
}
private GameplayEffect _sharedInstance;

View File

@@ -25,7 +25,7 @@ namespace GAS.Runtime
public void Tick(int dt)
{
var gameplayEffectSpecs = JexGasObjectPool.Instance.Fetch<List<GameplayEffectSpec>>();
var gameplayEffectSpecs = _owner.GetManager().ObjectPool.Fetch<List<GameplayEffectSpec>>();
gameplayEffectSpecs.AddRange(_gameplayEffectSpecs);
foreach (var gameplayEffectSpec in gameplayEffectSpecs)
@@ -37,7 +37,7 @@ namespace GAS.Runtime
}
gameplayEffectSpecs.Clear();
JexGasObjectPool.Instance.Recycle(gameplayEffectSpecs);
_owner.GetManager().ObjectPool.Recycle(gameplayEffectSpecs);
}
public void RegisterOnGameplayEffectContainerIsDirty(Action action)
@@ -54,7 +54,7 @@ namespace GAS.Runtime
{
if (tags.Empty) return;
var removeList = JexGasObjectPool.Instance.Fetch<List<GameplayEffectSpec>>();
var removeList = _owner.GetManager().ObjectPool.Fetch<List<GameplayEffectSpec>>();
foreach (var gameplayEffectSpec in _gameplayEffectSpecs)
{
@@ -72,7 +72,7 @@ namespace GAS.Runtime
foreach (var gameplayEffectSpec in removeList) RemoveGameplayEffectSpec(gameplayEffectSpec);
removeList.Clear();
JexGasObjectPool.Instance.Recycle(removeList);
_owner.GetManager().ObjectPool.Recycle(removeList);
}
/// <summary>

View File

@@ -4,7 +4,8 @@ namespace GAS.Runtime
{
public class InstantGameplayEffectData : IGameplayEffectData
{
private string Name { get; }
private string name;
public string Name => name;
public GameplayEffectSnapshotPolicy SnapshotPolicy { get; set; } = GameplayEffectSnapshotPolicy.Specified;
@@ -15,7 +16,7 @@ namespace GAS.Runtime
public GameplayEffectModifier[] Modifiers { get; set; } = Array.Empty<GameplayEffectModifier>();
public GameplayEffectSpecifiedSnapshotConfig[] SpecifiedSnapshotConfigs { get; set; } = Array.Empty<GameplayEffectSpecifiedSnapshotConfig>();
public InstantGameplayEffectData(string name) => Name = name;
public InstantGameplayEffectData(string name) => this.name = name;
public string GetDisplayName() => Name;
@@ -62,6 +63,11 @@ namespace GAS.Runtime
public virtual GrantedAbilityConfig[] GetGrantedAbilities() => Array.Empty<GrantedAbilityConfig>();
public virtual GameplayEffectStacking GetStacking() => GameplayEffectStacking.None;
public GameplayEffect SharedInstance()
{
return null;
}
}
public class InfiniteGameplayEffectData : InstantGameplayEffectData

View File

@@ -37,7 +37,7 @@ namespace GAS.Runtime
Modifiers = GameplayEffect.Modifiers;
if (gameplayEffect.DurationPolicy != EffectsDurationPolicy.Instant)
{
var periodTicker = JexGasObjectPool.Instance.Fetch<GameplayEffectPeriodTicker>();
var periodTicker = new GameplayEffectPeriodTicker();
periodTicker.Awake(this);
// EntityRef之前必须确定InstanceId的值
PeriodTicker = periodTicker;
@@ -62,7 +62,7 @@ namespace GAS.Runtime
if (gameplayEffectPeriodTicker != null)
{
gameplayEffectPeriodTicker.Release();
JexGasObjectPool.Instance.Recycle(gameplayEffectPeriodTicker);
// JexGasObjectPool.Instance.Recycle(gameplayEffectPeriodTicker);
}
PeriodTicker = default;
@@ -80,12 +80,12 @@ namespace GAS.Runtime
if (grantedAbilitySpecFromEffect != null)
{
grantedAbilitySpecFromEffect.Release();
JexGasObjectPool.Instance.Recycle(grantedAbilitySpecFromEffect);
// JexGasObjectPool.Instance.Recycle(grantedAbilitySpecFromEffect);
}
}
GrantedAbilitiesSpecFromEffect.Clear();
JexGasObjectPool.Instance.Recycle(GrantedAbilitiesSpecFromEffect);
// JexGasObjectPool.Instance.Recycle(GrantedAbilitiesSpecFromEffect);
GrantedAbilitiesSpecFromEffect = default;
}
@@ -95,13 +95,13 @@ namespace GAS.Runtime
if (SnapshotSourceAttributes != null)
{
SnapshotSourceAttributes.Clear();
JexGasObjectPool.Instance.Recycle(SnapshotSourceAttributes);
// JexGasObjectPool.Instance.Recycle(SnapshotSourceAttributes);
}
if (SnapshotTargetAttributes != null && SnapshotSourceAttributes != SnapshotTargetAttributes)
{
SnapshotTargetAttributes.Clear();
JexGasObjectPool.Instance.Recycle(SnapshotTargetAttributes);
// JexGasObjectPool.Instance.Recycle(SnapshotTargetAttributes);
}
SnapshotSourceAttributes = null;
@@ -112,14 +112,14 @@ namespace GAS.Runtime
if (_valueMapWithTag != null)
{
_valueMapWithTag.Clear();
JexGasObjectPool.Instance.Recycle(_valueMapWithTag);
// JexGasObjectPool.Instance.Recycle(_valueMapWithTag);
_valueMapWithTag = null;
}
if (_valueMapWithName != null)
{
_valueMapWithName.Clear();
JexGasObjectPool.Instance.Recycle(_valueMapWithName);
// JexGasObjectPool.Instance.Recycle(_valueMapWithName);
_valueMapWithName = null;
}
@@ -129,7 +129,7 @@ namespace GAS.Runtime
OnStackChanged = default;
}
JexGasObjectPool.Instance.Recycle(this);
// JexGasObjectPool.Instance.Recycle(this);
}
public void Init(AbilitySystemComponent source, AbilitySystemComponent owner, LFloat level)
@@ -221,7 +221,8 @@ namespace GAS.Runtime
if (grantedAbilityFromEffects is null) return;
if (grantedAbilityFromEffects.Length == 0) return;
GrantedAbilitiesSpecFromEffect = JexGasObjectPool.Instance.Fetch<List<EntityRef<GrantedAbilitySpecFromEffect>>>();
// GrantedAbilitiesSpecFromEffect = JexGasObjectPool.Instance.Fetch<List<EntityRef<GrantedAbilitySpecFromEffect>>>();
GrantedAbilitiesSpecFromEffect = new List<EntityRef<GrantedAbilitySpecFromEffect>>();
foreach (var grantedAbilityFromEffect in grantedAbilityFromEffects)
{
GrantedAbilitiesSpecFromEffect.Add(grantedAbilityFromEffect.CreateSpec(this));
@@ -237,12 +238,12 @@ namespace GAS.Runtime
if (grantedAbilitySpecFromEffect != null)
{
grantedAbilitySpecFromEffect.Release();
JexGasObjectPool.Instance.Recycle(grantedAbilitySpecFromEffect);
// JexGasObjectPool.Instance.Recycle(grantedAbilitySpecFromEffect);
}
}
GrantedAbilitiesSpecFromEffect.Clear();
JexGasObjectPool.Instance.Recycle(GrantedAbilitiesSpecFromEffect);
// JexGasObjectPool.Instance.Recycle(GrantedAbilitiesSpecFromEffect);
}
public void SetStacking(GameplayEffectStacking stacking)
@@ -317,7 +318,8 @@ namespace GAS.Runtime
ReleaseCueDurationalSpecs();
if (GameplayEffect.CueDurational is { Length: > 0 })
{
_cueDurationalSpecs = JexGasObjectPool.Instance.Fetch<List<GameplayCueDurationalSpec>>();
// _cueDurationalSpecs = JexGasObjectPool.Instance.Fetch<List<GameplayCueDurationalSpec>>();
_cueDurationalSpecs = new List<GameplayCueDurationalSpec>();
foreach (var cueDurational in GameplayEffect.CueDurational)
{
var cueSpec = cueDurational.ApplyFrom(this);
@@ -489,7 +491,8 @@ namespace GAS.Runtime
{
case GameplayEffectSpecifiedSnapshotConfig.ESnapshotTarget.Source:
{
SnapshotSourceAttributes ??= JexGasObjectPool.Instance.Fetch<Dictionary<string, LFloat>>();
// SnapshotSourceAttributes ??= JexGasObjectPool.Instance.Fetch<Dictionary<string, LFloat>>();
SnapshotSourceAttributes ??= new Dictionary<string, LFloat>();
var attribute = Source.AttributeSetContainer.GetAttributeAttributeValue(config.AttributeSetName, config.AttributeShortName);
if (attribute != null)
{
@@ -504,7 +507,8 @@ namespace GAS.Runtime
}
case GameplayEffectSpecifiedSnapshotConfig.ESnapshotTarget.Target:
{
SnapshotTargetAttributes ??= JexGasObjectPool.Instance.Fetch<Dictionary<string, LFloat>>();
// SnapshotTargetAttributes ??= JexGasObjectPool.Instance.Fetch<Dictionary<string, LFloat>>();
SnapshotTargetAttributes ??= new Dictionary<string, LFloat>();
var attribute = Owner.AttributeSetContainer.GetAttributeAttributeValue(config.AttributeSetName, config.AttributeShortName);
if (attribute != null)
{
@@ -542,13 +546,15 @@ namespace GAS.Runtime
public void RegisterValue(in GameplayTag tag, LFloat value)
{
_valueMapWithTag ??= JexGasObjectPool.Instance.Fetch<Dictionary<GameplayTag, LFloat>>();
// _valueMapWithTag ??= JexGasObjectPool.Instance.Fetch<Dictionary<GameplayTag, LFloat>>();
_valueMapWithTag ??= new Dictionary<GameplayTag, LFloat>();
_valueMapWithTag[tag] = value;
}
public void RegisterValue(string name, LFloat value)
{
_valueMapWithName ??= JexGasObjectPool.Instance.Fetch<Dictionary<string, LFloat>>();
// _valueMapWithName ??= JexGasObjectPool.Instance.Fetch<Dictionary<string, LFloat>>();
_valueMapWithName ??= new Dictionary<string, LFloat>();
_valueMapWithName[name] = value;
}
@@ -618,7 +624,7 @@ namespace GAS.Runtime
if (_cueDurationalSpecs != null)
{
_cueDurationalSpecs.Clear();
JexGasObjectPool.Instance.Recycle(_cueDurationalSpecs);
// JexGasObjectPool.Instance.Recycle(_cueDurationalSpecs);
_cueDurationalSpecs = null;
}
}

View File

@@ -113,7 +113,7 @@ namespace GAS.Runtime
overflowEffects = new GameplayEffect[overflowEffectAssets.Length];
for (var i = 0; i < overflowEffectAssets.Length; ++i)
{
overflowEffects[i] = overflowEffectAssets[i].SharedInstance;
overflowEffects[i] = overflowEffectAssets[i].SharedInstance();
}
}

View File

@@ -148,7 +148,7 @@ namespace GAS.Runtime
public GrantedAbilitySpecFromEffect CreateSpec(GameplayEffectSpec sourceEffectSpec)
{
var grantedAbilitySpecFromEffect = JexGasObjectPool.Instance.Fetch<GrantedAbilitySpecFromEffect>();
var grantedAbilitySpecFromEffect = new GrantedAbilitySpecFromEffect();
grantedAbilitySpecFromEffect.Awake(this, sourceEffectSpec);
return grantedAbilitySpecFromEffect;
}

View File

@@ -2,6 +2,11 @@
{
public interface IGameplayEffectData
{
/// <summary>
/// 资源标识对应ScriptableObject的name
/// </summary>
string Name { get; }
string GetDisplayName();
EffectsDurationPolicy GetDurationPolicy();
int GetDuration();
@@ -38,5 +43,16 @@
//Stacking
GameplayEffectStacking GetStacking();
/// <summary>
/// 共享实例, 一个GameplayEffectAsset对应一个共享实例, 首次访问时创建
/// <remarks>
/// <para>优点: 通过共享实例, 可以减少GameplayEffect的实例化次数, 减少内存开销, 同时也可以减少GC的产生, 提高性能</para>
/// <para>缺点: Editor下实时修改GameplayEffectAsset无法实时生效, 因为共享实例一旦创建, 就不会再改变, 可以设置GasRuntimeSettings.DisableGameplayEffectSharedInstance来禁用Editor模式下的SharedInstance</para>
/// </remarks>
/// </summary>
public GameplayEffect SharedInstance();
}
}

View File

@@ -0,0 +1,45 @@
namespace GAS.Runtime
{
/// <summary>
/// 属性采样来源类型枚举
/// </summary>
public enum AttributeFrom : byte
{
#if UNITY_EDITOR
[Sirenix.OdinInspector.LabelText("来源(Source)", Sirenix.OdinInspector.SdfIconType.Magic)]
#endif
Source,
#if UNITY_EDITOR
[Sirenix.OdinInspector.LabelText("目标(Target)", Sirenix.OdinInspector.SdfIconType.Person)]
#endif
Target
}
/// <summary>
/// 属性捕获类型枚举
/// </summary>
public enum GEAttributeCaptureType : byte
{
#if UNITY_EDITOR
[Sirenix.OdinInspector.LabelText("快照(SnapShot)", Sirenix.OdinInspector.SdfIconType.Camera)]
#endif
SnapShot,
#if UNITY_EDITOR
[Sirenix.OdinInspector.LabelText("实时(Track)", Sirenix.OdinInspector.SdfIconType.Speedometer2)]
#endif
Track
}
public enum EnumMMCType : ushort
{
PureAttrBasedWithStackModCalculation = 1,
PureAttributeBasedModCalculation = 2,
PureScalableFloatModCalculation = 3,
PureStackModCalculation = 4,
EnumBuiltinCount = 10,
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: a5952d6cd83f4e0db54536fb85503d13
timeCreated: 1729498418

View File

@@ -0,0 +1,73 @@
using JNGame.Math;
using Sirenix.OdinInspector;
using UnityEngine;
namespace GAS.Runtime
{
/// <summary>
/// 基于属性混合GE堆栈的MMC
/// </summary>
[CreateAssetMenu(fileName = "AttrBasedWithStackModCalculation", menuName = "GAS/MMC/AttrBasedWithStackModCalculation")]
public class PureAttrBasedWithStackModCalculation : PureAttributeBasedModCalculation
{
public enum StackMagnitudeOperation
{
Add,
Multiply
}
[InfoBox(" 公式StackCount * sK + sB")]
[TabGroup("Default", "AttributeBasedModCalculation")]
[Title("堆叠幅值计算")]
[LabelText("系数(sK)")]
public LFloat sK = 1;
[TabGroup("Default", "AttributeBasedModCalculation")]
[LabelText("常量(sB)")]
public LFloat sB = 0;
[TabGroup("Default", "AttributeBasedModCalculation")]
[Title("最终结果")]
[InfoBox(" 最终公式: \n" +
"Add:(AttributeValue * k + b)+(StackCount * sK + sB); \n" +
"Multiply:(AttributeValue * k + b)*(StackCount * sK + sB)")]
[LabelText("Stack幅值与Attr幅值计算方式")]
public StackMagnitudeOperation stackMagnitudeOperation;
[TabGroup("Default", "AttributeBasedModCalculation")]
[LabelText("最终公式")]
[ShowInInspector]
[DisplayAsString(TextAlignment.Left, true)]
public string FinalFormulae
{
get
{
var formulae = stackMagnitudeOperation switch
{
StackMagnitudeOperation.Add => $"({attributeName} * {k} + {b}) + (StackCount * {sK} + {sB})",
StackMagnitudeOperation.Multiply => $"({attributeName} * {k} + {b}) * (StackCount * {sK} + {sB})",
_ => ""
};
return $"<size=15><b><color=green>{formulae}</color></b></size>";
}
}
public override LFloat CalculateMagnitude(GameplayEffectSpec spec, LFloat modifierMagnitude)
{
var attrMagnitude = base.CalculateMagnitude(spec, modifierMagnitude);
if (spec.Stacking.stackingType == StackingType.None) return attrMagnitude;
var stackMagnitude = spec.StackCount * sK + sB;
return stackMagnitudeOperation switch
{
StackMagnitudeOperation.Add => attrMagnitude + stackMagnitude,
StackMagnitudeOperation.Multiply => attrMagnitude * stackMagnitude,
_ => attrMagnitude + stackMagnitude
};
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 6b7892b02c5a49f3a56e7ca1215086c3
timeCreated: 1729498090

View File

@@ -0,0 +1,136 @@
using System.Linq;
using JNGame.Math;
using Sirenix.OdinInspector;
using UnityEngine;
namespace GAS.Runtime
{
[CreateAssetMenu(fileName = "AttributeBasedModCalculation", menuName = "GAS/MMC/AttributeBasedModCalculation")]
public class PureAttributeBasedModCalculation : PureModifierMagnitudeCalculation
{
public enum AttributeFrom
{
[LabelText("来源(Source)", SdfIconType.Magic)]
Source,
[LabelText("目标(Target)", SdfIconType.Person)]
Target
}
public enum GEAttributeCaptureType
{
[LabelText("快照(SnapShot)", SdfIconType.Camera)]
SnapShot,
[LabelText("实时(Track)", SdfIconType.Speedometer2)]
Track
}
[TabGroup("Default", "AttributeBasedModCalculation", SdfIconType.PersonBoundingBox, TextColor = "blue")]
[InfoBox(" 以什么方式(Capture Type)从谁身上(Attribute From)捕获哪个属性的值(Attribute Name)。")]
[EnumToggleButtons]
[LabelText("捕获方式(Capture Type)")]
public GEAttributeCaptureType captureType;
[TabGroup("Default", "AttributeBasedModCalculation")]
[EnumToggleButtons]
[LabelText("捕获目标(Attribute From)")]
public AttributeFrom attributeFromType;
[TabGroup("Default", "AttributeBasedModCalculation")]
[ValueDropdown("@ValueDropdownHelper.AttributeChoices", IsUniqueList = true)]
[LabelText("属性的名称(Attribute Name)")]
[OnValueChanged("@OnAttributeNameChanged()")]
[ValidateInput("@AttributeValidator.IsValidAttributeName($value)", "属性名无效")]
public string attributeName;
[TabGroup("Default", "Details", SdfIconType.Bug, TextColor = "orange")]
[ReadOnly]
public string attributeSetName;
[TabGroup("Default", "Details")]
[ReadOnly]
public string attributeShortName;
[InfoBox("计算逻辑与ScalableLFloatModCalculation一致, 公式AttributeValue * k + b")]
[TabGroup("Default", "AttributeBasedModCalculation")]
[LabelText("系数(k)")]
public LFloat k = 1;
[TabGroup("Default", "AttributeBasedModCalculation")]
[LabelText("常量(b)")]
public LFloat b = 0;
public override LFloat CalculateMagnitude(GameplayEffectSpec spec, LFloat modifierMagnitude)
{
LFloat attributeValue;
if (attributeFromType == AttributeFrom.Source)
{
if (captureType == GEAttributeCaptureType.SnapShot)
{
var snapShot = spec.SnapshotSourceAttributes;
if (snapShot == null || snapShot.TryGetValue(attributeName, out attributeValue) == false)
{
Debug.LogError($"Source snapshot Attribute '{attributeName}' not found in source snapshot for spec: '{spec.GameplayEffect.GameplayEffectName}'.");
attributeValue = 1;
}
}
else
{
var attributeCurrentValue = spec.Source.GetAttributeCurrentValue(attributeSetName, attributeShortName);
if (attributeCurrentValue == null)
{
Debug.LogError($"Source Attribute '{attributeName}' not found in source for spec: '{spec.GameplayEffect.GameplayEffectName}'.");
attributeValue = 1;
}
else
{
attributeValue = attributeCurrentValue.Value;
}
}
}
else
{
if (captureType == GEAttributeCaptureType.SnapShot)
{
var snapShot = spec.SnapshotTargetAttributes;
if (snapShot == null || snapShot.TryGetValue(attributeName, out attributeValue) == false)
{
Debug.LogError($"Target snapshot Attribute '{attributeName}' not found in target snapshot for spec: '{spec.GameplayEffect.GameplayEffectName}'.");
attributeValue = 1;
}
}
else
{
var attributeCurrentValue = spec.Owner.GetAttributeCurrentValue(attributeSetName, attributeShortName);
if (attributeCurrentValue == null)
{
Debug.LogError($"Source Attribute '{attributeName}' not found in source for spec: '{spec.GameplayEffect.GameplayEffectName}'.");
attributeValue = 1;
}
else
{
attributeValue = attributeCurrentValue.Value;
}
}
}
return attributeValue * k + b;
}
private void OnAttributeNameChanged()
{
if (!string.IsNullOrWhiteSpace(attributeName))
{
var split = attributeName.Split('.');
attributeSetName = split[0];
attributeShortName = split[1];
}
else
{
attributeSetName = null;
attributeShortName = null;
}
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 74fb43f815744dac9bcc44b7ae35549d
timeCreated: 1729498090

View File

@@ -0,0 +1,59 @@
using System.Linq;
using GAS.General;
using JNGame.Math;
using Sirenix.OdinInspector;
using UnityEngine;
namespace GAS.Runtime
{
public abstract class PureModifierMagnitudeCalculation : ScriptableObject,IModifierMagnitudeCalculation
{
public virtual ushort TypeId => 0;
protected const int WIDTH_LABEL = 70;
[TitleGroup("Base")]
[HorizontalGroup("Base/H1", width: 1 - 0.618f)]
[TabGroup("Base/H1/V1", "Summary", SdfIconType.InfoSquareFill, TextColor = "#0BFFC5", Order = 1)]
[HideLabel]
[MultiLineProperty(10)]
public string Description;
#if UNITY_EDITOR
[TabGroup("Base/H1/V2", "General", SdfIconType.AwardFill, TextColor = "#FF7F00", Order = 2)]
[TabGroup("Base/H1/V2", "Detail", SdfIconType.TicketDetailedFill, TextColor = "#BC2FDE")]
[LabelText("类型名称", SdfIconType.FileCodeFill)]
[LabelWidth(WIDTH_LABEL)]
[ShowInInspector]
[PropertyOrder(-1)]
public string TypeName => GetType().Name;
[TabGroup("Base/H1/V2", "Detail")]
[LabelText("类型全名", SdfIconType.FileCodeFill)]
[LabelWidth(WIDTH_LABEL)]
[ShowInInspector]
[PropertyOrder(-1)]
public string TypeFullName => GetType().FullName;
[TabGroup("Base/H1/V2", "Detail")]
[ListDrawerSettings(ShowFoldout = true, ShowItemCount = false, ShowPaging = false)]
[ShowInInspector]
[LabelText("继承关系")]
[LabelWidth(WIDTH_LABEL)]
[PropertyOrder(-1)]
public string[] InheritanceChain => GetType().GetInheritanceChain().Reverse().ToArray();
#endif
public abstract LFloat CalculateMagnitude(GameplayEffectSpec spec, LFloat modifierMagnitude);
#if UNITY_EDITOR
private void OnValidate()
{
// if(Application.isPlaying) return;
// EditorUtility.SetDirty(this);
// AssetDatabase.SaveAssets();
// AssetDatabase.Refresh();
}
#endif
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 38469c588420428dbd16a6fda9439591
timeCreated: 1729498090

View File

@@ -0,0 +1,25 @@
using JNGame.Math;
using Sirenix.OdinInspector;
using UnityEngine;
namespace GAS.Runtime
{
[CreateAssetMenu(fileName = "ScalableLFloatModCalculation", menuName = "GAS/MMC/ScalableLFloatModCalculation")]
public class PureScalableLFloatModCalculation : PureModifierMagnitudeCalculation
{
private const string Desc = "计算公式ModifierMagnitude * k + b";
private const string Detail =
"ScalableLFloatModCalculation可缩放浮点数计算\n该类型是根据Magnitude计算Modifier模值的计算公式为ModifierMagnitude * k + b 实际上就是一个线性函数k和b为可编辑参数可以在编辑器中设置。";
[DetailedInfoBox(Desc, Detail, InfoMessageType.Info)] [SerializeField]
private LFloat k = LFloat.L1;
[SerializeField] private LFloat b = LFloat.L0;
public override LFloat CalculateMagnitude(GameplayEffectSpec spec, LFloat input)
{
return input * k + b;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 062e7b5a35be434b839d3d2ecbab97a8
timeCreated: 1729498090

View File

@@ -0,0 +1,19 @@
using JNGame.Math;
using UnityEngine;
namespace GAS.Runtime
{
[CreateAssetMenu(fileName = "SetByCallerFromName", menuName = "GAS/MMC/SetByCallerFromNameModCalculation")]
public class PureSetByCallerFromNameModCalculation : PureModifierMagnitudeCalculation
{
[SerializeField] private string valueName;
public override LFloat CalculateMagnitude(GameplayEffectSpec spec,LFloat input)
{
var value = spec.GetMapValue(valueName);
#if UNITY_EDITOR
if(value==null) Debug.LogWarning($"[EX] SetByCallerModCalculation: GE's '{valueName}' value(name map) is not set");
#endif
return value ?? 0;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: ab0276bbb7c8483cbde7d5a2708b4585
timeCreated: 1729498090

View File

@@ -0,0 +1,24 @@
using JNGame.Math;
using Sirenix.OdinInspector;
using UnityEngine;
namespace GAS.Runtime
{
[CreateAssetMenu(fileName = "SetByCallerFromTag", menuName = "GAS/MMC/SetByCallerFromTagModCalculation")]
public class PureSetByCallerFromTagModCalculation : PureModifierMagnitudeCalculation
{
[SerializeField]
[ValueDropdown("@ValueDropdownHelper.GameplayTagChoices", HideChildProperties = true)]
private GameplayTag _tag;
public override LFloat CalculateMagnitude(GameplayEffectSpec spec, LFloat input)
{
var value = spec.GetMapValue(_tag);
#if UNITY_EDITOR
if (value == null)
Debug.LogWarning($"[EX] SetByCallerModCalculation: GE's '{_tag.Name}' value(tag map) is not set");
#endif
return value ?? 0;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 0394869df5504d90bc580383dbbc7289
timeCreated: 1729498090

View File

@@ -0,0 +1,27 @@
using JNGame.Math;
using Sirenix.OdinInspector;
using UnityEngine;
namespace GAS.Runtime
{
[CreateAssetMenu( fileName = "StackModCalculation", menuName = "GAS/MMC/StackModCalculation" )]
public class PureStackModCalculation : PureModifierMagnitudeCalculation
{
[InfoBox("计算逻辑与ScalableLFloatModCalculation一致, 公式:(StackCount) * k + b")]
[TabGroup("Default", "StackModCalculation")]
[LabelText("系数(k)")]
public LFloat k = 1;
[TabGroup("Default", "StackModCalculation")]
[LabelText("常量(b)")]
public LFloat b = 0;
public override LFloat CalculateMagnitude(GameplayEffectSpec spec, LFloat modifierMagnitude)
{
if (spec.Stacking.stackingType == StackingType.None) return 0;
var stackCount = spec.StackCount;
return stackCount * k + b;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 7acf84e0af1440a7bd995578f44a4ce7
timeCreated: 1729498090

View File

@@ -0,0 +1,12 @@
using GAS.Runtime;
namespace JNGame.Runtime.GAS
{
public interface IJexGASObject
{
public JexGasManager GetManager();
public void SetManager(JexGasManager manager);
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 878812783d9a43eaa7da120f0eac8f78
timeCreated: 1729480508

View File

@@ -17,6 +17,7 @@ namespace GAS.Runtime
public JexGasManager()
{
ObjectPool = new JexGasObjectPool(this);
#if UNITY_EDITOR
//预览GAS
Editor = this;
@@ -31,7 +32,7 @@ namespace GAS.Runtime
/// <summary>
/// GAS 专用对象池 (只限制当前管理器)
/// </summary>
private JexGasObjectPool ObjectPool = new JexGasObjectPool();
public JexGasObjectPool ObjectPool { get; private set; }
//GAS 更新
public void Update(int dt)
@@ -39,7 +40,7 @@ namespace GAS.Runtime
Profiler.BeginSample($"{nameof(JexGasManager)}::Tick()");
var abilitySystemComponents = JexGasObjectPool.Instance.Fetch<List<AbilitySystemComponent>>();
var abilitySystemComponents = ObjectPool.Fetch<List<AbilitySystemComponent>>();
abilitySystemComponents.AddRange(AbilitySystemComponents);
foreach (var abilitySystemComponent in abilitySystemComponents)
@@ -48,7 +49,7 @@ namespace GAS.Runtime
}
abilitySystemComponents.Clear();
JexGasObjectPool.Instance.Recycle(abilitySystemComponents);
ObjectPool.Recycle(abilitySystemComponents);
Profiler.EndSample();
@@ -77,16 +78,11 @@ namespace GAS.Runtime
/// 创建 AbilitySystemComponent
/// </summary>
/// <returns></returns>
public T CreateAbilitySystemComponent<T>(AbilitySystemComponentPreset ascPreset,int level = 1) where T : AbilitySystemComponent, new()
public T CreateAbilitySystemComponent<T>() where T : AbilitySystemComponent, new()
{
var asc = new T();
asc.OnCreate();
asc.SetPreset(ascPreset);
asc.SetLevel(level);
Register(asc);
return asc;
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 29fcc5027c714f648f896f1fdb3dd65a
timeCreated: 1729497471

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 8f55f838e9004c68a22984dbf2aa59fb
timeCreated: 1729497482

View File

@@ -0,0 +1,69 @@
using System;
namespace GAS.Runtime
{
/// <summary>
/// Ability基础配置数据接口
/// </summary>
public interface IAbilityAsset
{
string Name { get; }
/// <summary>
/// Ability唯一标识字符串
/// </summary>
string UniqueName { get; }
/// <summary>
/// Ability的消耗GE配置
/// </summary>
IGameplayEffectData Cost { get; }
/// <summary>
/// Ability的冷却效果
/// </summary>
IGameplayEffectData Cooldown { get; }
/// <summary>
/// Ability的冷却时长单位毫秒
/// </summary>
int CooldownTime { get; }
/// <summary>
/// 描述性质的标签用来描述Ability的特性表现比如伤害、治疗、控制等。
/// </summary>
GameplayTag[] AssetTags { get; }
/// <summary>
/// Ability激活时Ability持有者当前持有的所有Ability中拥有【任意】这些标签的Ability会被取消。
/// </summary>
GameplayTag[] CancelAbilityTags { get; }
/// <summary>
/// Ability激活时Ability持有者当前持有的所有Ability中拥有【任意】这些标签的Ability会被阻塞激活。
/// </summary>
GameplayTag[] BlockAbilityTags { get; }
/// <summary>
/// Ability激活时持有者会获得这些标签Ability被失活时这些标签也会被移除。
/// </summary>
GameplayTag[] ActivationOwnedTags { get; }
/// <summary>
/// Ability只有在其拥有者拥有【所有】这些标签时才可激活。
/// </summary>
GameplayTag[] ActivationRequiredTags { get; }
/// <summary>
/// Ability在其拥有者拥有【任意】这些标签时不能被激活。
/// </summary>
GameplayTag[] ActivationBlockedTags { get; }
/// <summary>
/// 获取运行时的Ability类型
/// </summary>
/// <returns></returns>
Type AbilityType();
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 3c3c0cb099744f90af5faaefac71bfba
timeCreated: 1729499278

View File

@@ -0,0 +1,20 @@
using JNGame.Math;
namespace GAS.Runtime
{
public interface IModifierMagnitudeCalculation
{
/// <summary>
/// Modifier的类型Id
/// </summary>
ushort TypeId { get; }
/// <summary>
/// 属性计算
/// </summary>
/// <param name="spec"></param>
/// <param name="modifierMagnitude"></param>
/// <returns></returns>
LFloat CalculateMagnitude(GameplayEffectSpec spec, LFloat modifierMagnitude);
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 6e92e5303b6443c0a36218b3bfc7ae77
timeCreated: 1729497485

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 77b9750491334df1822a19708b3b13e8
timeCreated: 1729505134

View File

@@ -0,0 +1,46 @@
using System;
using JNGame.Serialization;
namespace GAS.Runtime
{
public abstract class PureAbilityAsset : IAbilityAsset,ISerializable
{
protected const int WIDTH_LABEL = 70;
public string m_Name;
public string m_UniqueName;
public IGameplayEffectData m_Cost;
public IGameplayEffectData m_Cooldown;
public int m_CooldownTime;
public GameplayTag[] m_AssetTags;
public GameplayTag[] m_CancelAbilityTags;
public GameplayTag[] m_BlockAbilityTags;
public GameplayTag[] m_ActivationOwnedTags;
public GameplayTag[] m_ActivationRequiredTags;
public GameplayTag[] m_ActivationBlockedTags;
public string Name => m_Name;
public string UniqueName => m_UniqueName;
public IGameplayEffectData Cost => m_Cost;
public IGameplayEffectData Cooldown => m_Cooldown;
public int CooldownTime => m_CooldownTime;
public GameplayTag[] AssetTags => m_AssetTags;
public GameplayTag[] CancelAbilityTags => m_CancelAbilityTags;
public GameplayTag[] BlockAbilityTags => m_BlockAbilityTags;
public GameplayTag[] ActivationOwnedTags => m_ActivationOwnedTags;
public GameplayTag[] ActivationRequiredTags => m_ActivationRequiredTags;
public GameplayTag[] ActivationBlockedTags => m_ActivationBlockedTags;
public abstract Type AbilityType();
public void Serialize(Serializer writer)
{
}
public void Deserialize(Deserializer reader)
{
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 15fd65bc8eb34108a617f535c2e4ee66
timeCreated: 1729503254

View File

@@ -157,7 +157,7 @@ namespace GAS.Runtime
}
else
{
var list = JexGasObjectPool.Instance.Fetch<List<object>>();
var list = _owner.GetManager().ObjectPool.Fetch<List<object>>();
list.Add(source);
_dynamicAddedTags.Add(tag, list);
}
@@ -172,7 +172,7 @@ namespace GAS.Runtime
if (_dynamicAddedTags.TryGetValue(tag, out var addedTag))
{
addedTag.Clear();
JexGasObjectPool.Instance.Recycle(addedTag);
_owner.GetManager().ObjectPool.Recycle(addedTag);
dirty = _dynamicAddedTags.Remove(tag);
}
@@ -184,7 +184,7 @@ namespace GAS.Runtime
}
else
{
var list = JexGasObjectPool.Instance.Fetch<List<object>>();
var list = _owner.GetManager().ObjectPool.Fetch<List<object>>();
list.Add(source);
_dynamicRemovedTags.Add(tag, list);
}
@@ -205,7 +205,7 @@ namespace GAS.Runtime
dirty = tagList.Count == 0;
if (dirty)
{
JexGasObjectPool.Instance.Recycle(tagList);
_owner.GetManager().ObjectPool.Recycle(tagList);
dynamicTag.Remove(tag);
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 5b06cadfa1714076bafde3b55634aa54
timeCreated: 1729504568

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: b2cace2b74934df1ba47e6682854751c
timeCreated: 1729504662

View File

@@ -8,18 +8,31 @@ using UnityEngine.Serialization;
namespace GAS.Runtime
{
public abstract class AbilityAsset : ScriptableObject
public abstract class AbilityAsset : ScriptableObject,IAbilityAsset
{
protected const int WIDTH_LABEL = 70;
public abstract Type AbilityType();
public string Name => name;
public string UniqueName => uniqueName;
public IGameplayEffectData Cost => cost;
public IGameplayEffectData Cooldown => cooldown;
public int CooldownTime => cooldownTime;
public GameplayTag[] AssetTags => assetTags;
public GameplayTag[] CancelAbilityTags => cancelAbilityTags;
public GameplayTag[] BlockAbilityTags => blockAbilityTags;
public GameplayTag[] ActivationOwnedTags => activationOwnedTags;
public GameplayTag[] ActivationRequiredTags => activationRequiredTags;
public GameplayTag[] ActivationBlockedTags => activationBlockedTags;
[TitleGroup("Base")]
[HorizontalGroup("Base/H1", Width = 1 - 0.618f)]
[TabGroup("Base/H1/V1", "Summary", SdfIconType.InfoSquareFill, TextColor = "#0BFFC5", Order = 1)]
[HideLabel]
[MultiLineProperty(10)]
public string Description;
[FormerlySerializedAs("Description")]
public string description;
[TabGroup("Base/H1/V2", "General", SdfIconType.AwardFill, TextColor = "#FF7F00", Order = 2)]
[LabelText("所属能力", SdfIconType.FileCodeFill)]
@@ -59,86 +72,93 @@ namespace GAS.Runtime
[LabelText("U-Name", SdfIconType.Fingerprint)]
[LabelWidth(WIDTH_LABEL)]
[ValidateInput("@GAS.General.Validation.Validations.IsValidVariableName($value)", "无效的名字 - 不符合C#标识符命名规则")]
[InlineButton("@UniqueName = name", "Auto", Icon = SdfIconType.Hammer)]
public string UniqueName;
[FormerlySerializedAs("UniqueName")]
public string uniqueName;
[TabGroup("Base/H1/V2", "General")]
[Title("消耗&冷却", bold: true)]
[LabelWidth(WIDTH_LABEL)]
[AssetSelector]
[LabelText(SdfIconType.HeartHalf, Text = GASTextDefine.ABILITY_EFFECT_COST)]
public GameplayEffectAsset Cost;
[FormerlySerializedAs("Cost")]
public GameplayEffectAsset cost;
[TabGroup("Base/H1/V2", "General")]
[LabelWidth(WIDTH_LABEL)]
[AssetSelector]
[LabelText(SdfIconType.StopwatchFill, Text = GASTextDefine.ABILITY_EFFECT_CD)]
public GameplayEffectAsset Cooldown;
[FormerlySerializedAs("Cooldown")]
public GameplayEffectAsset cooldown;
[TabGroup("Base/H1/V2", "General")]
[LabelWidth(WIDTH_LABEL)]
[LabelText(SdfIconType.ClockFill, Text = GASTextDefine.ABILITY_CD_TIME)]
[Unit(Units.Millisecond)]
public int CooldownTime;
[FormerlySerializedAs("CooldownTime")]
public int cooldownTime;
// Tags
[TabGroup("Base/H1/V3", "Tags", SdfIconType.TagsFill, TextColor = "#45B1FF", Order = 3)]
[ListDrawerSettings(ShowFoldout = true, ShowItemCount = false, DraggableItems = false)]
[DisableContextMenu(disableForMember: false, disableCollectionElements: true)]
[CustomContextMenu("排序", "@AssetTags = TagHelper.Sort($value)")]
// [CustomContextMenu("排序", "@AssetTags = TagHelper.Sort($value)")]
[ValueDropdown("@ValueDropdownHelper.GameplayTagChoices", IsUniqueList = true, HideChildProperties = true)]
[Tooltip("描述性质的标签用来描述Ability的特性表现比如伤害、治疗、控制等。")]
[FormerlySerializedAs("AssetTag")]
public GameplayTag[] AssetTags;
[FormerlySerializedAs("AssetTags")]
public GameplayTag[] assetTags;
[Space]
[TabGroup("Base/H1/V3", "Tags")]
[ListDrawerSettings(ShowFoldout = true, ShowItemCount = false, DraggableItems = false)]
[DisableContextMenu(disableForMember: false, disableCollectionElements: true)]
[CustomContextMenu("排序", "@CancelAbilityTags = TagHelper.Sort($value)")]
// [CustomContextMenu("排序", "@CancelAbilityTags = TagHelper.Sort($value)")]
[ValueDropdown("@ValueDropdownHelper.GameplayTagChoices", IsUniqueList = true, HideChildProperties = true)]
[LabelText("CancelAbility With Tags ")]
[Tooltip("Ability激活时Ability持有者当前持有的所有Ability中拥有【任意】这些标签的Ability会被取消。")]
public GameplayTag[] CancelAbilityTags;
[FormerlySerializedAs("CancelAbilityTags")]
public GameplayTag[] cancelAbilityTags;
[Space]
[TabGroup("Base/H1/V3", "Tags")]
[ListDrawerSettings(ShowFoldout = true, ShowItemCount = false, DraggableItems = false)]
[DisableContextMenu(disableForMember: false, disableCollectionElements: true)]
[CustomContextMenu("排序", "@BlockAbilityTags = TagHelper.Sort($value)")]
// [CustomContextMenu("排序", "@BlockAbilityTags = TagHelper.Sort($value)")]
[ValueDropdown("@ValueDropdownHelper.GameplayTagChoices", IsUniqueList = true, HideChildProperties = true)]
[LabelText("BlockAbility With Tags ")]
[Tooltip("Ability激活时Ability持有者当前持有的所有Ability中拥有【任意】这些标签的Ability会被阻塞激活。")]
public GameplayTag[] BlockAbilityTags;
[FormerlySerializedAs("BlockAbilityTags")]
public GameplayTag[] blockAbilityTags;
[Space]
[TabGroup("Base/H1/V3", "Tags")]
[ListDrawerSettings(ShowFoldout = true, ShowItemCount = false, DraggableItems = false)]
[DisableContextMenu(disableForMember: false, disableCollectionElements: true)]
[CustomContextMenu("排序", "@ActivationOwnedTags = TagHelper.Sort($value)")]
// [CustomContextMenu("排序", "@ActivationOwnedTags = TagHelper.Sort($value)")]
[ValueDropdown("@ValueDropdownHelper.GameplayTagChoices", IsUniqueList = true, HideChildProperties = true)]
[Tooltip("Ability激活时持有者会获得这些标签Ability被失活时这些标签也会被移除。")]
[FormerlySerializedAs("ActivationOwnedTag")]
public GameplayTag[] ActivationOwnedTags;
public GameplayTag[] activationOwnedTags;
[Space]
[TabGroup("Base/H1/V3", "Tags")]
[ListDrawerSettings(ShowFoldout = true, ShowItemCount = false, DraggableItems = false)]
[DisableContextMenu(disableForMember: false, disableCollectionElements: true)]
[CustomContextMenu("排序", "@ActivationRequiredTags = TagHelper.Sort($value)")]
// [CustomContextMenu("排序", "@ActivationRequiredTags = TagHelper.Sort($value)")]
[ValueDropdown("@ValueDropdownHelper.GameplayTagChoices", IsUniqueList = true, HideChildProperties = true)]
[Tooltip("Ability只有在其拥有者拥有【所有】这些标签时才可激活。")]
public GameplayTag[] ActivationRequiredTags;
[FormerlySerializedAs("ActivationRequiredTags")]
public GameplayTag[] activationRequiredTags;
[Space]
[TabGroup("Base/H1/V3", "Tags")]
[ListDrawerSettings(ShowFoldout = true, ShowItemCount = false, DraggableItems = false)]
[DisableContextMenu(disableForMember: false, disableCollectionElements: true)]
[CustomContextMenu("排序", "@ActivationBlockedTags = TagHelper.Sort($value)")]
// [CustomContextMenu("排序", "@ActivationBlockedTags = TagHelper.Sort($value)")]
[ValueDropdown("@ValueDropdownHelper.GameplayTagChoices", IsUniqueList = true, HideChildProperties = true)]
[Tooltip("Ability在其拥有者拥有【任意】这些标签时不能被激活。")]
public GameplayTag[] ActivationBlockedTags;
[FormerlySerializedAs("ActivationBlockedTags")]
public GameplayTag[] activationBlockedTags;
// public GameplayTag[] SourceRequiredTags;
// public GameplayTag[] SourceBlockedTags;
// public GameplayTag[] TargetRequiredTags;
@@ -146,11 +166,11 @@ namespace GAS.Runtime
}
public abstract class AbilityAssetT<T> : AbilityAsset where T : class
{
public sealed override Type AbilityType()
{
return typeof(T);
}
}
// public abstract class AbilityAssetT<T> : AbilityAsset where T : class
// {
// public sealed override Type AbilityType()
// {
// return typeof(T);
// }
// }
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 86bcaa66216445e19e861ed7d4c980ba
timeCreated: 1729505774

View File

@@ -167,7 +167,7 @@ namespace GAS.Runtime
{
startFrame = clipEvent.startFrame,
endFrame = clipEvent.EndFrame,
buff = clipEvent.gameplayEffect.SharedInstance,
buff = clipEvent.gameplayEffect.SharedInstance(),
buffSpec = default
};
_cacheBuffGameplayEffectTrack.Add(runtimeBuffClip);
@@ -319,7 +319,7 @@ namespace GAS.Runtime
{
foreach (var gea in mark.gameplayEffectAssets)
{
var ge = gea.SharedInstance;
var ge = gea.SharedInstance();
_abilitySpec.Owner.ApplyGameplayEffectTo(ge, asc);
}
}

View File

@@ -1,11 +1,10 @@
using System;
using System.Collections.Generic;
using GAS.Runtime;
namespace GAS.Runtime
{
[Serializable]
public class InstantCueTrackData:TrackDataBase
public class InstantCueTrackData : TrackDataBase
{
public List<InstantCueMarkEvent> markEvents = new List<InstantCueMarkEvent>();

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 9230cd6f3c114761b2b515646df8dfda
timeCreated: 1729504843

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 7e648b1c47094c0b82684f11e0851160
timeCreated: 1729504879

Some files were not shown because too many files have changed in this diff Show More