MEGALOVANIA MEGALOVANIA

游戏开发中

目录
CPKA开发日志 其七
/      

CPKA开发日志 其七


工作日志

  • 简单做了一套 ActionMgr 的原型,说一下思路
  • 简单来说就是做一套命令模式,把每个操作当做的单独的一个对象,然后在方法中提供 Excute 和 Undo 方法
  • 首先实现的是移动功能,通过 Path 插件计算路径,然后将路径存储到 Action 对象中
  • 这里发现的一个问题是:如果 Action 对象中用 AIPath 来做移动,那么 Path 里的一些东西会被释放掉,具体代码我没看到,但是感觉上不如自己来手动处理移动逻辑.AStar 插件的官方也提供了一些实例
  • 于是想到干脆拿 DOTween 暂时做好了,用了 Dotween 的 DOPath 和 LookAt,保证了能够顺着移动方向转头,也能保证移动的流畅,另外 AIPath 这个组件虽然不再负责移动,但是他计算出来的 Velocity 还是有用的
  • ActionMgr 维护一套 Action 的列表,并且有一个指针指向当前的 Action
  • 然后 Undo 遇到的问题是,没找到一个合理的方法来让 DOPath 倒着来,最后放弃了单纯用 DOPAth 来做 Undo 的思路
  • 于是想到了一个邪门的思路:在 Action Excute 的时候启一个 Unitask,每隔 0.02s 记录一下角色的位置朝向和动画状态,然后在 Undo 的时候把这些状态倒着播回去.这样不仅能够记录,而且能够提供任意时刻的位置
  • 根据上面的思路,位置和旋转很容易记录.关于动画状态,最开始的错误思路是记录 Animator 的参数值,后来发现这没啥意义,因为你指定一个参数的情况下并不能得到唯一的动画状态
  • 除此以外最大的问题是 Animator 里是一个 BlendTree,要还原这两个东西似乎不是那么容易...
  • 但是最后通过这里的代码打出来发现,似乎 BlendTree 没怎么 Blend(也就刚开始的时候),打印粗的结果大部分都是 1,只有极小部分过度状态时是 2

  • 因此改变了思路,直接记录每一帧的 Clip 和他的动画时间,动画时间可以这样算出

  • 然后要还原的时候,通过 AnimationClip 的 SampleAnimation 得到,需要注意的是,这里必须对 Clip 的长度取余
1private void EvauateByFrame(FrameData item)
2{
3    _animMgr.SetMoveFactor(false);
4  
5    transform.parent.position = item.position;
6    transform.parent.rotation = item.rotation;
7    // _animator.SetFloat("vel", item.speedFactor)
8    item.clip.SampleAnimation(_animator.gameObject, item.time%item.clip.length  );
9}
  • 最后实现了正向 Move,撤回 Undo,以及定位到 Action 中任意为止的功能


优化事项

  • 要写 Demo 性质的代码的时候很容易变得爆炸乱,为了快速出效果不择手段
  • 感觉应该根据工作性质区分开时间,一部分用来快速出东西,这部分可以不追求品质快速出活;一部分用来追求技术深度
  • 静下心来啃一些东西.静下心啃东西的意义在于祛魅,去除恐惧感.快速原型工作的意义在于实践和犯错.目前的工作需要两者结合
  • 另外分开这种工作状态也更有助于时间的安排,因为每天的精力分配情况是不同的,何时适合啃,何时适合快速实验会因情况而异

今日目标

  • 继续写完 ActionMgr 中剩下类型的 Action

标题:CPKA开发日志 其七
作者:matengli110
地址:https://www.sunsgo.world/articles/2024/03/29/1711691981126.html