Unity中判断欧拉角y为20时if语句不生效的问题咨询
Unity欧拉角判断异常问题排查
问题现象
Debug.Log输出gameObject.transform.eulerAngles.y为20,但对应的if判断始终不成立;移除欧拉角条件后判断正常,说明实际欧拉角并非精确的20,只是显示为20。但另一段判断eulerAngles.y == 340的代码却能正常工作。
异常代码片段
Debug.Log(gameObject.transform.eulerAngles.y); if (gameObject.transform.eulerAngles.y == 20 && x >= -2) { gameObject.transform.Rotate(0, -20, 0); coolDown = true; }
正常工作的代码片段
if (gameObject.transform.eulerAngles.y == 340 && x <= -11) { gameObject.transform.Rotate(0, 20, 0); coolDown = true; }
完整代码
public float horizontalInput; public int horizontalInput2; public float Speed; public float TimeSpeed; public bool TimeSpeed2; public float TimeSpeed3; public float x; public int yValue = 20; public bool coolDown = true; // Start is called before the first frame update void Start() { } // Update is called once per frame void Update() { if (gameObject.transform.position.x <= -11) { } TimeSpeed3++; if (TimeSpeed3 == 75) { TimeSpeed2 = true; TimeSpeed3 = 0; } if (TimeSpeed == 100) { TimeSpeed2 = true; } if (TimeSpeed == 30) { Speed++; TimeSpeed = 0; if (Speed > 60) { float v = Speed - 0.8f; Speed = v; if (Speed > 100) { v = Speed - 0.18f; Speed = v; } if (Speed >= 105) { v = Speed - 0.2f; Speed = v; } } } x = gameObject.transform.position.x; TimeSpeed++; horizontalInput = Input.GetAxis("Horizontal"); transform.Translate(Vector3.forward * Time.deltaTime * Speed); if (Input.GetKeyDown(KeyCode.LeftArrow) && coolDown == true) { if (horizontalInput < 0) { horizontalInput2 = -1; } transform.Rotate(Vector3.up * 20 * horizontalInput2); if (x <= -11) { transform.Rotate(0, 0, 0); } Debug.Log(coolDown); coolDown = false; } if (gameObject.transform.eulerAngles.y == 340 && x <= -11) { gameObject.transform.Rotate(0, 20, 0); coolDown = true; } else if (Input.GetKeyDown(KeyCode.RightArrow) && coolDown == true) { if (horizontalInput > 0) { horizontalInput2 = 1; } transform.Rotate(Vector3.up * 20 * horizontalInput2); coolDown = false; } Debug.Log(gameObject.transform.eulerAngles.y); if (gameObject.transform.eulerAngles.y == 20 && x >= -2) { gameObject.transform.Rotate(0, -20, 0); } }
问题原因
Unity中transform.eulerAngles.y是浮点数类型,直接用==进行精确比较会因为浮点数精度误差失效。Debug.Log输出时会对浮点数进行四舍五入显示,所以看起来是20,但实际值可能是20.000001或19.999999这类接近20的数值,导致==判断不成立。
而eulerAngles.y == 340能正常工作只是偶然情况,刚好该帧的欧拉角数值没有精度误差,或者误差被忽略了,这种情况不具备通用性。
解决方案
不要直接用==比较浮点数,改用以下两种方式:
方式1:使用Mathf.Approximately比较
Unity提供的Mathf.Approximately专门用于比较浮点数是否近似相等,内部会处理精度问题:
if (Mathf.Approximately(gameObject.transform.eulerAngles.y, 20) && x >= -2) { gameObject.transform.Rotate(0, -20, 0); coolDown = true; }
方式2:判断数值在误差范围内
自定义一个误差阈值(比如0.1),判断欧拉角是否在目标值的阈值范围内:
float targetY = 20; float tolerance = 0.1f; if (Mathf.Abs(gameObject.transform.eulerAngles.y - targetY) < tolerance && x >= -2) { gameObject.transform.Rotate(0, -20, 0); coolDown = true; }
同时建议把另一段==340的判断也改成上述方式,避免后续出现同样的问题。
内容的提问来源于stack exchange,提问作者Idk v.2
相关产品推荐
相关产品推荐

