Unity 中的 Buggy 子弹碰撞一致性

问题描述 投票:0回答:1

我的 FPS 项目中的子弹碰撞问题相当多。也就是说,有时,子弹会记录碰撞,有时却不会。看来两者之间的差异恰好与我们站在自己和目标之间的位置有关,但有时情况并非如此(即我们稍微移动回刚刚射击的同一位置并发生碰撞)可能会再次工作)。

为了简单地解决这个问题,我将留下一个链接,指向我针对此问题所做的大量 Reddit 帖子:https://www.reddit.com/r/Unity3D/comments/18g4dr8/comment/ke7x2k7 /?上下文=3

问题的当前状态是该错误仍然有效,并且自我上次测试以来没有任何真正的改变。如果你们需要有关此事的更多信息,请告诉我。

unity-game-engine collision-detection
1个回答
0
投票

在不知道您当前的代码的情况下,我很难判断,但对我来说,这听起来像是“隧道”的情况。您可以在[此处]找到非常好的解释(https://gamedev.stackexchange.com/a/192403)。

简而言之:您的物体在一帧中仍然位于碰撞物体的前面,而在下一帧中则位于碰撞物体的后面。所以它实际上永远不会碰撞/触发。

在 Unity 中,有多种方法可以解决这个问题。我将介绍两个最简单和常见的。在大多数情况下,光线投射方法是最好的方法。

持续碰撞

调整物体的碰撞器设置,将“碰撞检测”属性设置为“连续”或“连续动态”,这样Unity就可以进行更准确的碰撞检查,特别是对于快速移动的物体这是必要的。

光线投射

基本上,您必须从最后一帧到当前帧位置执行光线投射,以避免隧道问题。这样光线就会击中上一帧和本帧之间的所有物体。示例:

using UnityEngine;

public class Bullet : MonoBehaviour
{
    private Vector3 lastPosition;
    private float bulletSpeed = 1000.0f;

    void Start()
    {
        lastPosition = transform.position;
    }

    void Update()
    {
        lastPosition = transform.position;

        // Move the bullet to its next position
        transform.Translate(transform.forward * Time.deltaTime * bulletSpeed);

        // Perform raycast from last position to current position
        CheckForCollisions();
    }

    void CheckForCollisions()
    {
        // Calculate the direction the bullet moved
        Vector3 movedVector = transform.position - lastFramePosition;

        // Cast a ray from the last position to the current position
        // `QueryTriggerInteraction.Collide` including triggers
        RaycastHit hit;
        if (Physics.Raycast(lastPosition, movedVector.normalized, out hit, movedVector.magnitude, QueryTriggerInteraction.Collide))
        {
            HandleCollision(hit.collider);
        }
    }

    void HandleCollision(Collider otherCollider)
    {
        Debug.Log("Bullet hit: " + otherCollider.gameObject.name);
        Destroy(gameObject);
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.