Unity 2D 碰撞器卡在墙上?

Unity 2D Colliders Stuck to Walls?

今天早上我刚刚将 Unity 从 5.0.0 更新到 5.2.1 版本,但遇到了一些问题。在 Unity 将游戏转换为适用于新版本后,我测试了游戏。一切正常,除了当我在游戏中射出一颗子弹时,它们会粘在墙上而不是从墙上弹开,但仅限于特定的角度和距离。就好像子弹太快了,它没有击中对撞机,而是卡在了对撞机里面。这有点道理,但奇怪的是我有一个 C# 脚本用于游戏中的慢动作。每当我打开慢动作然后再次将其关闭时,子弹粘住的问题就会消失。我似乎无法弄清楚是什么导致了问题,而且在我更新软件之前它肯定不存在。谁能帮我解决这个问题?谢谢。我会 post 下面的子弹脚本和慢动作脚本。顺便在player脚本里面实例化了子弹

子弹脚本:

using UnityEngine;
using System.Collections;

public class Bullet : MonoBehaviour {

public float bulletSpeed;
public float bulletOpacity;
public bool fadeOut;

Animator anim;
Rigidbody2D rigidbod;
SpriteRenderer spriterend;

public GameObject player;
public float aimRotation;

// Use this for initialization
void Start () {

    anim = GetComponent<Animator> ();
    rigidbod = GetComponent<Rigidbody2D> ();
    spriterend = GetComponent<SpriteRenderer> ();

    rigidbod.velocity = transform.right * bulletSpeed;
    rigidbod.gravityScale = 0;

    bulletOpacity = 1;

}

// Update is called once per frame
void Update () {

    Destroy (gameObject, 3f);

    spriterend.color = new Color (1f, 1f, 1f, bulletOpacity);

    if (fadeOut == true)
        bulletOpacity -= 0.03f;

    if (bulletOpacity <= 0)
        Destroy (gameObject);

    aimRotation = player.GetComponent<Player> ().aimRotation;

}

void OnTriggerEnter2D (Collider2D bulletHit) {

    /*if (bulletHit.gameObject.layer == LayerMask.NameToLayer ("vulnerableLayer")) {

    }*/
    rigidbod.gravityScale = 1;
    rigidbod.drag = 1;
    fadeOut = true;

}

}

慢动作脚本:

using UnityEngine;
using System.Collections;

public class SlowMotion : MonoBehaviour {

public float currentLongevity = 0f;
public float slowAmount = 0.2f;
public float normalTime = 1f;
public float slowLongevity = 0.4f;


// Use this for initialization
void Start () {

}

// Update is called once per frame
void Update () {

    if (Input.GetMouseButtonDown (1)) {
        Time.fixedDeltaTime = 0.0f * Time.timeScale;
        if (Time.timeScale == normalTime)
            Time.timeScale = slowAmount;
    }

    if (Time.timeScale == slowAmount) {
        currentLongevity += Time.deltaTime;
    }

    if (currentLongevity > slowLongevity) {
        currentLongevity = 0;
        Time.timeScale = normalTime;
    }

}
}

由于您指出 'weird' 项目符号行为在 SlowMotion 脚本为 运行 后停止,我建议问题与设置 Time.fixedDeltaTime 有关,就像您在SlowMotion 脚本的 Update() 方法。您后来的评论也支持这一点,即当您将 rigidBody2D 的碰撞检测设置为连续时(我假设是子弹的 RigidBody2D),'weird' 行为不再出现。

Continuous RididBody2D collision detection enables determining if contact occurred between updates, where as Discrete 碰撞检测在物理更新 期间注册碰撞。在您的 SlowMotion 脚本中,以下行(在 Update() 方法中)将 fixedDeltaTime 设置为 zero:

Time.fixedDeltaTime = 0.0f * Time.timeScale;

Time.fixedDeltaTime is the interval in seconds at which physics and other fixed frame rate updates are performed, there must be some minimum value at which the frame rate is realistically run, (0.0 cannot be an actual frame-rate update interval). When Time.fixedDeltaTime == 0.0, Unity may use a default minimum value or use this to indicate that frame updates run as often as possible, (though I have not tested this). Since the Bullet script calls Update() rather than FixedUpdate(), there is no guarantee that the actual interval between the frame updates is uniform。我怀疑当您 运行 SlowMotion 脚本并将 Time.fixedDeltaTime 设置为 0.0 时,Unity 运行s 具有尽可能小的帧更新间隔并遵循此,它确实会呈现预期的子弹行为。

测试此方法的一种方法是在编辑器中将初始 Time.fixedDeltaTime 设置为 0.0(并且将子弹的 RididBody2D 的碰撞检测行为恢复为离散)。

在编辑器中设置Time Manager fixedDeltaTime主菜单->编辑->项目设置->时间

如果您找到一个可用的 fixedDeltaTime,您可以在编辑器中设置它并在您的 SlowMotion 脚本中的 Awake() 方法中检索初始值以初始化基本的 fixedDeltaTime。我不建议使用 fixedDeltaTime == 0.0,因为文档中没有指示时间间隔为 0.0 的一致行为,并且它可能更多地绑定到底层硬件,并可能导致更多意外行为。

希望这对您有所帮助,干杯!