自己琢磨了一个塔防游戏,目前的效果框架是这样的
当塔射出子弹时,子弹会携带一个效果集合,单个效果会包含多个子效果,例如冰冻效果的子效果是【移速减少10%】【攻速减少10%】,当效果被添加到敌人身上时,会遍历拥有的子效果添加到对应的属性组件上,当需要调用属性的当前值时,属性组件遍历自身拥有的效果计算出当前值返回。这些可以影响属性的效果都继承自AttributeEffect。
现在我想要实现一个【在敌人所在地块生成一个燃烧地块】的效果,它不属于影响属性的效果,我要再新创建一个GroundEffect类吗,地块效果和属性效果需要继承自同一个Effect基类吗?还是我之前效果的写法有问题,需要修改,
求大佬指点
像这个燃烧地块应该会影响其他敌人,感觉开新的基类出来会好一点,你当前的特效类应该都是在敌人自身节点上吧,还是说有一个总管理特效的节点
属性效果现在是添加到敌人身上敌人自己管理的,没有统一的管理器,
对这个燃烧地块就是每秒对在该地块的敌人造成伤害,所以我认为【生成一个燃烧地块】这个效果跟属性效果没有关系,就想不通实现这种效果实现应该怎么写了,是在子弹命中敌人时在敌人内部生成,还是广播一个事件由地块管理器来生成这个地块呢
看你把effect当作什么来理解,一般来说是一个比较宽泛的概念,
针对属性的effect一般叫做modifier,你想当成effect统一处理就可以叫做AreaEffect,
想单独处理,那就是单独的战场中的Entity(Field,Zone,Aura,Trap,和子弹一个级别);纯个人习惯问题。你也可以拆分成两个,一个域对象,给它添加effect(buff)
这个应该是一个触发技能,分为两种情况,一个是只触发一次,那么只需要给你自身添加一个xxx命中时在目标位置创建一个燃烧地面的技能。另一种是持续效果,比如说,目标每X秒创建一个燃烧地面,那么就应该是添加一个Buff,Buff的效果是给目标添加一个技能,技能效果是,每X秒创建一个燃烧地面,当Buff被移除的时候移除这个技能
这方面可以参考UE的GAS框架,你可以看下
燃烧效果可以看做一个特殊的子弹,普通子弹命中时造成一次伤害,燃烧地块有个生命周期,生命周期内持续造成伤害
也分两种情况,一种周期性的对与地块接触的目标直接造成伤害,还有一种是点燃目标,那么就需要给目标挂buff
统一抽象成一个触发对象。TriggerObj 无论子弹,buff 技能,还是区域伤害,都可通用
子弹的直接伤害和buff效果分开处理就OK了,你现在写的没啥问题,只是要增加燃烧伤害(直接伤害,按照范围伤害来)和引燃伤害的buff(子效果,attr需要增加敌人减少的生命值,敌人属性多一些占不了多少内存的);
燃烧地块属于场景元素,你可以做一个场景区域触发器对象类,也可以用一个间隔触发的特殊子弹子类来做。
原来的子弹击中后,产生该对象即可。
这种纯数据的相对死板,你可以认为子弹有一个OnHit的事件Hook,携带一个闭包函数,在里面你想加属性就加属性,想生成物体就生成物体。就是不仅仅带数据,还可以带逻辑。
buff这东西,数据和效果是应该分离的,效果很多时候就是个动画或粒子表现而已,表现和数据怎么绑定那需要策划思维,比如你说的效果和子效果,在数值表上就可以完全整合(比如配置一个subBuffs字段),甚至在解析配置表时就可以把子效果的所有属性预处理到父效果的属性上,减少业务逻辑运行期的循环遍历、降低CPU计算。
我个人认为Buff是可以统一定义和处理的,不管是子弹、敌人还是地块都是Buff的载体,可以定义一个统一的BuffComp组件,里面绑定的唯一数据就是Buff数值表ID,只要在Buff载体的node上添加这个BuffComp组件,BuffComp内部通过Buff数值表ID去加载或添加具体的动画或粒子效果即可,同理也可以处理Buff载体的移速、攻速等,也能处理燃烧地块,角色触碰燃烧地块掉血等问题。
地图上所有东西都是element。可以相互挂在对方身上。有一个update去处理就行了
1优雅的架构设计(C# 示例,Unity 风格)
// 1. Buff/Debuff 基础接口
public interface IStatusEffect
{
string Id { get; }
float Duration { get; } // -1 = 永久
int StackCount { get; set; } // 堆叠数
int MaxStack { get; }
bool IsDebuff { get; }
void OnApply(StatusSystem target);
void OnUpdate(StatusSystem target, float deltaTime);
void OnRemove(StatusSystem target);
void OnStack(IStatusEffect existing);
}
2优雅的数据驱动
// StatusEffects.json
[
{
"id": "poison",
"type": "PoisonEffect",
"duration": 5,
"maxStack": 3,
"damagePerSec": 5,
"isDebuff": true
},
{
"id": "speed_up",
"type": "SpeedBuff",
"duration": 8,
"speedMultiplier": 1.5,
"isDebuff": false
}
]
3给“敌人”添加效果(优雅调用)
// 在技能中:
enemy.GetComponent<StatusSystem>().ApplyEffect(
new PoisonEffect { StackCount = 1 }
);
// 或从配置表创建:
var factory = new StatusEffectFactory();
enemy.GetComponent<StatusSystem>().ApplyEffect(
factory.Create("poison")
);
您好朋友 我曾经制作过ARPG游戏 开发过相同需求的功能 ,这里分享下当年的思路,希望能帮到您,其实 燃烧的火焰 是一个子弹 ,一直放在那个位置,它自带碰撞块 ,但每间隔0.5秒 就回开关一次 ,也就是说 其实它每0.5秒回和周围进行一次碰撞计算 ,此时 你就可以用碰撞逻辑去判断 燃烧效果了,当然 我当初做的要稍微麻烦一些,离开后也会在一段时间受到 燃烧伤害,那么你可以 每0.5秒 碰撞一次但不回造成伤害但回给 玩家增加一次debuff时间,debuff会运行自己的逻辑每X秒对目标造成伤害
Dota2 这种就是比较典型的逻辑的配置数据化。事件 --> 动作(带参数)列表。