程序员开发实例大全宝库

网站首页 > 编程文章 正文

7.Unity刚体与碰撞(unity物体碰撞)

zazugpt 2024-10-24 19:25:00 编程文章 18 ℃ 0 评论

7.刚体与碰撞

7.1 刚体

使用刚体(Rigidbody)组件可以让对象使用 Unity 内置的物理引擎。

添加刚体组件时先选中对象,单击 Add Component -> Physics -> Rigidbody 即可。

刚体属性:

  • Mass - 任意单元中对象的质量。
  • Drag - 对象在移动时的空气阻力。
  • Angular Drag - 转动时的空气阻力。
  • Use Gravity - 是否对对象应用重力计算。
  • Is Kinematic - 是否受 Unity 的物理学影响。
  • Interpolate - 对象的运动是否平滑。
  • Collision Detection - 确定碰撞的计算方式。
  1. Discrete :相对于彼此来测试所有的对象。
  2. Continuous : 在检测极快的对象碰撞时使用,对性能影响较大。
  3. Continuous Dynamic : 对于离散对象使用离散检测,对应连续对象使用连续检测
  • Constraints - 刚体施加于对象的运动限制。冻结位置轴将阻止对象沿该轴移动,冻结旋转轴将阻止对象绕该轴旋转。

7.2 碰撞

碰撞器(Collider)组件是投射在对象周围的边界,当其他对象进入其中时可以检测。

对象不需要刚体也能发生碰撞,碰撞只需要所设计的两个对象具有一个碰撞器对象即可。

7.2.1 碰撞器

对于没有碰撞器的对象,可以通过 Add Component -> Physics 选择一个碰撞器即可。

碰撞器的属性:

  • Is Trigger - 确定碰撞器是物理碰撞器还是触发碰撞器。
  • Material - 碰撞器的物理材质。
  • Center - 碰撞器相对于包含对象的中心点。
  • Size - 碰撞器的大小。
  • 几何属性 - 对于球体或胶囊碰撞器,会具有一下额外的几何属性,如 Radius。

在对象上可以使用不同形状的多个碰撞器。Mesh Collider(网格碰撞器)是一种具有 3D 模型的精确形状的碰撞器。虽然看上去有用,但在实际中使用会极大地降低性能。所以在实际中,同时使用多个碰撞器组成复杂的碰撞器才是最有效的方法。

7.2.2 物理材质

创建物理材质,在 Project 窗口中右击选择 Create -> Physic Material。

物理材质的属性:

  • Dynamic Friction - 对象移动时应用的摩擦力,数值越小对象越光滑。
  • Static Friction - 对象静止时应用的摩擦力,数值越小对象越光滑。
  • Bounciness - 碰撞保留的能量值,1会导致对象弹跳,而不会损失任何能量;0会阻止对象弹跳。
  • Friction Combine - 确定如何计算两个碰撞对象的摩擦力。可以使用平均值、最小或最大值,也可以相乘起来。
  • Bounce Combine - 确定如何计算两个碰撞对象的弹力。可以使用平均值、最小或最大值,也可以相乘起来。
  • Friction Direction 2 - 给对象在特定方向具有不同的摩擦力。
  • Dynamic Friction 2 - 应用于指定方向的动态摩擦力。
  • Static Friction 2 - 应用于指定方向的静态摩擦力。

使用物理材质时,只需要将物理材质拖拽到对象上。

7.2.3 物理碰撞

碰撞器的 Is Trigger 不勾选的情况下为物理碰撞。物理碰撞的事件如下:

状态

Collision 模式

调用次数

碰撞时

OnCollisionEnter2D|OnCollisionEnter

一次

碰撞的过程中

OnCollisionStay2D|OnCollisionStay

持续调用

碰撞结束时

OnCollisionExit2D|OnCollisionExit

一次

7.2.4 触发碰撞

碰撞器的 Is Trigger 勾选的情况下为触发碰撞,触发器可以检测碰撞,当检测到碰撞后会调用如下方法:

状态

Trigger 模式

调用次数

碰撞时

OnTriggerEnter2D|OnTriggerEnter

一次

碰撞的过程中

OnTriggerStay2D|OnTriggerStay

持续调用

碰撞结束时

OnTriggerExit2D|OnTriggerExit

一次

  • void OnTriggerEnter(Collider other)
  • void OnTriggerStay(Collider other)
  • void OnTriggerExit(Collider other)

other 是进入触发器的UI下的引用,使用该变量可以操作相应的对象。

要让触发器工作,必须涉及到一个刚体,如果不带刚体的对象进入触发器,则什么也不会发生。

示例:

创建新的项目,在场景中添加一个立方体和一个球体,立方体的位置(-1,1,-5),球体的位置(1,1,-5)。

给立方体创建脚本 TriggerScript,给球体创建脚本 MovementScript,并挂载。

TriggerScript 脚本如下:

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

public class TriggerScript : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        
    }

    private void OnTriggerEnter(Collider other)
    {
        print(other.gameObject.name + " has entered the cube");
    }

    private void OnTriggerStay(Collider other)
    {
        print(other.gameObject.name + " is still in the cube");
    }

    private void OnTriggerExit(Collider other)
    {
        print(other.gameObject.name + " has left the cube");
    }
}

MovementScript 脚本如下:

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

public class MovementScript : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        float mx = Input.GetAxis("Mouse X") / 10;
        float my = Input.GetAxis("Mouse Y") / 10;
        transform.Translate(mx, my, 0);
    }
}

运行场景,移动鼠标,观察控制台输出。

7.3 光线投射

光线投射是发出一根假设的射线(即光线)并观察它撞上某个物体之后的动作。使用光线投射可以是实现瞄准、确定视线、测量距离等动作。Unity 中使用 Raycast 方法来实现光线投射。常用的 Raycast 方法:

1.bool Raycast(Vector3 origin, Vector3 direction, float distance, LayerMask mask);

  • origin - 光线开始位置
  • direction - 光线的行进方向
  • distance - 光线的行进距离,省略表示无限远的距离
  • mask - 确定光线会撞上的层,省略表示所有对象类型

2.bool Raycast(Vector3 origin, Vector3 direction, out RaycastHit hit, float distance);

hit - 包含了被撞上的任何对象

示例:

创建新项目,向场景中添加 4 个球体,命名为 Sphere1 ~ Sphere4,位置分别为:(-1,1,-5),(1,1.5,-5),(-1,-2,5),(1.5,0,0)。

创建脚本如下:

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

public class RayController : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        float dirX = Input.GetAxis("Mouse X");
        float dirY = Input.GetAxis("Mouse Y");
        
        transform.Rotate(dirY, dirX, 0);
        CheckForRayCastHit();
    }

    void CheckForRayCastHit()
    {
        RaycastHit hit;
        if (Physics.Raycast(transform.position, transform.forward, out hit))
        {
            print(hit.collider.gameObject.name + "destroyed!");
            Destroy(hit.collider.gameObject);
        }
    }
}

运行游戏,移动鼠标,观察球体的销毁和控制台消息。

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表