Unity 2019.4中Rigidbody.velocity.y赋值0引发Pong游戏AI异常问题排查
嘿,我仔细看了你的问题和代码,发现这个异常根本不是Unity 2019.4的Bug,而是AI控制脚本里的一个逻辑漏洞导致的循环问题,咱们一步步拆解看看:
看你PlayerController里的AI控制代码:
//AI else { rbBall = ball.GetComponent<Rigidbody2D>(); sign = Mathf.Sign(rbBall.velocity.y); Debug.Log("sign:"+sign); if (sign == -1) { moveInput = -1; } else { Debug.Log("rb.y:"+rb.velocity.y); if (rb.velocity.y != 0) { moveInput = 1; } } } rb.velocity = new Vector2(rb.velocity.x, moveInput * speed);
这里的问题出在球向上运动(sign == 1)时的分支逻辑:你加了一个rb.velocity.y != 0的判断,只有满足这个条件才会把moveInput设为1。但如果AI对象的rb.velocity.y初始是0(比如刚重置游戏后),这个分支就不会执行,moveInput会保持默认值0,导致rb.velocity.y = 0 * speed = 0——这就形成了死循环:
- 球向上 → 进入
sign == 1分支 - AI的
rb.velocity.y是0 → 不设置moveInput = 1 - 赋值后
rb.velocity.y还是0 - 下一帧重复上述步骤,持续输出0
而当球向下运动(sign == -1)时,代码会强制设置moveInput = -1,不管当前rb.velocity.y是什么,所以不会卡壳;球碰撞后速度变负时,同样触发这个强制赋值分支,逻辑正常。
把if (rb.velocity.y != 0)删掉后,只要球向上,就直接设置moveInput = 1,打破了死循环,AI的rb.velocity.y会变成1 * speed,后续帧里这个值不再是0,逻辑就能正常跑起来了。
除了删掉那个多余的判断,我建议你确保AI控制的所有分支都明确给moveInput赋值,避免依赖变量的默认值(万一默认值不是你预期的就麻烦了):
//AI else { sign = Mathf.Sign(rbBall.velocity.y); Debug.Log("sign:"+sign); // 给所有情况明确赋值moveInput if (sign == -1) { moveInput = -1; } else { Debug.Log("rb.y:"+rb.velocity.y); moveInput = 1; // 直接设置向上移动,不需要额外判断 } } rb.velocity = new Vector2(rb.velocity.x, moveInput * speed);
另外,还有个小优化:把rbBall = ball.GetComponent<Rigidbody2D>()移到Start()方法里,别每帧都获取组件,浪费性能:
void Start() { // ... 原有代码 ... rb = GetComponent<Rigidbody2D>(); // 提前获取球的Rigidbody2D组件,不用每帧查 rbBall = ball.GetComponent<Rigidbody2D>(); }
如果你还是怀疑是Unity 2019.4的问题,可以做个极简测试:
- 新建场景,放一个带Rigidbody2D的空物体
- 写个脚本直接设置
rb.velocity = new Vector2(0, 5),然后打印rb.velocity.y
你会发现数值是正常的5,这就能彻底排除版本Bug的可能性了。
内容的提问来源于stack exchange,提问作者Shade

