Bevy_behave行为树
行为树是AI的一种,适合npc或敌人的简单智能。
这个库非常棒,实现简单高效,符合作者宣传的简单API.
树的构成
下面都属于枚举,每个枚举值都是一个一条处理分支。
Match的分支不需要全部返回相同的类型
看下面的代码,感受一下神奇的写法。
match分支返回的是bool,这是明确的,但前两条分支并没有返回什么,而是提前结束了函数。
在常见的match写法中,每个分支的返回值都应该保持一致的类型。但这里打破了这个规则。
关系
Bevy官方查找祖先节点的代码。
传送门
传送门的目的在传送二字上,位置移动是基本属性。下面讨论一下几种位置移动。
- 关卡之间的移动
- 如果是单向的,直接重建就行了。
- 如果是双向的,就需要记住传送门的位置,Entity_ref就很好用
- 关卡内的移动,不管是单向还是双向,都需要记住位置的
资料收集
游戏中的“传送门”机制,其本质是空间跳转系统,可能包括视角转换、位置转换、甚至状态同步。 不同类型的游戏中,传送门系统的复杂程度和实现方式差别很大。 以下是业界主流的几种实现方式和思路,按技术复杂度和类型分类讲讲:
🎮 一、基础分类
1. 瞬间传送型(Teleportation)
-
代表作:《塞尔达》、《GTA》、《原神》的传送点
-
实现方法:
- 触发区域检测(如碰撞盒)
- 更换玩家位置(
player.position = target.position) - 可选切场景(Unload/Load Scene)
- 传送后延迟输入、动画、黑屏遮挡等优化体验
2. 可视穿越型(Portal-like)
-
代表作:《传送门(Portal)》
-
实现方法:
- 渲染视窗穿透效果(Render Texture) 另一端的摄像机渲染结果投射到传送门的表面材质上
- 空间转换(Transform Matrix) 玩家穿越时,将玩家的局部空间坐标转换到目标门的空间下
- 多摄像头同步(双向 portal) 避免错位,需要追踪摄像机朝向并同步场景中的穿越视角
3. 物理穿越型(Seamless World / Streaming)
-
代表作:《传送门骑士》、《死亡搁浅》、UE大型开放世界
-
实现方法:
- 门后其实是另一片地形的加载区域
- 利用“世界划分 + 流式加载”(World Partition / Stream)实现无缝加载
- 门的边缘使用遮挡或狭窄通道隐藏加载过程
🧠 二、技术实现关键点
✅ 1. 触发检测
- 碰撞体(trigger volume)
- 输入行为(交互键触发)
✅ 2. 玩家状态同步
- 动画中不可传送
- 传送后恢复状态(坐标、朝向、动画、速度)
✅ 3. 多人同步问题(网络游戏)
- 状态一致性:传送前广播断开,再加入新场景
- 服务器端主导传送判断,防止作弊
✅ 4. 渲染穿透的优化
- 设置 stencil buffer 分离 portal 和场景
- 使用裁剪矩阵 / portal clipping planes 防止“错穿”
🧪 三、开发引擎支持情况
| 引擎 | 支持情况 | 示例/技术栈 |
|---|---|---|
| Unity | ✅ RenderTexture + 相机同步 | 可用开源插件如 Portal Render |
| Unreal Engine | ✅ RenderTarget + SceneCapture | 官方示例项目即含 Portal 示例 |
| Godot | ✅ ViewportTexture + Portal Camera | 有社区插件支持 |
| 自研引擎/Bevy等 ECS | 🟡 需自行处理空间变换与渲染纹理 |
🎨 四、传送门机制设计建议
-
传送体验要顺畅
剑舞bevy_rapier2d_例子分析
自由下落的箱子
动力学箱子 + 静态刚体地面.
箱子受重力影响。
角色移动资料收集
游戏角色移动的方案,不管是在独立游戏还是商业大作中,通常都会围绕普通移动(行走、奔跑)、跳跃和冲刺这几个基本能力进行设计。以下是目前行业里主流与较新方案的系统化分析。
本文聚焦于2d top-down游戏。
🎮 一、普通移动(走 / 跑)
1. 主流方案
✅ 物理系统驱动(如 Unity 的 Rigidbody / Unreal 的 CharacterMovement)
-
优点:支持物理交互、坡道、重力,表现真实。
-
使用方式:
- 给角色加刚体(Rigidbody),通过
velocity或AddForce()控制移动。 - Unreal 用
AddMovementInput(),底层已包含加速、滑动、楼梯处理等。
- 给角色加刚体(Rigidbody),通过
✅ 非物理驱动(Transform 直接移动)
-
优点:控制更直接,适合 2D 或无物理需求的游戏。
-
典型用法:
transform.Translate()或手动设置position += speed * deltaTime
2. 进阶做法
✅ 基于 NavMesh / A* 的路径导航
- 用于 AI 或点击移动型角色(RTS、RPG)
- 结合路径平滑处理 + 动画状态切换
✅ 根运动(Root Motion)
- 动作动画中包含位移,动画驱动角色移动
- 常用于 3A 游戏,能确保动画和位置完全一致
- 缺点:不灵活,难调整实时响应性
🦘 二、跳跃(Jump)
1. 主流实现
✅ 加速度实现
- 使用
velocity.y += jump_force,再交给重力慢慢拉下 - 优点:自然、支持多段跳,结合动画易实现
✅ 时间控制跳跃(跳跃时间/高度可控)
-
按下跳跃时开始计时,持续往上推力,松开跳跃按钮时立刻终止上升
插件如何捕捉用户操作
一个Plugin提供了一些函数接受用户输入,在首帧之前要统计所有用户输入, 一个简单的方法是在Plugin::finish()做处理。
在生态库中很少见到这种需求,只有在复杂生态库才能看到。
在Plugin构建时添加一个保存数据的资源,在所有插件加载完毕后,读取数据并删掉资源。
不是泛型类型却有泛型方法
第一次遇到这种写法,需要记录一下开开眼。
仔细一想,这是很合理的嘛。