问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

UE5制作推箱子游戏机制:获取物体与角色朝向角度及跨蓝图变量修改

创作时间:
作者:
@小白创作中心

UE5制作推箱子游戏机制:获取物体与角色朝向角度及跨蓝图变量修改

引用
CSDN
1.
https://blog.csdn.net/snans/article/details/136937390

在虚幻引擎5(UE5)中制作推箱子游戏机制时,如何判断玩家是否正对箱子并进行推动物体的操作是一个常见的技术问题。本文将详细介绍如何通过获取物体与角色朝向的角度,以及如何实现跨蓝图修改变量,帮助开发者实现这一功能。

准备工作:实现跨蓝图修改变量

1. 创建玩家蓝图

创建一个名为 LightRobot 的玩家蓝图(Pawn)。使用正常的配置操作即可。

2. 创建箱子蓝图

创建一个名为 BP_Box 的角色蓝图(Actor),其中包含 Cube 立方体组件和 Box 盒体碰撞组件。Box 的四周比 Cube 大一点,底顶比 Cube 小一点。

注意:需要将 Box 作为 Cube 的子级,否则 Cube 移动后,Box 并不会跟随移动,下次想要推就没法激活了。

同理:DefaultSceneRoot 不会随着 Cube 移动,因为它是根,是 Cube 的父级,而父级不会跟随子级移动。这点很重要哦,搞错的话将无法获取正确的位置。

3. 创建动画蓝图

创建一个动画蓝图 LightRobot_ABP,其中包含一个变量 isPush 来确定是否激活推动动画。动画部分不在本文展开。

4. 使用重叠事件

使用重叠事件来更改 LightRobot_ABPisPush 的值。这个流程人物只要走到箱子附近就会释放推动动画,哪怕人物是背对着箱子的。

两个知识点和流程

  • 知识点:

  • 跨蓝图修改需要用 Castto... 节点,翻译为 类型转换为~~

  • 要读取动画蓝图则需要先获取 动画实例

  • 流程:

    1. 重叠事件发生,于是从一堆 Other Actor 碰撞到的物体中 Cast to BP_LightRobot 找到玩家蓝图;
    2. Get Mesh 找到该玩家蓝图下的网格体;
    3. 这个网格体下有动画,于是 Get Anim Instance 获取动画实例;
    4. 在用 Cast To LightRobot_ABP 从一堆动画中找到玩家用的动画蓝图;
    5. 最后 Set isPush 设置变量。

下面的图片是从玩家蓝图中找到动画蓝图的顺序,看完是不是就清楚上面的流程了?

这些准备好后,现在开始正式判断角度。

根据位置判断

基本原理:

  1. 获得箱子的位置和玩家的位置,计算得到一个人到箱子的向量A;
  2. 获得玩家脸朝向的向量,其实就是前进的向量B;
  3. 计算得出A和B之间的夹角

不过这种方法并不精准哦,毕竟站在箱子边缘和站在箱子中间,本身就会产生角度,当然如果箱子不那么大,也够用了。

1. 通过Cube的相对位置来实现

我之前说过,在 BP_Box 蓝图中,Cube 是能动的,可根 self 是不会移动的,需要通过 Get Relactive Location 来获得 Cube 相对 DefaultSceneRoot 的位置。

这里的点积 Dot Product 和反余弦 Acos(Dgrees) 只要知道是比较两个向量后再换算成角度

2. 将Cube设置为根级来实现

这里直接调用 Cube 的位置,但是必须要将 Cube 作为根替换掉原来的 DefaultSceneRoot,道理是一样的,因为根 DefaultSceneRoot 不会跟随子级 Cube 移动,那么当第一次重叠时能获得正确的角度,而第二次重叠时虽然箱子已经移动过位置了,但箱子的根位置还在原来的地方,于是就出错了。

根据射线判断

上面的方法是根据角色到物体的方向和角色前进方向来算出两个方向的夹角是否满足面对物体的要求。这个方法在遇到小物体是没问题,但遇到一个很大的物体时,就会出错了——当你站在物体边缘,这时候两个方向的角度已经很大了,就更不用提脸的朝向了。

然后就找到了真正的解决办法~~,应该也是真正常用的办法:“胸口射线法”,学会了这个方法基本可以解决90%以上的碰撞问题了;

简单来说就是:

  1. 当组件重叠事件激活时,从玩家胸口射出一根有指定方向和距离的射线;
  2. 当这个射线击中某个可以碰撞的物体时检测是否符合要求,符合则为真;
  3. 本例中因为触发盒体碰撞的范围离箱子很近,那么射线的第一个遇到的目标肯定是盒体,所以就为真了;
  4. 本例中的射线长度为1500,目的是为了测试时能看清射线,实际运行时是有问题的,因为你斜着箱子站的时候,射线虽然没有击中箱子,但可能击中更远的墙了,那么也会判定命中为真,所以射线长度设个50、100短一点的就行了。
  5. 注意 Ignore Self 需要去掉勾,因为打勾意味着忽略触发射线的Actor,也就是说射线投射将不会与触发该投射的Actor产生碰撞。由于我们是重叠时才会激活这个射线,重叠的前提就是玩家与箱子共同参与这个触发,如果此刻 Ignore Self 为真的话,那么射线就会忽略掉箱子,直接穿到后面去了。

网上很多案例的情况与本文不同,他们并不涉及重叠事件,因此 Ignore Self 为真是没问题的,这点需要注意。

主要是理解 LineTraceByChannel 按通道进行线条追踪的用法:

  • start 开始值为玩家的当前位置(向量);
  • End 结束值为玩家面对的方向多n个距离的位置(向量);

1. 根据世界坐标射出射线

2. 根据角色坐标射出射线

在本例中用这个方法也没问题,反正就是胸口射出射线么,用这个还不需要查询根组件,效率更高一点。

也可以把其中向前的向量直接简写为如下

小知识:
乘法默认情况下两个乘数的单位是相同的,但是你可以选中其中一个数右键菜单更改其单位。

参考:

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号