插值函数及通过向量判断敌人方位

本文介绍了在Unity开发中学习的二叉树遍历方法,重点讲解了层序遍历和使用Lerp进行插值运算。同时,讨论了向量的长度、单位向量、点乘与叉乘在游戏场景中的应用,如NPC的扇形巡视范围检测和敌人方位判断。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这一周学的算法是二叉树

二叉树的遍历有前 中 后,这是以中间节点为基准的,前->先访问中间节点->左右

后->先访问左右->中

中->左 中 右

二叉树的层序遍历借助queue更加方便实现,其思路就是先让根节点入队,然后在循环中获得这一层的size,遍历整个一层,把它的子节点给入队,然后弹出自己,循环往复操作.

二叉树中某个节点的深度是指该节点到跟节点的距离

某个节点的高度是指该节点到叶子节点的距离,叶子节点本身的高度就是1

Unity->

插值表达式Lerp

插值运算 - Lerp

Lerp函数公式 //result = Mathf.Lerp(start, end, t);

t为插值系数,取值范围为 0~1 //result = start + (end - start)*t

插值运算用法一 //每帧改变start的值——变化速度先快后慢,位置无限接近,但是不会得到end位置

start初始值为0 start = Mathf.Lerp(start, 10, Time.deltaTime);

//插值运算用法二 //每帧改变t的值——变化速度匀速,位置每帧接近,当t>=1时,得到结果 time += Time.deltaTime;

result = Mathf.Lerp(start, 10, time);

当time由Time.deltaTime搞到1的时候,result就会取得10

向量模长与单位向量获取

获取两个点之间的距离的两种方式→

1.Vector3.Distance(A,B);

2.AB.magnitude;

一个是通过点得到的长度,一个是通过向量得到的长度

如何获取单位向量(模长为1)→

AB.normalized;

单位向量目前来说对于我们的意义就是用于位移计算,由于它的模长为1,所以我们可以通过控制速度的大小来控制物体每帧位移的多少,而不是由各种天花乱坠的模长来控制.

在Vector3中有Vector3.Angle(A,B); 用于计算两个向量之间的夹角

该方法实现的原理就是通过向量的点乘实现的→

float dotResult = Vector3.Dot(this.transform.forward,(target.position - this.transform.position).normalized);

//即使传入的不是方向向量,我们也可以化为方向向量的点乘,因为我们只用来判断方向而不是距离

所以角度就可以求→

Mathf.Acos(dotResult)*Mathf.Rad2Deg;

Vector3.Dot(); 是用于计算两个向量的点乘的值,返回值是浮点数

我们可以通过点乘的结果来判断目标在我的前方还是后方

如果点乘的结果大于0,说明目标与我的正前方方向的夹角小于等于九十度,也就是在我的前方,反之在我的后方

通过这种判断方位以及角度的方式,我们就可以设置一个NPC的扇形巡视范围,当玩家出现在NPC一定角度的范围时且是在该NPC的前方方位,我们就可以触发NPC事件了

扇形检测(45°)敌人是否进入范围→

public Transform Target;

float DotRes;

void Update() {

DotRes = Vector3.Dot(transform.forward,(Target.position-transform.position).normalized);

float angle = Mathf.Acos(DotRes)*Mathf.Rad2Deg; //弧度转为角度

print(angle);

if (DotRes >=0 && angle <= 22.5f&&Vector3.Distance(transform.position,Target.position)<=5) //小于五米的话,检测敌人 { print("发现敌人");

}

叉乘结合点乘判断方位->

Vector3.Cross(A,B);

A叉乘B得到的向量是他俩的法向量,该法向量的y的值>0则说明B在A的右侧

                                                              //y的值<0则说明B在A的左侧

判断敌人在我的左前方,右前方,左后方,右后方→

public Transform Target;

float DotRes;

void Update() {

DotRes = Vector3.Dot(transform.forward,(Target.position-transform.position).normalized);

Vector3 isUpper = Vector3.Cross(this.transform.forward,Target.position-this.transform.position);

// if (DotRes >= 0) //点乘大于0说明在前方 {

if (isUpper.y >= 0) //说明在右方

{ print("发现敌人在右前方");

} else { print("发现敌人在左前方"); }

} else { if (isUpper.y >= 0)

{ print("发现敌人在右后方");

} else { print("发现敌人在左后方");

}

}

}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值