检测周围的物理环境来控制人物的跳跃
相关文档
- https://docs.unity.cn/ScriptReference/Physics2D.html
- https://docs.unity.cn/ScriptReference/Physics2D.OverlapCircle.html
OverlapCircle API
这里我们使用的是 OverlapCircle
检测,是一种用于检测圆形区域内物体碰撞的函数
Parameters参数
字段 | 解析 |
---|---|
point点 | Centre of the circle.圆的中心。 |
radius半径 | The radius of the circle.圆的半径。 |
layerMask层数 | Filter to check objects only on specific layers. 筛选器,只检查特定图层上的对象。 防止全部检测,节省性能! |
minDepthminDepth | Only include objects with a Z coordinate (depth) greater than or equal to this value.只包括Z坐标(深度)大于或等于此值的物体。 |
maxDepth最大深度 | Only include objects with a Z coordinate (depth) less than or equal to this value.只包括Z坐标(深度)小于或等于此值的对象 |
它会返回一个Collider2D或Collider数组,表示在给定的圆周范围内与当前层级的物体发生碰撞的所有物体。
需要注意的是,OverlapCircle只检测圆形范围内的碰撞,对于其他形状的检测可以使用类似的函数,例如Physics2D.OverlapBox和Physics2D.OverlapCapsule等。
创建检测脚本
我们对于物理检测的脚本,单独独立出一个 c# 脚本出来,因为不单单是我们的主角需要进行物理检测,后面我们添加到场景中的敌人同样需要进行周围环境的物理检测!
创建一个 Detection 文件夹!防止检测的脚本!添加到Player主角上!
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PhysicalDetection : MonoBehaviour
{
// 暴露在 可视化界面去改变!
// 检测的半径
public float checkRadius;
// layer 指定检测的图层
public LayerMask layer;
// 是否检测到当前GameObject是否与layer 指定检测的图层有接触
bool _isOn;
void Update()
{
Check();
}
private void Check()
{
_isOn = Physics2D.OverlapCircle(transform.position, checkRadius,layer);
}
}
保存执行脚本,当选择layer的时候发现这里没有我们想要的layer
如果我们想要检测人物与地面的检测,我们需要针对地面去创建一个 layer,选中我们的地形,在检查器中Layer选择 add Layer !
随便起个名字叫做Ground
然后给地面指定Layer为Ground!
然后回到主角的配置检测脚本的可视化界面这里,选择layer为 Ground !
设置检测半径为 0.2,因为本身角色的轴心点就在脚步,所以不用太大!
这里我们加一个 Log
来持续看看到底有没有人物与地面的检测!!
可以看到这个 _isOn
在落地之后就变成了 True
,代表检测到了周围的地形的 Groud
图层!
解决我们之前跳跃的连跳问题
有了地面检测!
那就可以在跳跃的时候根据主角是不是在地面上!选择是不是要跳跃了!如果在地面上那么就跳,否则就不能跳!
为了能在主角控制的脚本中使用isOn实例属性,我们需要把isOn改成public
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PhysicalDetection : MonoBehaviour
{
// 暴露在 可视化界面去改变!
// 检测的半径
public float checkRadius;
// layer 指定检测的图层
public LayerMask layer;
// 是否检测到当前GameObject是否与layer 指定检测的图层有接触
public bool isOn;
void Update()
{
Check();
}
private void Check()
{
isOn = Physics2D.OverlapCircle(transform.position, checkRadius,layer);
Debug.Log(isOn);
}
}
然后去控制主角的脚本去获取检测脚本!检测脚本同样是一个组件!通过 GetComponent 获取 ,泛型传入 检测脚本Class 就可以!
可以看到不管我空格摁的多频繁,他始终在落地后才能进行起跳!!!
优化我们的检测脚本-增加方便的检测范围可视化
因为我们的检测脚本 PhysicalDetection
是一个通用的脚本!
isOn = Physics2D.OverlapCircle(transform.position, checkRadius,layer);
我们目前判断的圆心是通过绑定改脚本的GameObject的锚点来判定的!不同的物体的大小,锚点也是不同的!如果锚点在一个物体的底部,就比如上面的例子,我们可以盲猜一个很小的值去确认他的检测半径!如果是一个在中心的我们需要根据物体的宽高去计算检测半径,这样其实不够方便不够直观!
我希望使用一种可视化的方法,能实时看到检测的半径!
首先我们创建一个变量用于计算去控制GameObject的transform.position圆心范围!
// 一个和圆心计算去调整偏移量的参数!
public Vector2 offset;
然后我让这个值和GameObject
的transform.position
相加,这样就可以计算一个新的圆心的位置,我们可以通过调整offset来从界面方便的控制圆心!
那么如何能让我从界面上看到圆心的位置呢!甚至可以看到检测区域的形状!
OnDrawGizmosSelected文档(https://docs.unity.cn/ScriptReference/MonoBehaviour.OnDrawGizmosSelected.html)
这个钩子函数的触发条件是当点击启用切换所有Gizmos可见的时候触发的!
而且必须是绑定改脚本的物体被选中,才会触发这个钩子函数!【还有一个 OnDrawGizmos 这个就是无论绑定该脚本的物体是否被选中都会执行这个钩子函数!】
那么我们就用这个特性在这个钩子函数里绘制一个圆,圆心和半径就是用检测扫描的圆心和半径
void OnDrawGizmosSelected()
{
// 绘制一个 线框的圆 使用的是我们检测扫描的圆心和半径
Gizmos.DrawWireSphere((Vector2)transform.position+offset,checkRadius);
}
然后你就能看到,在可视化界面可以通过调整参数实时的看到我们扫描的圆的范围和位置了!(半径+圆形都可以实时调整并且显示在场景中!)
这样我们调整检测范围就比较方便啦!
评论区