4

我的 2D Unity 游戏中有一个非常奇怪的问题,我能够将其简化为以下核心问题/最小的重现测试用例。请按照以下步骤重现(Unity 5.1.1f1):

  • 在 location 创建一个玩家对象(Cube)(0,0,0)
  • 移除BoxCollider组件。
  • 附加以下C#脚本,Unity 将自动添加所需的组件,从而使其成为刚体对撞机。
  • 设置isKinematic标志。
  • 在 location 处将另一个 Cube 添加到场景中(2,0,0)
  • 移除BoxCollider组件并添加一个BoxCollider2D. 这使得这个立方体成为一个静态碰撞器。
  • 设置isTrigger标志。
  • 运行场景。

预期行为:
玩家立方体向另一个立方体加速,一旦碰到它就停止移动。

观察到
的行为:玩家立方体向另一个立方体加速,然后继续以恒定速度移动。

附加实现细节:
我最初通过平移所有对象的变换来移动所有对象,并且根本没有使用刚体,因为我不需要碰撞检测。现在我这样做了,所以我想要刚体。我深入研究了在线资源,发现我应该使用rigidbody.MovePosition()而不是transform.Translate()or transform.position。我更改了脚本,出现了上述错误。
回去transform.position解决问题,但这不是一个好的解决方案,因为它涉及不良做法,根据我的阅读,会产生大量的 CPU 负载。

尝试解决失败:

  • 切换到Update()Time.deltaTime没有任何区别。
  • 我尝试不返回,Update()而是简单地将设置重置timestep为。不用找了。0stop
  • 摆弄 Inspector 并做一些事情,比如在刚体上冻结位置或将玩家对象也设置为触发器,这些都没有任何效果。在游戏运行时(碰撞后)更改刚体组件上的任何内容都会使立方体立即停止。从字面上看,任何东西,甚至将其质量设置为 0。
  • 我也尝试设置velocity为0,结果没有变化。这确实是有道理的,因为Update()它被完全跳过了(顺便说一下,我也用 aDebug.Log()进行了检查)。

所以在这一点上,我只写了 30 行代码,我仍然不知道是什么原因造成的。由于涉及的对象是静态触发对撞机和运动学刚体对撞机,两者都没有物理材料,因此一旦设置了标志,就不应该有任何东西可以让这个东西移动。但它确实移动。


SimpleController2D.cs

using UnityEngine;
using System.Collections;

[RequireComponent (typeof (BoxCollider2D), typeof (Rigidbody2D))]
public class SimpleController2D : MonoBehaviour {

    public Vector3 velocity = Vector3.zero;

    private Transform thisTransform;
    private Rigidbody2D thisRigidbody;

    public bool stop = false;

    void Awake () {
        thisTransform = GetComponent<Transform> ();
        thisRigidbody = GetComponent<Rigidbody2D> ();
    }

    void FixedUpdate() {
        float timestep = Time.fixedDeltaTime; // temporarily stored for ease of access
        if (stop) {
            return; // freeze on hit
        }

        velocity.x += timestep; // accelerate
        /* add a second slash (/) to toggle between transform and rigidbody
        thisTransform.position += velocity * timestep; /*/
        thisRigidbody.MovePosition ((Vector3)thisRigidbody.position + velocity*timestep); //*/
    }

    void OnTriggerEnter2D(Collider2D col) {
        stop = true;
    }
}
4

1 回答 1

3

解决方案

这是 Unity 5.1.1f1 中的一个错误,已在补丁版本 5.1.1p2 及更高版本中修复。

在这里获取: http ://unity3d.com/unity/qa/patch-releases?version=5.1

发生了什么?

您甚至可以将问题减少到一个MovePosition呼叫。MovePosition使用物理引擎移动对象。因此,Unity 会计算在下一次物理更新中到达目标位置所需的速度。版本 5.1.1f1 在到达位置后未能将速度重置为零,因此对象将继续以计算出的速度移动。

于 2015-07-13T19:05:19.463 回答