Unity开发:如何通过if语句检测prefab的rotation是否发生变化
旋转检测逻辑修复方案
原代码核心问题
- Unity 中
Transform.localEulerAngles的返回值范围固定为 0~360,不存在负值,原判断中所有小于0的条件永远无法触发 - 条件判断存在语法逻辑错误:
eulerAngY < 0 && eulerAngY > 0是永假命题,不可能满足 - 缺少初始旋转基准值:没有存储预制体初始化时的原始旋转作为对比参照,直接和0值对比不适用初始旋转非0的场景
- 直接对比欧拉角存在天然缺陷:会遇到万向锁、360度跳变问题(例如359°和1°实际仅差2°,直接数值对比会误判为差异极大)
pawnName变量从未赋值,即使判断触发日志也会显示空值
修复后代码
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Pawn : MonoBehaviour { private string pawnName; public Transform tf; // 存储初始旋转作为对比基准 private Quaternion initialLocalRot; // 旋转误差阈值,单位为度,可在Inspector面板调整 public float rotateThreshold = 1f; [SerializeField] float eulerAngX; [SerializeField] float eulerAngY; [SerializeField] float eulerAngZ; public void Start() { tf = GetComponent<Transform>(); // 保存初始本地旋转 initialLocalRot = tf.localRotation; // 初始化对象名变量 pawnName = gameObject.name; } public void OnTriggerEnter(Collider other) { } public void PawnHasFallen() { eulerAngX = transform.localEulerAngles.x; eulerAngY = transform.localEulerAngles.y; eulerAngZ = transform.localEulerAngles.z; Debug.Log("Calling this script"); // 用四元数计算当前旋转和初始旋转的角度差 float rotateDiff = Quaternion.Angle(tf.localRotation, initialLocalRot); // 差值超过阈值即判定为发生了旋转 if (rotateDiff > rotateThreshold) { Debug.Log(pawnName + " Has Fallen"); } } }
补充说明
- 可根据需求在Inspector面板调整
rotateThreshold的数值,避免物理引擎微小抖动导致的误判 - 如果需要检测世界坐标系下的旋转变化,将代码中所有
localRotation替换为rotation即可
内容的提问来源于stack exchange,提问作者Benjamin Venema
相关产品推荐
相关产品推荐

