0

這個腳本的大部分工作原理,然而敵人在尋路時會失敗並穿過建築物或牆壁。有沒有辦法阻止這種情況?碰撞檢測腳本有時會失敗

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); 
     } 
    } 
} 
+0

這可能不是合適的做法......但你仍然有問題,如果你改變'FixedUpdate()''來更新()'? – ryeMoss

+0

嘗試設置從離散到連續型 – Isma

+0

您的剛體碰撞檢測我可能是錯的,但你正在做的只有4個主要方向光線投射,所以或許光線投射只是缺少障礙(即光線投射高於或障礙物等..下)。 –

回答

0

現在沒事了,這是人與物理引擎播放時所面臨的最常見的問題之一,相信我有很多的因素加起來,你所面對的結果/後果。人們設計的最常見的解決方案是使用更新這是執行每幀物理計算是完全錯誤。要固定更新的內進行所有相關的計算需要物理否則將在更新這意味着每一個幀執行基於物理模擬太昂貴了。在你的情況下,你的敵人是通過牆壁和物理碰撞缺少最好的解決方案,你可以採取的是調整一些物理相關屬性在Unity這些都位於編輯>>>項目設置>>>時間更改檢查器中的時間步長和最大允許時間步驟,以便正確設置您的碰撞。在處理物理如尺度,質量和碰撞等時還要記住其他一些事情。這裏是關於統一物理設置的詳細力學的Link。確保在工作和調整物理設置之前閱讀並理解鏈接的內容。