Unity2D - 碰撞检测及边界检测

1. 地面检测

1.1 地面检测的逻辑及代码

一般情况下,对于手人物进行事件处理或动作处理时,我们需要判定人物是否在地面上,这个时候最好的方式是设定地面碰撞器,只有角色在地面时才可以进行跳跃; 我们可以想象物体的重心向地面延伸一条射线,射线到里面的距离就是地面监测的距离,如果物体离地面的距离长于射线距离,则判定为不在地面,为了方便编写相应程序,我们将射线可视化出来。

private float groundCheckDistance;
   
private void OnDrawGizmos()
   {
       //程序编写中可视化
       Gizmos.DrawLine(transform.position, new Vector3(transform.position.x,transform.position.y - groundCheckDistance));
       //可以理解为根据提供的两个点,连成一条直线
   }

可视化射线后我们了解物体中心点与地面之间的判定距离。

[SerialField] private LayerMask WhatisGround;
private bool isGrounded;

void Update()
{
    isGrounded = Physics2D.Raycast(transform.position,Vector2.down,groundCheckDistance,WhatisGround);
}

上述代码显示我们如何判定人物与地面间的距离,isGrounded是一个布尔类型的参数,调用Physics2D中的Raycast方法,可以理解为射线检测方法。输入有四个参数,目标位置,检测方向,检测距离,以及检测图层。

图层是我们需要手动拖拽赋给WhatisGround。

Raycast方法最后返回布尔类型参数判定物体是否与地面接触。

1.2 自定义化检测

在实际过程中,我们需要用到不同位置的物体中心点,特别是拥有一个父类之后,子类需要继承到父类的碰撞器。如果能自定义化碰撞器中心点将会大大提高创作效率。

[SerializeField] private Transform groundCheck; // 定义一个位置组件
 

之后的碰撞器以位置组件为基准衡量与地面是否接触,于是我们将之前的碰撞器代码修改为:

    private void OnDrawGizmos()
    {
        //程序编写中可视化
        Gizmos.DrawLine(groundCheck.position, new Vector3(groundCheck.position.x,groundCheck.position.y - groundCheckDistance));
        //可以理解为根据提供的两个点,连成一条直线
    }
}

void Update()
{
    isGrounded = Physics2D.Raycast(groundCheck.position,Vector2.down,groundCheckDistance,WhatisGround);
}

最后在父类对象中创建子类对象,父类对象中的groundCheck用来接收这个子类对象。

2. 障碍物碰撞检测

障碍物检测的实现逻辑与地面检测实现逻辑一样,将内部的参数修改即可。

[SerializeField] private Transform WallCheck;
[SerializeField] private float WallCheckDistance;
private bool isWall;
       
isWall = Physics2D.Raycast(WallCheck.position, Vector2.right * FacingDir, WallCheckDistance, WhatisGround);

Gizmos.DrawLine(WallCheck.position, new Vector3(WallCheck.position.x + WallCheckDistance * FacingDir, WallCheck.position.y ));

3. 玩家碰撞检测

根据上述的过程,对于物体间碰撞已经大差不大了。

在这里我想延伸一种其他物体针对于玩家的碰撞,在之后的创作中将会更加的方便灵活。

判断参数设定为RaycastHit2D类型。

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

public class test : MonoBehaviour
{
    [SerializeField] private float playerCheckDistance;
    [SerializeField] private LayerMask whatIsPlayer;
    private RaycastHit2D isPlayerDetected;
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        isPlayerDetected = Physics2D.Raycast(transform.position, Vector2.right,playerCheckDistance,whatIsPlayer);
        if (isPlayerDetected)
        {
            Debug.Log("I have detected the Player!!!");
        }
    }
}

将玩家设置的图层设置为player,将whatIsPlayer设置为player图层即可。

本质就是图层的检验。 

### 实现 Unity 2D 小球碰撞效果 为了在 Unity 2D 中创建类似于台球游戏的小球碰撞效果,需利用内置的物理引擎来处理物体间的交互。以下是详细的实现方法: #### 创建项目并设置环境 启动 Unity 并新建一个 2D 项目。确保场景中已配置好 Camera 和 Lighting。 #### 添加刚体组件给小球对象 对于每一个代表小球的游戏对象,在 Inspector 面板下为其添加 Rigidbody2D 组件。这允许这些对象参与物理仿真过程[^1]。 ```csharp // C# Script to add rigidbody component programmatically. using UnityEngine; public class BallInitializer : MonoBehaviour { void Start() { GetComponent<Rigidbody2D>(); } } ``` #### 定义碰撞器属性 同样针对每个小球实例,附加 CircleCollider2D 来定义其外形边界用于检测与其他实体接触的情况。调整 Collider 的 Radius 属性匹配实际模型尺寸以获得更精确的结果[^2]。 #### 编写脚本控制逻辑 编写自定义脚本来管理小球之间的相互作用行为,比如施加力矩使它们滚动起来或是反弹离开彼此。下面是一个简单的例子展示了如何响应两颗球相碰事件: ```csharp void OnCollisionEnter2D(Collision2D other) { // Apply force based on collision normal and relative velocity between balls Vector2 direction = new Vector2(other.contacts[0].normal.x, other.contacts[0].normal.y); float speedFactor = Random.Range(5f, 10f); // Add some randomness for realism this.GetComponent<Rigidbody2D>().AddForce(direction * speedFactor); Debug.Log("Collision detected with " + other.gameObject.name); } ``` 此代码片段会在每次发生碰撞时打印日志消息,并向当前物体应用沿碰撞法线方向的力量,从而模仿真实的弹射现象。 #### 调整 Physics Material 参数优化摩擦与弹性表现 通过修改关联材料中的 Friction(摩擦系数)和 Bounciness(回弹程度),可进一步微调最终视觉反馈的质量,使其更加贴近真实世界里的台球体验。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值