当前位置: 首页 > news >正文

Unity物理响应函数与触发器

一、物理响应函数(碰撞检测)

用于处理刚体间的物理碰撞,要求双方均有 Collider,且至少一方有 Rigidbody。双方 Collider 均不能勾选 Is Trigger

  1. OnCollisionEnter(Collision collision)

    • 触发时机:碰撞发生的第一帧(接触瞬间)
    • 典型场景:球撞击地面时播放音效
    void OnCollisionEnter(Collision collision) {if (collision.gameObject.tag == "Ground") {PlaySound("impact");}
    }
    

  2. OnCollisionStay(Collision collision)

    • 触发时机:碰撞持续期间每帧调用(除首尾帧)
    • 典型场景:物体在斜坡上滑动时持续施加摩擦力
    void OnCollisionStay(Collision collision) {ApplyFriction(collision.contacts[0].normal);
    }
    

  3. OnCollisionExit(Collision collision)

    • 触发时机:碰撞结束的分离瞬间
    • 典型场景:玩家离开平台时取消特殊状态
    void OnCollisionExit(Collision collision) {if (collision.gameObject.name == "MovingPlatform") {player.ResetState();}
    }
    


二、触发器响应函数

用于检测物体进入特定区域,要求:

  • 至少一方 Collider 勾选 Is Trigger
  • 至少一方有 Rigidbody(可为 Kinematic)
  1. OnTriggerEnter(Collider other)

    • 触发时机:另一物体进入触发器区域的第一帧
    • 典型场景:玩家拾取道具
    void OnTriggerEnter(Collider other) {if (other.CompareTag("Coin")) {Destroy(other.gameObject); // 销毁金币AddCoins(1);}
    }
    

  2. OnTriggerStay(Collider other)

    • 触发时机:物体停留在触发器内每帧调用
    • 典型场景:持续区域伤害(如毒圈)
    void OnTriggerStay(Collider other) {if (other.CompareTag("Player")) {other.GetComponent<Player>().TakeDamage(1); // 每帧扣血}
    }
    

  3. OnTriggerExit(Collider other)

    • 触发时机:物体离开触发器区域的第一帧
    • 典型场景:离开安全区警告
    void OnTriggerExit(Collider other) {if (other.CompareTag("Player")) {ShowWarning("离开安全区域!");}
    }
    


三、触发条件对比分析
条件碰撞响应 (OnCollision*)触发器响应 (OnTrigger*)
Collider 要求双方均非 Trigger至少一方为 Trigger
Rigidbody 要求至少一方有 Rigidbody至少一方有 Rigidbody
物理效果产生物理力(反弹/摩擦)无物理效果(直接穿透)
性能消耗较高(需计算物理反馈)较低(仅检测重叠)
典型应用场景物理交互(弹跳、推箱子)逻辑检测(收集品、陷阱)

四、关键注意事项
  1. 刚体运动类型影响

    • Kinematic Rigidbody:可触发碰撞/触发器事件,但不受物理力影响
    • Dynamic Rigidbody:参与完整物理模拟
  2. 静态碰撞体限制

    • 无 Rigidbody 的静态 Collider 可参与碰撞,但无法触发 OnTriggerEnter 等事件
  3. 执行顺序
    所有物理响应均在 FixedUpdate() 后执行,与渲染帧无关

  4. 优化建议

    • 避免在 Stay 函数中执行复杂计算
    • 使用 Layer 过滤不必要的碰撞检测:
    void OnCollisionEnter(Collision collision) {if (collision.gameObject.layer != LayerMask.NameToLayer("Enemy")) return; // 跳过非敌人层
    }
    

通过合理选择碰撞/触发器响应,可高效实现物理交互与游戏逻辑检测。

http://www.dtcms.com/a/287826.html

相关文章:

  • LVS详解
  • GitHub 趋势日报 (2025年07月18日)
  • 【图像处理基石】什么是小波变换?
  • CAN总线负载率计算及示例说明
  • 【CVPR2025】计算机视觉|RORem:让物体移除“脱胎换骨”!
  • Streamlit 官翻 2 - 开发指南 Develop Concepts
  • 昇思+香橙派 AI 开发实践:DeepSeek 全流程指南(基于 openEuler)
  • lesson18:Python函数的闭包与装饰器(难)
  • TypeScript 泛型详解:从基础到实战应用
  • 3.条件判断:让程序学会做选择
  • Web开发 03
  • import.meta.glob 与 import.meta.env、import的几个概念的简单回顾
  • react+antd+表格拖拽排序以及上移、下移、移到顶部、移到底部
  • 408数据结构强化(自用)
  • 实现el-select下拉框,下拉时加载数据
  • MYSQL 第一次作业
  • 《命令行参数与环境变量:从使用到原理的全方位解析》
  • Flink实时流量统计:基于窗口函数与Redis Sink的每小时PV监控系统(学习记录)
  • UniApp 自定义导航栏:解决安全区域适配问题的完整实践
  • C++基于muduo库从零实现Rpc框架
  • Ubuntu18.04环境下,vscode使用clangd、bear实时准确跳转过程中遇到的compile_commands.json无法解析问题
  • windows wsl ubuntu 如何安装 maven
  • 程序混淆的可行性?
  • PyCharm 入门指南:起步学习、开发环境一体
  • java: DDD using sql server 2019 or Oracle21c
  • WLAN Autoconfig 自启动失效/WIFI功能消失问题解决方案
  • Gradle安装教程
  • 深入理解设计模式之模板模式:优雅地定义算法骨架
  • 在RK3588开发板快速搭建ros环境以及运行ros程序(以usb_cam为例)
  • 云服务器搭建自己的FRP服务。为什么客户端的项目需要用Docker启动,服务端才能够访问到?