返回首页DA系统C#IDE文件同步服务屏保 今天是: 2026-05-05    "立夏"  夏季的第一个节气,表示盛夏时节的正式开始

搜索
热搜: linux 技术
Hi~登录注册
查看: 4936|回复: 0

[原创] 【原创】物理引擎-碰撞器及触发器的讲解

[复制链接]
发表于 2021-12-3 18:22:52 | 显示全部楼层 |阅读模式

少侠不来段修仙之旅吗~

您需要 登录 才可以下载或查看,没有帐号?注册成为修仙之旅的少年~

x
本帖最后由 da11 于 2021-12-3 18:24 编辑

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

/// <summary>
/// 物理引擎讲解类
/// </summary>
public class PhysicsEngineDemo : MonoBehaviour
{
/* 什么是物理引擎:
* · 带有刚体组件的游戏物体
*   Add Component--physics--Rigidbody
* · 刚体组件可使游戏对象受物理引擎控制,在受到外力时产生真实世界中的运动。
* · 碰撞器(Collider):让物体有了物理的边界,只有知道了物理的边界,才可以开始模拟物理中力的作用!
* · 物理引擎(Rigidbody(刚体)):模拟真实世界中物理物理特性的引擎。
*
* 在游戏物体挂载上Rigidbody(刚体)组件即有物理引擎效果,需配合上碰撞器使用
* 注意:手游(硬件性能一般)的设备,碰撞器检测一般使用Box Collider检测,只有检测8个面,节省资源
* 碰撞器检测的最精细为Mesh Collider检测,这是根据模型的点和面来检测的,消耗CPU资源巨巨巨巨大。
* 如想高精度模拟,优先选择原模型最贴切的碰撞器类型,高精度模拟一般使用Sphere Collider检测,这是根据圆形的面数检测。这是系统自带最高精度的碰撞器。
* 实在需求需要高精度模拟,才使用Mesh Collider碰撞器。
* 使用Mesh Collider碰撞器时,勾上Convex可以优化模型点数和面数,从而尽量降低消耗的资源。
* Box Collider碰撞器可以设置碰撞器的中心点(x,y,z)和碰撞器的大小(x,y,z).
* Sphere Collider碰撞器可以设置碰撞器的中心点(x,y,z)和碰撞器的缩放大小(x,y,z).
*
* Rigidbody(刚体)组件的属性值
* · Mass-质量,描述物体的质量,多物体有Rigidbody组件的时候使用。
* · Drag-阻力,广泛意义上的阻力,当受力移动时物体受到的空气阻力。
*   0表示没有空气阻力,极大时可使物体停止运动,通常砖头0.001,羽毛设置为10
* · Angular Drag-角阻力:当受扭力旋转时物体受到的空气阻力。
*   0表示没有空气阻力,极大时可使物体停止运动
* · Use Gravity-使用重力:若激活,则物体受重力影响。
* · Is Kinematic-是否是运动学(霸体):若激活,该物体不再受物理引擎控制
*   而只能通过变换组件来操作。
*   
* · Interpolate-插值:用于缓解刚体运动时的抖动。
*   None-无--不应用插值
*   Interpolate--内插值:基于上一帧的变换来平滑本帧变换。
*   Extrapolate--外插值:基于下一帧的预估变换来平滑本帧变换。
*   
* · Collision Detection-碰撞检测:碰撞检测模式。
*   快速移动的刚体在碰撞时有可能互相穿透,可以设置碰撞检测频率,
*   但频率越高对物理引擎性能影响越大。
*   
*   Discrete--不连续:不连续碰撞检测。适用于普通碰撞(默认模式)。
*   Continuous--连续:连续碰撞检测。
*   Continuous Dynamic--动态连续:连续动态碰撞检测,适用于高速物体。
*   
* · Constraints-约束:对刚体运动的约束
*   Freeze Position--冻结位置:刚体在世界中沿所选X,Y,Z轴的移动,将无效。
*   Freeze Rotation--冻结旋转:刚体在世界中沿所选X,Y,Z轴的旋转,将无效。
*   
* 碰撞条件
* · 两者具有碰撞组件(碰撞器组件)
* · 运动的物体具有刚体组件。
*
* 碰撞三阶段脚本周期,须有Collision类型的形参
* · 当进入碰撞时执行
*   void OnCollisionEnter(Collision collOther)
* · 当碰撞体与刚体接触时每帧执行
*   void OnCollisionStay(Collision collOther)
* · 当停止碰撞时执行
*   void OnCollisionExit(Collision collOther)
*   
* 碰撞器简介
* · 带有碰撞器组件,且Is Trigger属性被勾选的物体。
* · 现象:无碰撞效果
*
* · 注意:带有碰撞器组件,且Is Trigger属性被勾选的物体是触发器,
*   带有碰撞器组件,Is Trigger属性 没有 被勾选的物体是碰撞器
*
* 触发条件
* · 两者具有碰撞器(Collider)组件
* · 其中之一带有刚体(Rigidbody)组件,(都带有刚体(Rigidbody)组件也算满足条件)
* · 其中之一勾选Is Trigger属性,(都勾选Is Trigger属性也会满足条件233)
*
* 触发三阶段
* · 当碰撞器(Collider)进入触发器时执行
*   void OnTriggerEnter(Collider cldOther)
*   
* · 当碰撞器(Collider)与触发器接触时每帧执行
*   void OnTriggerStay(Collider cldOther)
*   
* · 当停止触发时执行
*   void OnTriggerExit(Collider cldOther)
*/

    //当满足碰撞接触条件!!这个逻辑重点
    //当碰撞接触第一帧执行以下脚本生命周期方法
    private void OnCollisionEnter(Collision collision)
    {
        //事件参数类
        //形参collision 获取对方的碰撞器组件,或者直接获取 对方 的组件collision.collider.GetComponent<?>
        print("check--OnCollisionEnter:   "+ collision.collider.name);

        //碰撞器的参数可以获得碰撞点数组
        print(collision.contacts.Length);

        //获取第一个接触点
        //ContactPoint CP = collision.contacts[0];

        //获取第一个接触点的 世界 坐标
        //print(CP.point);

        //获取碰撞的所有接触点
        int CPL = collision.contacts.Length;
        for (int i = 0; i < CPL -1; i++)
        {

            print(collision.contacts.point);
        }

        //获取接触面法线(直白点说就是撞的方向)
        Vector3 CNormal = collision.contacts[0].normal;

        //collision.transform.position = new Vector3(0, 0, 0);

        //获取对方的GameObject组件,并使用Object.Destroy销毁对方游戏物体
        //Object.Destroy(collision.collider.gameObject);
    }

    //当满足触发条件!!
    //当触发第一帧执行以下脚本生命周期方法
    private void OnTriggerEnter(Collider colliderVar)
    {
        //形参colliderVar 就是对方的碰撞器组件,直接获取 对方 的组件colliderVar.GetComponent<?>
        print("check--OnTriggerEnter:   " + colliderVar.name);

    }



    /*
    public void FixedUpdate()
    {
        //Time.frameCount 属性是查看当前过了多少帧帧
        print(Time.frameCount + "--" + this.transform.position);

        this.transform.Translate(0, 0, Time.deltaTime * movespeed);
    }
    */

    //注意:如果movespeed物体移动速度过快(一般大于200以上),碰撞检测方法(OnTriggerEnter、OnCollisionEnter)将失效
    //解决方案:游戏开始时,使用射线检测
}


游客
回复
*滑块验证:

DA论坛飞机票来了~
快速回复 返回顶部 返回列表