MDD
写这篇博客技术实现倒是其次,主要想分享一下篇尾的思考。
时间缩放的概念
在游戏开发中所提到的时间缩放
我认为就是在游戏世界内做到控制时间流速的效果
经典例子:
猎天使魔女的魔女时间
鬼泣5最终boss的时间立场
dota中虚空假面的大招
如何做到
unity并未天然支持组件级别的时间缩放
其提供的Time轮询计时器只能支持全局时间缩放,这用来暂停游戏恢复游戏十分方便
但如果我们要做到每个角色都能有单独时间缩放尺度,unity的天然支持就无法做到了
所以我们需要自己精确定义游戏中的个体,并为其提供单独的时间缩放尺度。
个体级别的时间缩放控制是一个老老实实穿针引线的活,几乎没有技巧可言
在MDDSkillEngine中影响角色时间流速表现的系统如下
1.动画
2.特效
3.FSM
4.行为树
5.BuffSystem
6.角色控制器(包括寻路--其实暂时也只有寻路)
7.物理
接下来我们要做的事情就很简单了
我们需要为每一个系统指定一个PlayableSpeed
这部分代码我就不具体展示了
当每个系统有了一个PlayableSpeed以后
使用观察者模式,将一个角色的总PlayableSpeed与所有的关联系统串起来即可
类似于如下代码
blackboard.Set<VarFloat>("PlayableSpeed", 1);
blackboard.AddObserver("PlayableSpeed",CacheAction);
public virtual void ObservingPlayableSpeed(Blackboard.Type type, Variable newValue)
{
if (type == Blackboard.Type.CHANGE)
{
VarFloat varFloat = (VarFloat)newValue;
if (CachedAnimancer != null)
{
CachedAnimancer.Playable.Speed = varFloat.Value;
}
if (CacheMove != null)
{
CacheMove.PlayableSpeed = varFloat.Value;
}
}
}
/// <summary>
/// 时间缩放适配函数
/// </summary>
/// <param name="type"></param>
/// <param name="newValue"></param>
public override void ObservingPlayableSpeed(Blackboard.Type type, Variable newValue)
{
base.ObservingPlayableSpeed(type, newValue);
if (type == Blackboard.Type.CHANGE)
{
VarFloat varFloat = (VarFloat)newValue;
IBuffSystem buffsystem = Game.Buff.GetBuffSystem(Id.ToString());
if (buffsystem != null)
{
buffsystem.PlayableSpeed = varFloat.Value;
}
IFsm<Entity> fsm = Game.Fsm.GetFsm<Entity>(Id.ToString());
fsm.PlayableSpeed = varFloat.Value;
}
}
这样我们需要控制一个角色的时间缩放只需要如下代码
//将指定实体的时间缩放参数设为0.3
entity.blackboard.Set<VarFloat>("PlayableSpeed",0.3f);
需要注意的点
在回收个体以及与个体关联的模块的时候,一定要注意时间尺度的复原。
在制作过程产生的一个思考--不要忘记自己是在做游戏
我在给各个模块适配时间缩放的时候
卡壳在了物理模块
众所周知游戏中的物理模块就是对现实物理的模仿
而在unity中我们也无法为rigbody指定一个playablespeed
所以我就思考
一个物理效果被时间尺度所影响
在代码中如何体现
:改变了速度与重力,还要考虑能量守恒。。所以要记录影响的时间长度。。。如果整理出一个公式。。。。。。。。
很显然我在犯傻
目前来说,正确的答案应该是:按相应比例改变速度表现即可,时间尺度恢复就直接恢复速度。
如果忘记自己是在做游戏,陷入在问题本身,很容易做相当大的无用功。付出了精力,可能也无法达到一个好的游戏效果。
所以,不要忘记自己是在做游戏。
Comments | NOTHING