1.分析游戏中的Buff系统
2.Buff系统的类结构
3.游戏中存在很多种buff, 是否需要创建不同的buff实体
1.分析游戏中的Buff系统
csharp
复制代码
a.Buff系统的类结构
b.游戏中存在很多种buff, 是否需要创建不同的buff实体
2.Buff系统的类结构
csharp
复制代码
将Buff分为三个部分: 数据, 行为, 表现
a.Buff数据(BuffData): 定义Buff的静态属性, 如BuffID、持续时间、效果类型、效果值等; 这些数据可以从配置表读取
b.Buff实例(BuffInstance): 每个Buff在角色身上的一个实例, 它包含动态数据, 如剩余时间、层数等, 并持有对BuffData
的引用
c.Buff行为(BuffBehavior): 负责Buff的效果逻辑, 如应用效果、移除效果、定时更新等; 这部分可以放在BuffInstance中
也可以分离出来
d.Buff表现(BuffView): 负责Buff的视觉和听觉表现, 如特效、音效等; 这部分应该与行为分离, 通过监听Buff的状态变化
来触发表现
csharp
复制代码
// Buff事件系统
public class BuffEvent
{
public static event Action<Buff, GameObject> OnBuffApply;
public static event Action<Buff, GameObject> OnBuffRefresh;
public static event Action<Buff, GameObject> OnBuffRemove;
public static event Action<Buff, GameObject> OnBuffExpire;
public static void TriggerApply(Buff buff, GameObject target)
=> OnBuffApply?.Invoke(buff, target);
// ... 其他触发方法
}
// 简化的Buff基类
public abstract class Buff
{
public BuffData Data { get; protected set; }
public virtual void Apply(GameObject target)
{
// 业务逻辑
BuffEvent.TriggerApply(this, target);
}
public virtual void Remove(GameObject target)
{
// 业务逻辑
BuffEvent.TriggerRemove(this, target);
}
}
// 独立的Buff表现控制器
public class BuffVisualController : MonoBehaviour
{
private Dictionary<Buff, GameObject> activeVisuals = new Dictionary<Buff, GameObject>();
private void OnEnable()
{
BuffEvent.OnBuffApply += OnBuffApplied;
BuffEvent.OnBuffRemove += OnBuffRemoved;
BuffEvent.OnBuffRefresh += OnBuffRefreshed;
}
private void OnDisable()
{
BuffEvent.OnBuffApply -= OnBuffApplied;
BuffEvent.OnBuffRemove -= OnBuffRemoved;
BuffEvent.OnBuffRefresh -= OnBuffRefreshed;
}
private void OnBuffApplied(Buff buff, GameObject target)
{
// 播放获得特效
PlayOneShotEffect(buff.Data.applyEffect, target.transform);
// 开始持续特效
if(buff.Data.loopEffect != null)
{
var effect = Instantiate(buff.Data.loopEffect, target.transform);
activeVisuals[buff] = effect;
}
// 更新UI图标等
UIManager.Instance.ShowBuffIcon(buff);
}
private void OnBuffRemoved(Buff buff, GameObject target)
{
// 播放消失特效
PlayOneShotEffect(buff.Data.removeEffect, target.transform);
// 停止持续特效
if(activeVisuals.TryGetValue(buff, out var effect))
{
Destroy(effect);
activeVisuals.Remove(buff);
}
// 移除UI图标
UIManager.Instance.HideBuffIcon(buff);
}
private void OnBuffRefreshed(Buff buff, GameObject target)
{
// 播放刷新特效(如闪光一下)
PlayOneShotEffect(buff.Data.refreshEffect, target.transform);
}
}
3.游戏中存在很多种buff, 是否需要创建不同的buff实体
csharp
复制代码
a.继承体系: 创建一个抽象的Buff基类, 然后为每种不同类型的Buff创建子类; 这种方式直观, 但当Buff行为复杂且组合多
变时, 会导致类层次过深或子类数量过多
b.组件化(策略模式): 将Buff的行为拆分成多个组件(例如:效果应用、持续时间管理、叠加规则等), 然后通过组合这些组
件来构建不同的Buff; 这种方式更灵活, 易于扩展
csharp
复制代码
将Buff的行为拆分为多个可组合的部分
a.效果(IEffect): 定义Buff的具体效果, 如伤害、修改属性等
b.持续时间(IDuration): 管理Buff的持续时间
c.叠加规则(IStacking): 定义Buff如何叠加
csharp
复制代码
public interface IEffect
{
void OnApply(GameObject target);
void OnUpdate(GameObject target, float deltaTime);
void OnRemove(GameObject target);
}
public interface IDuration
{
float Duration { get; set; }
bool IsExpired { get; }
void Update(float deltaTime);
}
public interface IStacking
{
int Stacks { get; set; }
void Stack(Buff buff);
}
public class Buff
{
public GameObject Target { get; private set; }
public IEffect Effect { get; private set; }
public IDuration Duration { get; private set; }
public IStacking Stacking { get; private set; }
public Buff(IEffect effect, IDuration duration, IStacking stacking)
{
Effect = effect;
Duration = duration;
Stacking = stacking;
}
public void Apply(GameObject target)
{
Target = target;
Effect.OnApply(target);
}
public void Update(float deltaTime)
{
Duration.Update(deltaTime);
Effect.OnUpdate(Target, deltaTime);
}
public void Remove()
{
Effect.OnRemove(Target);
}
public void Stack(Buff other)
{
Stacking.Stack(other);
}
}
// 具体效果实现
public class DamageOverTimeEffect : IEffect
{
private float tickInterval;
private float timeSinceLastTick;
private float damagePerTick;
public DamageOverTimeEffect(float tickInterval, float damagePerTick)
{
this.tickInterval = tickInterval;
this.damagePerTick = damagePerTick;
timeSinceLastTick = 0f;
}
public void OnApply(GameObject target) { }
public void OnUpdate(GameObject target, float deltaTime)
{
timeSinceLastTick += deltaTime;
if (timeSinceLastTick >= tickInterval)
{
Health health = target.GetComponent<Health>();
if (health != null)
{
health.TakeDamage(damagePerTick);
}
timeSinceLastTick = 0f;
}
}
public void OnRemove(GameObject target) { }
}
// 具体持续时间实现
public class FixedDuration : IDuration
{
public float Duration { get; set; }
public bool IsExpired => Duration <= 0f;
public FixedDuration(float duration)
{
Duration = duration;
}
public void Update(float deltaTime)
{
Duration -= deltaTime;
}
}
// 具体叠加规则实现
public class SimpleStacking : IStacking
{
public int Stacks { get; set; } = 1;
public void Stack(Buff other)
{
// 简单叠加:层数+1,刷新持续时间
Stacks++;
if (other.Duration is FixedDuration fixedDuration)
{
// 刷新持续时间,例如:重置为初始持续时间
// 这里需要知道初始持续时间,所以可能需要扩展设计
}
}
}