一、知识回顾 物理系统之碰撞检测
1.碰撞产生的必要条件
(1)至少一个物体有刚体
(2)两个物体都必须有碰撞器
2.碰撞和触发
(1)碰撞会产生实际的物理效果
(2)触发看起来不会产生碰撞但是可以通过函数监听触发
3.使用场景
碰撞检测主要用于实体物体之间产生物理效果时使用
二、什么是范围检测
1.使用场景
游戏中瞬时的攻击范围判断一般会使用范围检测
2.常用游戏案例
(1)玩家在前方10m处释放一个魔法,在此处范围内的对象将受到魔法伤害
(2)玩家攻击,在前方1米圆形范围内对象都受到伤害等等
3.总结
没有实体物体 只想要检测在指定某一范围是否让敌方受到伤害时 便可以使用范围判断。在指定位置进行范围判断,我们可以得到处于指定范围内的对象,目的是对对象进行处理,比如受伤 减血等等
三、如何进行范围检测
1.必备条件
想要被范围检测到的对象,必须具备碰撞器。
2.注意点
(1)范围检测相关API,只有当执行该句代码时,进行一次范围检测,它是瞬时的
(2)范围检测相关API,并不会真正产生一个碰撞器,只是碰撞判断计算而已
3.范围检测API
3.1盒状范围检测
参数一:立方体中心点
参数二:立方体三边大小
参数三:立方体角度
参数四:检测指定层级(不填检测所有层)
参数五:是否忽略触发器
UseGlobal-使用全局设置
Collide-检测触发器
Ignore-忽略触发器
不填默认使用UseGlobal
返回值:在该范围内的触发器(得到了对象触发器就可以得到对象的所有信息)
print(LayerMask.NameToLayer("UI"));
Collider[] colliders = Physics.OverlapBox( Vector3.zero, Vector3.one, Quaternion.AngleAxis(45, Vector3.up),
1 << LayerMask.NameToLayer("UI") |
1 << LayerMask.NameToLayer("Default"), QueryTriggerInteraction.UseGlobal);
for (int i = 0; i < colliders.Length; i++)
{
print(colliders[i].gameObject.name);
}
返回值:碰撞到的碰撞器数量
参数:传入一个数组进行存储
Physics.OverlapBoxNonAlloc()
if(Physics.OverlapBoxNonAlloc(Vector3.zero, Vector3.one, colliders) != 0)
{
}
3.2球形范围检测
参数一:中心点
参数二:球半径
参数三:检测指定层级(不填检测所有层)
参数四:是否忽略触发器
UseGlobal-使用全局设置
Collide-检测触发器
Ignore-忽略触发器
不填默认使用UseGlobal
返回值:在该范围内的触发器(得到了对象触发器就可以得到对象的所有信息)
colliders = Physics.OverlapSphere(Vector3.zero, 5, 1 << LayerMask.NameToLayer("Default"));
返回值:碰撞到的碰撞器数量
参数:传入一个数组进行存储
Physics.OverlapSphereNonAlloc
if( Physics.OverlapSphereNonAlloc(Vector3.zero, 5, colliders) != 0 )
{
}
3.3胶囊范围检测
参数一:半圆一中心点
参数二:半圆二中心点
参数三:半圆半径
参数四:检测指定层级(不填检测所有层)
参数五:是否忽略触发器
UseGlobal-使用全局设置
Collide-检测触发器
Ignore-忽略触发器
不填默认使用UseGlobal
返回值:在该范围内的触发器(得到了对象触发器就可以得到对象的所有信息)
colliders = Physics.OverlapCapsule(Vector3.zero, Vector3.up, 1, 1 << LayerMask.NameToLayer("UI"), QueryTriggerInteraction.UseGlobal);
返回值:碰撞到的碰撞器数量
参数:传入一个数组进行存储
Physics.OverlapCapsuleNonAlloc
if ( Physics.OverlapCapsuleNonAlloc(Vector3.zero, Vector3.up, 1, colliders ) != 0 )
{
}
4.层级以及层级编号知识点补充
通过名字得到层级编号
LayerMask.NameToLayer
通过编号左移构建二进制数,这样每一个编号的层级 都是 对应位为1的2进制数,我们通过 位运算 可以选择想要检测层级,好处 一个int 就可以表示所有想要检测的层级信息。
层级编号是 0~31 刚好32位,是一个int数,每一个编号 代表的 都是二进制的一位

四、练习题
1.题目
世界坐标原点有一个立方体,键盘WASD键可以控制其前后移动和旋转
1.按J键在立方体面朝向前方1米处进行立方体范围检测
2.按K键在立方体前面5米范围内进行胶囊范围检测
3.按L键以立方体脚下为原点,半径10米内进行球形范围检测
2.代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Lesson22_Exercises : MonoBehaviour
{
//移动速度
public float moveSpeed;
//旋转速度
public float roundSpeed;
void Update()
{
//位移
this.transform.Translate(Vector3.forward * Time.deltaTime * moveSpeed * Input.GetAxis("Vertical"));
//旋转
this.transform.Rotate(Vector3.up, Input.GetAxis("Horizontal") * roundSpeed * Time.deltaTime);
if( Input.GetKeyDown(KeyCode.J) )
{
Collider[] colliders = Physics.OverlapBox( this.transform.position + this.transform.forward,
Vector3.one*0.5f, //长宽高的一半
this.transform.rotation,
1 << LayerMask.NameToLayer("Monster"));
for (int i = 0; i < colliders.Length; i++)
{
print("物体受伤" + colliders[i].gameObject.name);
}
}
if(Input.GetKeyDown(KeyCode.K))
{
Collider[] colliders = Physics.OverlapCapsule(this.transform.position,
this.transform.position + this.transform.forward * 5,
0.5f,
1 << LayerMask.NameToLayer("Monster"));
for (int i = 0; i < colliders.Length; i++)
{
print("物体受伤" + colliders[i].gameObject.name);
}
}
if(Input.GetKeyDown(KeyCode.L))
{
Collider[] colliders = Physics.OverlapSphere(this.transform.position, 10, 1 << LayerMask.NameToLayer("Monster"));
for (int i = 0; i < colliders.Length; i++)
{
print("物体受伤" + colliders[i].gameObject.name);
}
}
}
}
1632

被折叠的 条评论
为什么被折叠?



