记录一下U3d使用Raycast射线做跳跃检测时出现的问题

文章介绍了在Unity中使用Raycast射线检测实现3D物体跳跃功能的详细步骤,包括设置特定平台层、获取物体最低点、进行射线检测以及解决起始点与碰撞盒重叠导致的问题。还提到在2D场景与3D场景中射线检测的差异,并指出在3D环境下可能需要调整射线起点以确保正确检测。
摘要由CSDN通过智能技术生成

需求描述

实现3d物体只有在指定平台上才能够跳跃,在空中不能跳跃

使用Raycast射线检测的方法,从player碰撞盒最底部发射一条长度为0.1f射线,如果这条射线与设定好的地面相撞,认为是可以跳跃

实现

1、将可以跳跃的平台同一设定为一层layer,比如Ground
在这里插入图片描述

2、获取player最低点的位置

//首先获取碰撞盒
 SphereCollider sphereCollider;
   
    void Start()
    {
        rb = GetComponent<Rigidbody>();
        sphereCollider = GetComponent<SphereCollider>();
		Vector3 origin = sphereCollider.bounds.center + new Vector3(0,-sphereCollider.bounds.extents.y+0.0f,0);
    }
//

bounds是碰撞盒的界限属性,通过bounds.certer可以获取碰撞盒的中心坐标,extents可以获取bounds的范围,extents.y即是y轴上碰撞盒长度的一半,可以当作半径来用

对于球型物体来说,中心坐标在高度上减去半径就是球的最低点,可以作为射线的初始位置

3、进行射线检测

Unity中有很多种射线,这里使用Physics.Raycast方法:

 public static bool Raycast(Vector3 origin, Vector3 direction, out RaycastHit hitInfo, float maxDistance, int layerMask)

返回值是bool,五个参数分别是:

Vector3 origin:射线起始位置
Vector3 direction:射线方向
out RaycastHit hitInfo:获取hit,射线碰撞的信息
float maxDistance:射线长度
int layerMask:允许射线碰撞的layer范围

从初始点origin沿direction方向发出一条长度为maxDistance的射线,如果射线与layerMask中的layer碰撞,返回true,否则返回false。

碰撞信息会保存在hitInfo中,如果检测到碰撞,会保存碰撞点坐标等信息;如果没有检测到碰撞,则会给hitInfo一个固定值,其中碰撞点坐标为(0,0,0)。

代码实现:

	bool isGround;

	void Start()
    {
        rb = GetComponent<Rigidbody>();
        sphereCollider = GetComponent<SphereCollider>();
    }

	private void Raycast()
    {
        RaycastHit hit;
        Vector3 origin = sphereCollider.bounds.center + new Vector3(0,-sphereCollider.bounds.extents.y+0.0f,0);
        isGround = Physics.Raycast(origin,Vector3.down,out hit,0.01f,1<<6);
        print(hit.point);
        Debug.DrawLine(origin, hit.point,Color.red);
    }

这样就可以进行射线检测,当isGround为true时,表示在平台上,可以进行跳跃:

private void Jump()
    {
        if(isGround && Input.GetKeyDown(KeyCode.Space))
        {
            rb.velocity = new Vector3(rb.velocity.x,0,rb.velocity.z);
            rb.AddForce(Vector3.up*300*jumpSpeed);
        }
    }

会出现无法跳跃的情况

在上面的方法中,选取的origin坐标是player碰撞盒的最低点
在这里插入图片描述
发出的射线在起始点origin出并不会做碰撞检测,导致射线会直接穿过与player接触的Ground平台的碰撞盒,所以发现player与平台完全接触时无法跳跃,而与平台快要接触的时候时可以跳跃的。

解决方法
可以将射线的起始位置向上移动0.1f,同时将射线的长度也加长0.1f:

	private void Raycast()
    {
        RaycastHit hit;
        Vector3 origin = sphereCollider.bounds.center + new Vector3(0,-sphereCollider.bounds.extents.y+0.1f,0);
        isGround = Physics.Raycast(origin,Vector3.down,out hit,0.11f,1<<6);
        print(hit.point);
        Debug.DrawLine(origin, hit.point,Color.red);
    }

这样就可以避免origin和碰撞盒重叠的问题

在2D平面上跳跃出现的奇怪现象

如果将Ground换成一个平面,比如:
在这里插入图片描述

让player在一个平面上跳跃,而且origin与平面的碰撞盒重叠时,会出现上面1、4象限可以跳跃,2、3象限不能跳跃的情况。
也就是说,射线下一半平面可以检测到碰撞,另一半平面不能检测到碰撞

目前还不知道什么原因

另外,在做2D场景的时候,即使origin与平面的碰撞盒重叠也能检测到碰撞,不需要对起始点origin进行处理。

总之,在3D场景下使用这种方法做跳跃检测还是要对origin坐标的位置做一下处理的

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值