0

Pour la plupart, ce script fonctionne, mais de temps en temps, un ennemi échouera lors de la recherche de chemin et traversera un bâtiment ou un mur. Est-ce qu'il y a une manière que je peux arrêter ceci?Le script de détection de collision échoue parfois

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

Ce n'est peut-être pas une bonne pratique ... mais avez-vous encore des problèmes si vous changez 'FixedUpdate()' en 'Update()'? – ryeMoss

+0

Essayez de définir votre détection de collision de Discrete à Continuos – Isma

+0

Je peux me tromper mais vous ne faites que 4 rayons dans les directions principales, alors peut-être que les rayons rayent juste l'obstacle (raycast qui va au-dessus ou en dessous de l'obstacle etc. .). –

Répondre

0

Bon maintenant c'est l'un des problèmes que les gens les plus communs rencontrés lors de la lecture avec moteur physique et croyez-moi, il y a beaucoup de facteurs qui ajoute au résultat/conséquences que vous faites face. La plupart des solutions communes conçues par les gens est d'utiliser Mise à jour qui est Exécuté chaque trame pour le calcul de la physique qui est Entièrement erroné. Tous les calculs liés à la physique doivent être effectués à l'intérieur de la mise à jour fixe sinon il sera trop coûteux d'exécuter des simulations basées sur la physique dans le Mise à jour qui signifie chaque image. Dans votre cas où votre ennemi va à travers les murs et la physique sont Collisions manque la meilleure solution que vous pouvez faire est de modifier certains physique Propriétés connexes dans l'unité ceux-ci sont situés dans Modifier >>> Paramètres du projet >>> Temps modifiez le Temps pas et Temps maximum autorisé. Étape dans l'inspecteur pour régler vos collisions correctement. Il y a d'autres choses à garder à l'esprit en traitant de la physique comme l'échelle, la masse et les collisionneurs, etc. Voici un Link concernant la mécanique détaillée des paramètres physiques dans l'unité. Assurez-vous de lire et de comprendre le contenu du lien avant de travailler et de modifier les paramètres physiques.