【问题标题】:Collision detection script fails sometimes碰撞检测脚本有时会失败
【发布时间】:2017-08-25 14:33:27
【问题描述】:

这个脚本在大多数情况下都有效,但是有时敌人会在寻路失败并穿过建筑物或墙壁。有什么办法可以阻止这种情况吗?

using UnityEngine;
using System.Collections;

namespace Daniel {
    public class EnemyAI : Living {

        // Detection private int range = 10; private float speed = 10f; private bool isThereAnyThing = false;

        // Waypoints/Targets
        public GameObject[] targets;
        private float rotationSpeed = 900f;
        private RaycastHit hit;
        GameObject target;
        [SerializeField]
        private int randomTarget = 0;
        [SerializeField]
        float timeToNextCheck = 3;
        public float effectTimer = 2f;
        public GameObject deathEffect;
        public LayerMask detectThis;

        void Start()
        {
            randomTarget = Random.Range(0, 8);
            target = targets[randomTarget];
        }
        void FixedUpdate()
        {
            timeToNextCheck = timeToNextCheck - Time.deltaTime;
            ScanForNewWaypoint();
            LookAtTarget();
            Move();
            CheckForObsticales();
        }
        void LookAtTarget()
        {
            //Look At Somthly Towards the Target if there is nothing in front.
            if (!isThereAnyThing)
            {
                Vector3 relativePos = target.transform.position - transform.position;
                Quaternion rotation = Quaternion.LookRotation(relativePos);
                transform.rotation = Quaternion.Slerp(transform.rotation, rotation, Time.deltaTime);
            }
        }
        void Move()
        {
            // Enemy translate in forward direction.
            transform.Translate(Vector3.forward * Time.deltaTime * speed);
        }
        public void CheckForObsticales()
        {
            //Checking for any Obstacle in front.
            // Two rays left and right to the object to detect the obstacle.
            Transform leftRay = transform;
            Transform rightRay = transform;
            //Use Phyics.RayCast to detect the obstacle
            if (Physics.Raycast(leftRay.position + (transform.right * 7f), transform.forward, out hit, range, detectThis) || Physics.Raycast(rightRay.position - (transform.right * 7f), transform.forward, out hit, range))
            {
                if (hit.collider.gameObject.CompareTag("Obstacles"))
                {
                    isThereAnyThing = true;
                    transform.Rotate(Vector3.up * Time.deltaTime * rotationSpeed);
                }
            }
            // Now Two More RayCast At The End of Object to detect that object has already pass the obsatacle.
            // Just making this boolean variable false it means there is nothing in front of object.
            if (Physics.Raycast(transform.position - (transform.forward * 4), transform.right, out hit, 10, detectThis) ||
                Physics.Raycast(transform.position - (transform.forward * 4), -transform.right, out hit, 10, detectThis))
            {
                if (hit.collider.gameObject.CompareTag("Obstacles"))
                {
                    isThereAnyThing = false;
                }
            }
        }
        public void ScanForNewWaypoint()
        {
            CheckForObsticales();
            if (timeToNextCheck <= 0)
            {
                timeToNextCheck = Random.Range(6, 3);
                randomTarget = Random.Range(0, 8);
                target = targets[randomTarget];
            }
        }
        public override void TakeHit(float dmg, Vector3 hitPoint, Vector3 hitDirection)
        {
            if (dmg >= health)
            {
                Destroy(Instantiate(deathEffect, hitPoint, Quaternion.FromToRotation(Vector3.forward, hitDirection)) as GameObject, effectTimer);
                Debug.Log("Exploded");
            }
            base.TakeHit(dmg, hitPoint, hitDirection);
        }
    }
}

【问题讨论】:

  • 这可能不是合适的做法...但是如果您将FixedUpdate() 更改为Update(),您还有问题吗?
  • 尝试将刚体碰撞检测从离散设置为连续
  • 我可能错了,但您只在主要方向上进行 4 次光线投射,所以光线投射可能只是错过了障碍物(光线投射在障碍物上方或下方等......)。跨度>

标签: c# unity3d artificial-intelligence collision-detection path-finding


【解决方案1】:

好的,现在这是人们在玩 Physics Engine 时遇到的最常见问题之一,相信我,有很多因素会影响您面临的结果/后果。人们设计的最常见的解决方案是使用更新,即每帧执行进行物理计算,这是完全错误。所有与物理相关的计算都需要在 Fixed Update 中执行,否则在 Update 中执行基于物理的模拟将太昂贵,这意味着每一帧。如果您的 敌人 正在穿墙而物理碰撞丢失,您可以采取的最佳解决方案是调整一些 Unity 中的物理相关属性,这些属性位于 编辑>>>项目设置>>>时间更改检查器中的时间步长和最大允许时间步长,以正确设置碰撞。在处理诸如尺度、质量和对撞机等物理时,还有一些其他的事情要记住。这是一个Link,关于统一物理设置的详细机制。在进行和调整物理设置之前,请务必阅读并理解链接的内容。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-26
    • 1970-01-01
    相关资源
    最近更新 更多