【第017问 Unity Physics.OverlapSphere如何检测附近玩家?】

一、背景

如何检测一个对象范围内的玩家,这个可以直接使用距离判定,物体射线检测等相关方式;这里采用Physics.OverlapSphere的方式来实践其过程,并对Physics.OverlapSphere的使用做一下记录;

二、Physics.OverlapSphere

1、该API表示采用球体的方式进行物体的范围检测;那什么是球体,看下面的动画:请添加图片描述
上图就是Unity中创建的一个Sphere;想篮球、乒乓球也是这种形状;那么我们需要检测范围区域就是这种球形;

2、该球形检测的API有两个:
2.1 Physics.OverlapSphere(Vector3 position, float radius, int layerMask)
2.2 Physics.OverlapSphere(Vector3 position, float radius)

这两个API的区别就在于layerMask;如果你指定了layerMask,那么检测的对象就只针对指定的LayerMask,否则就是所有的碰撞体都会检测;

对该API进行详细说明:
position:表示需要指定的检测的位置,如下动画:请添加图片描述
上面移动的的位置就是该对象需要检测的起始位置,也就是这个球体的球心;整个检测的起始点位置;

radius: 表示该球心的半径,看动画:
请添加图片描述
可以看到上面的颜色部分,只是绘制除了一个平面的部分半径可视化的直线;当在进行检测的时候和半径的大小相关联;半径内的可以检测到,半径以外的不可以检测

layerMask: 可以设置,也可以不设置,如果设置那么就用方式:LayerMask.GetMask(“BoxCollider”); 进行设置;如果不进行设置就检测所有的Layer;这里的BoxCollider是自定义的Layer名字;

三、实践效果

1、检测LayerMask为BoxCollider的物体是否在球体范围内;半径可以调节:动画演示:请添加图片描述
默认白色的Cube表示没有被检测到,颜色变为红色的Cube表示在Sphere的范围内;
在上面的动画中:左右两个Cube的Layer为BoxCollider;上下两个Cube的layer为Default;

1.1 、可以看到在半径以外是不会被检测到的,也就是Cube不会变红的;
1.2、即使在半径范围内,如果和需要检测的LayerMask不一样,那么Cube也是不会变红的;

2、检测所有,不区分LayerMask 动画演示:
请添加图片描述
该动画就是不区分LayerMask,所有可以碰撞的物体都会被检测,如果在半径范围内,那么就会被检测到;

注意
既然是物体碰撞检测,那么被检测的对象一定要有Collider,要不然是不会被检测到的;以上就是通过可视化事件范围内NpC的检测;

四、源码

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;

[ExecuteAlways]
public class PhysicsSphereTest : MonoBehaviour
{
    private SphereCollider _sphereCollider;
    [SerializeField] private Material _material;
    [SerializeField] private Material defaultMaterial;


    [SerializeField] private List<MeshRenderer> _meshRenderers;

    private void Awake()
    {
        _sphereCollider = GetComponent<SphereCollider>();
    }

    // Start is called before the first frame update
    void Start()
    {
    }


    private void OnDrawGizmos()
    {
        if (_sphereCollider == null)
            _sphereCollider = GetComponent<SphereCollider>();
        float radius = _sphereCollider.radius;

        for (int angel = 0; angel < 360; angel += 2)
        {
            double x = Math.Cos(angel * 1.0f);
            double z = Math.Sin(angel * 1.0f);
            Vector3 v3 = Vector3.one;
            v3.y = 0;
            v3.x = (float) x * radius;
            v3.z = (float) z * radius;
            Vector3 target = transform.position + v3;
            Debug.DrawLine(transform.position, target, Color.magenta);
        }

        ResetMaterial();
        int layer = LayerMask.GetMask("BoxCollider");
        // Collider[] colliders = Physics.OverlapSphere(transform.position, radius, layer);
        Collider[] colliders = Physics.OverlapSphere(transform.position, radius);
        foreach (var boid in colliders)
        {
            boid.GetComponent<MeshRenderer>().material = _material;
        }
    }


    void ResetMaterial()
    {
        foreach (var mr in _meshRenderers)
        {
            mr.material = defaultMaterial;
        }
    }
}

五、结语

外面下雨,但屋里有点热[valaki]

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值