Search Unity

Need some help with flying enemy collision

Discussion in 'Scripting' started by MrKory, Aug 18, 2017.

  1. MrKory

    MrKory

    Joined:
    Sep 20, 2013
    Posts:
    66
    Hi,

    I am trying to create an enemy that hovers and follows the player around... like a Cacodemon from Doom/hovering drone would. I found a demo on Youtube, and while it works incredibly well, it fails in a huge way when it comes to detecting large colliders like terrain. It just seems to ignore them and pass through them. I have double checked tags, layers, and the physics matrix... all is good there. A comment in the Youtube demo stated that if two of the rays hit the object at the same time it would cause issues. I'll paste my code below. Any help would be a huge help. I've been stuck with this for a week now.

    To try/test the code create 2 cubes, name one player and one enemy. Set the player as the target for the enemy. Create a bunch of small cubes with colliders 1-2 units in scale. Place them around like walls and leave some floating in the air. Press the play button. Select the player and drag him around in the viewport. The variables that are exposed in the inspector will probably need to be tweaked a bit to.

    I'm also wondering if anyone has run into a good thread here for creating an enemy like a drone that will chase the player around objects, through halls, and over things. If so a link to it would be awesome.

    Thanks,
    -Kory

    Code (CSharp):
    1. public class EnemyHoverFollow : MonoBehaviour {
    2.  
    3.     [SerializeField]Transform target;
    4.     [SerializeField]float movementSpeed = 10.0f;
    5.     [SerializeField]float rotationalDamp = 0.5f;
    6.     [SerializeField]float rayCastOffset = 2.5f;
    7.     [SerializeField]float detectionDistance = 20.0f;
    8.  
    9.  
    10.     void Start(){
    11.     target = GameObject.Find("Player").transform;
    12.     }
    13.  
    14.     void Update(){
    15.         Pathfinding ();
    16.         Move ();
    17.     }
    18.  
    19.     void Turn(){
    20.         Vector3 pos = target.position - transform.position;
    21.         Quaternion rotation = Quaternion.LookRotation (pos);
    22.         transform.rotation = Quaternion.Slerp (transform.rotation, rotation, rotationalDamp * Time.deltaTime);
    23.     }
    24.  
    25.     void Move(){
    26.         transform.position += transform.forward * movementSpeed * Time.deltaTime;
    27.     }
    28.  
    29.     void Pathfinding(){
    30.         RaycastHit hit;
    31.         Vector3 raycastOffset = Vector3.zero;
    32.  
    33.         Vector3 left = transform.position - transform.right * rayCastOffset;
    34.         Vector3 right = transform.position + transform.right * rayCastOffset;
    35.         Vector3 up = transform.position + transform.up * rayCastOffset;
    36.         Vector3 down = transform.position - transform.up * rayCastOffset;
    37.  
    38.         Debug.DrawRay (left, transform.forward * detectionDistance, Color.cyan);
    39.         Debug.DrawRay (right, transform.forward * detectionDistance, Color.cyan);
    40.         Debug.DrawRay (up, transform.forward * detectionDistance, Color.cyan);
    41.         Debug.DrawRay (down, transform.forward * detectionDistance, Color.cyan);
    42.  
    43.         //Right and Left testing
    44.         if(Physics.Raycast(left, transform.forward, out hit, detectionDistance)){
    45.             raycastOffset += Vector3.right;
    46.         }
    47.         else if(Physics.Raycast(right, transform.forward, out hit, detectionDistance)){
    48.             raycastOffset -= Vector3.right;
    49.         }
    50.  
    51.         //Up and Down testing
    52.         if(Physics.Raycast(up, transform.forward, out hit, detectionDistance)){
    53.             raycastOffset -= Vector3.up;
    54.         }
    55.         else if(Physics.Raycast(down, transform.forward, out hit, detectionDistance)){
    56.             raycastOffset += Vector3.up;
    57.         }
    58.  
    59.         if (raycastOffset != Vector3.zero) {
    60.             transform.Rotate (raycastOffset * 5.0f * Time.deltaTime);
    61.         } else {
    62.             Turn ();
    63.         }
    64.     }
    65. }
     
  2. MattM_Unity

    MattM_Unity

    Unity Technologies

    Joined:
    Aug 18, 2017
    Posts:
    45
    Hello MrKory!

    You should try running your Pathfinding and Move functions in FixedUpdate rather than Update. The Update function runs once per frame whereas the FixedUpdate function can run zero, once or multiple times per frame.

    You can find a much more detailed explanation on the forum, right here.
     
    MrKory likes this.
  3. MrKory

    MrKory

    Joined:
    Sep 20, 2013
    Posts:
    66
    Thanks for the help MattUniQC!!
     
  4. MattM_Unity

    MattM_Unity

    Unity Technologies

    Joined:
    Aug 18, 2017
    Posts:
    45
    You're welcome :) Did using the FixedUpdate method worked?
     
  5. MrKory

    MrKory

    Joined:
    Sep 20, 2013
    Posts:
    66
    I haven't gotten that far yet..but will as soon as I have a bit of time to spend on it. I am currently having other issues that are severely impacting my project. I upgraded Unity to 2017, and my game went from 90fps to a crawling 35-60. I will return to this issue once I have fixed the new issue/s. Thanks for your help and checking back on the thread! :)

    -Kory