OnTrigger事件使用延迟

时间:2018-04-11 14:13:16

标签: unity3d triggers collision particle-system

我有一个带有粒子系统和贴花的子弹脚本。

我认为它与这些事件有关,无法及时触发或在更新时使用fps。还不确定。

所以,现在已经很晚了。 低点是粒子开始播放的地方。他们应该在这些木墙上。应该有三个粒子工作,三个弹孔,有点子弹穿透一面墙,并在第二个墙上被摧毁。

问题是如何让它正常工作,这些触发器在需要时如何以及粒子和标记一样工作?也许有办法优化代码按时工作?或许这可能是另一个问题?

屏幕截图:enter image description here 守则:

public class BulletScript : MonoBehaviour {

public bool isThrough = true;
public float BulletSpeed = 100;
public float CurrentDamage;
public float EnterLuft = -0.005f;
public float ExitLuft = 0.05f;
public GameObject woodParticle;
private ContactPoint CollisionPoint;
public GameObject BulletMarkPref;
Rigidbody bullet;

private void Start()
{
    bullet = this.GetComponent<Rigidbody>();
}

void FixedUpdate () {
       bullet.velocity = Vector3.forward * BulletSpeed;
    //this.transform.Translate(Vector3.forward * BulletSpeed * Time.deltaTime);
}

private void OnTriggerEnter(Collider other)
{
    Transform hitPoint = this.transform;
    LevelObject.LvlObjectType objectType = other.gameObject.GetComponent<LevelObject>().objType;
    if(objectType == LevelObject.LvlObjectType.obstacle)
    {
        if (isThrough)
        {
            Instantiate(woodParticle, hitPoint.localPosition, Quaternion.LookRotation(-hitPoint.forward)).GetComponent<ParticleSystem>().Play();
            LeaveBulletMark(this.transform, true);
        }
        else
        {
            Instantiate(woodParticle, hitPoint.localPosition, Quaternion.LookRotation(-hitPoint.forward)).GetComponent<ParticleSystem>().Play();
            LeaveBulletMark(hitPoint, true);
            Destroy(this.gameObject);
        }
    }
    else if(objectType == LevelObject.LvlObjectType.obstacle)
    {
        Destroy(this.gameObject);
    }
    else if(objectType == LevelObject.LvlObjectType.wall)
    {
        LeaveBulletMark(hitPoint, true);
        Destroy(this.gameObject);
    }
}

private void OnTriggerExit(Collider other)
{
    Transform hitPoint = this.transform;
    Instantiate(woodParticle, hitPoint.localPosition, hitPoint.rotation).GetComponent<ParticleSystem>().Play();
    LeaveBulletMark(hitPoint, false);
}

void LeaveBulletMark(Transform hitPoint, bool ifEnter)
{
    GameObject TemporaryBulletMarkHandler;
    TemporaryBulletMarkHandler = Instantiate(BulletMarkPref, hitPoint.localPosition, Quaternion.LookRotation(ifEnter ? hitPoint.forward : CollisionPoint.normal)) as GameObject;
    isThrough = false;
    TemporaryBulletMarkHandler.transform.Translate(hitPoint.forward * (ifEnter ? 0.005f : -0.005f));
}
}

1 个答案:

答案 0 :(得分:1)

我不认为你的问题与代码有关。计算快速移动的物体(例如子弹)具有真正的物理计算,尤其是如果它们很小,则存在固有的问题。通常在物理更新之间,它们完全穿过墙壁碰撞器而无需注册。

你必须这样想才能看到问题。子弹沿其轨迹不连续跟踪。它有一个起始位置,一个运动公式,并在每次物理更新时计算一个新位置。你可以直接在墙上发射子弹,并且在一次更新中,子弹将在墙前几米处,而在下一个,它将在墙后几米处,而不会引发碰撞。这就是为什么这么多游戏使用射线追踪来计算子弹轨迹的原因。子弹运动并不完全准确,特别是对于远射,但子弹路径的障碍物已被记录。

默认情况下,Unity的物理引擎以每秒50帧的速度运行。现代子弹的行进速度在1200到1700米/秒之间。这使您可以在帧之间移动24到34米之间的距离。即使是以最终速度(54 m / s)下降的小物体也可能会被忽视。如果你制作了一个1米厚的箱式对撞机,你可能会注册掉落物体而不是子弹。

我认为你可以做一些聪明的光线追踪和子弹物理组合,以获得两全其美的效果。也许你可以在每个固定的更新中从子弹射线追踪,或者可能有一些更好的技术已经针对我不知道的这种确切情况发明了。