C# 运动学刚体自行运动
在我的2D Unity游戏中,我遇到了一个非常奇怪的问题,我能够将其归结为以下核心问题/最小复制测试用例。按照以下步骤复制(Unity 5.1.1f1):C# 运动学刚体自行运动,c#,unity3d,collision-detection,rigid-bodies,C#,Unity3d,Collision Detection,Rigid Bodies,在我的2D Unity游戏中,我遇到了一个非常奇怪的问题,我能够将其归结为以下核心问题/最小复制测试用例。按照以下步骤复制(Unity 5.1.1f1): 在位置(0,0,0)创建播放器对象(立方体) 卸下BoxCollider组件 附加以下c35;脚本,Unity将自动添加所需的组件,从而使其成为刚体碰撞器 设置iskinetic标志 将另一个立方体添加到场景的位置(2,0,0) 卸下BoxCollider组件并添加BoxCollider2D。这使得这个立方体成为一个静态碰撞器 设置isTr
- 在位置
创建播放器对象(立方体)(0,0,0)
- 卸下
组件BoxCollider
- 附加以下
脚本,Unity将自动添加所需的组件,从而使其成为刚体碰撞器c35;
- 设置
标志iskinetic
- 将另一个立方体添加到场景的位置
(2,0,0)
- 卸下
组件并添加BoxCollider
。这使得这个立方体成为一个静态碰撞器BoxCollider2D
- 设置
标志isTrigger
- 运行场景
玩家立方体向另一个立方体加速,一旦碰到它就停止移动 观察到的行为:
玩家立方体向另一个立方体加速,然后继续匀速移动 其他实施细节:
我最初通过平移所有对象的变换来移动它们,并且根本不使用刚体,因为我不需要碰撞检测。现在我想要刚体。我深入到在线资源中,发现我应该使用
rigidbody.MovePosition()
而不是transform.Translate()
或transform.position
。我更改了脚本,出现了上述错误。返回到
transform.position
解决了这个问题,但这不是一个好的解决方案,因为它涉及到坏的实践,据我所读,这会产生大量的CPU负载
解决问题的尝试失败:
- 切换到
和Update()
没有任何区别Time.deltaTime
- 我尝试在
中不返回,而是在设置Update()
时将stop
重置为timestep
。没有变化0
- 摆弄检查员和做一些事情,比如冻结刚体上的位置,或者将玩家对象设置为触发器,都没有任何效果。在游戏运行时(碰撞后)更改刚体组件上的任何内容都会使立方体立即停止。实际上是任何东西,甚至将其质量设置为0
- 我还尝试将
设置为0,结果没有改变。这是有意义的,因为velocity
被完全跳过(顺便说一句,我还用Update()
检查了这一点)Debug.Log()
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;
}
}
使用UnityEngine;
使用系统集合;
[RequireComponent(typeof(boxr2d)、typeof(Rigidbody2D))]
公共类SimpleController2D:MonoBehavior{
公共矢量3速度=矢量3.0;
私有化改造;
私有刚体2d这个刚体;
公共bool-stop=false;
无效唤醒(){
thisTransform=GetComponent();
thisRigidbody=GetComponent();
}
void FixedUpdate(){
float timestep=Time.fixedDeltaTime;//临时存储以便于访问
如果(停止){
return;//命中时冻结
}
velocity.x+=timestep;//加速
/*添加第二个斜杠(/)以在变换和刚体之间切换
thisTransform.position+=速度*时间步/*/
thisRigidbody.MovePosition((向量3)thisRigidbody.position+速度*时间步)//*/
}
无效OnTriggerEnter2D(碰撞的R2D列){
停止=真;
}
}
解决方案
这是Unity 5.1.1f1中的一个bug,已在5.1.1p2及更高版本的补丁中修复
在这里获取:
怎么搞的?
您甚至可以将问题简化为单个
MovePosition
调用<代码>移动位置使用物理引擎移动对象。因此,Unity计算在下一次物理更新中到达目标位置所需的速度。版本5.1.1f1无法在到达位置后将速度重置为零,因此对象将继续以计算出的速度移动。“玩家立方体落在较低的立方体上,然后慢慢向上漂移……我使用的是自制的物理引擎……它也可以工作,不像Unity自己的物理引擎,它一直在做奇怪的事情。”-这是一个相当大胆的说法,因为你的“引擎”与牛顿定律背道而驰,似乎有一个反重力的实现。我的建议是回去看看你在Unity Physics上做错了什么,因为很多人都在毫无问题地使用它,只要我使用静态对撞机,它就可以工作。自从我引入刚体以来,物理引擎就把事情搞砸了。这一运动也可与使用Unity physics引擎的对撞机与其自身碰撞时发生的运动相媲美。但正如你所看到的,没有这样的事情发生。我包括了所有相关的代码(以及所有的替代引擎。请随意给我指出代码中“与牛顿定律相反”的那一行)。发动机非常好,问题就在代码中的某个地方。“请随意给我指出代码中“与牛顿定律相反”的行。”-我不需要。这是你自己承认的“玩家立方体落在较低的立方体上,然后慢慢向上漂移……我正在以你在代码中看到的方式处理重力和碰撞”。我曲解了吗?祝你一切顺利。设置busy=true
将禁用整个发动机。在这一点上,对象应该是