在我的2D统一游戏中,我有一个非常奇怪的问题,我可以把它简化为下面的核心问题/最小的再现测试用例。按照以下步骤复制(团结5.1.1f1):
(0,0,0)位置创建一个player对象(立方体)。BoxCollider组件。C#脚本,团结将自动添加所需的组件,从而使它成为刚体对撞机。isKinematic标志。(2,0,0)。BoxCollider组件并添加一个BoxCollider2D。这使得这个立方体成为静态对撞机。isTrigger标志。预期行为:
玩家立方体加速到另一个立方体,一旦接触到它就停止移动。
观察行为:
玩家立方体加速到另一个立方体,然后继续以恒定的速度移动。
其他实现详细信息:
最初,我通过翻译所有对象的转换来移动它们,并且根本不使用刚体,因为我不需要碰撞检测。现在我想,所以我想要刚毅。我深入研究了在线资源,发现我应该使用rigidbody.MovePosition()而不是transform.Translate()或transform.position。我更改了脚本,出现了上面的错误。
回到transform.position修复了这个问题,但是这不是一个好的解决方案,因为它涉及到糟糕的实践,根据我所读到的,这会产生大量的CPU负载。
未能解决:
Update()和Time.deltaTime并没有什么区别。Update(),而只是在设置stop时将timestep重置为0。没有变化。velocity设置为0,结果没有发生任何更改。这是有意义的,因为Update()是完全跳过的(顺便说一句,我也用Debug.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;
}
}发布于 2015-07-13 19:05:19
解决方案
这是Unity5.1.1f1中的一个bug,并且在5.1.1p2及更高版本中得到了修复。
到这里来:http://unity3d.com/unity/qa/patch-releases?version=5.1
发生了什么?
您甚至可以将问题简化为一个MovePosition调用。MovePosition使用物理引擎来移动对象。因此,联合计算在下一次物理更新中到达目标位置所需的速度。5.1.1f1版本无法在到达位置后将速度重置为零,因此该对象将继续以计算出的速度移动。
https://stackoverflow.com/questions/31330463
复制相似问题