C# 运动学刚体自行运动

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

在我的2D Unity游戏中,我遇到了一个非常奇怪的问题,我能够将其归结为以下核心问题/最小复制测试用例。按照以下步骤复制(Unity 5.1.1f1):

  • 在位置
    (0,0,0)
    创建播放器对象(立方体)
  • 卸下
    BoxCollider
    组件
  • 附加以下
    c35;
    脚本,Unity将自动添加所需的组件,从而使其成为刚体碰撞器
  • 设置
    iskinetic
    标志
  • 将另一个立方体添加到场景的位置
    (2,0,0)
  • 卸下
    BoxCollider
    组件并添加
    BoxCollider2D
    。这使得这个立方体成为一个静态碰撞器
  • 设置
    isTrigger
    标志
  • 运行场景
预期行为:
玩家立方体向另一个立方体加速,一旦碰到它就停止移动

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

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

解决问题的尝试失败:

  • 切换到
    Update()
    Time.deltaTime
    没有任何区别
  • 我尝试在
    Update()
    中不返回,而是在设置
    stop
    时将
    timestep
    重置为
    0
    。没有变化
  • 摆弄检查员和做一些事情,比如冻结刚体上的位置,或者将玩家对象设置为触发器,都没有任何效果。在游戏运行时(碰撞后)更改刚体组件上的任何内容都会使立方体立即停止。实际上是任何东西,甚至将其质量设置为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;
    }
}
使用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
将禁用整个发动机。在这一点上,对象应该是