Search Unity

  1. If you have experience with import & exporting custom (.unitypackage) packages, please help complete a survey (open until May 15, 2024).
    Dismiss Notice
  2. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice

Object Not Dying When Approached

Discussion in 'Scripting' started by TheBigChedder, Apr 18, 2019.

  1. TheBigChedder

    TheBigChedder

    Joined:
    Mar 24, 2019
    Posts:
    6
    Hi! I'm trying to make an object die when the player approaches it. Any tips on what I'm doing wrong?

    Script for the object (It patrols around)
    Code (CSharp):
    1. using System.Collections;
    2. using System;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5. using UnityEngine.AI;
    6.  
    7. public class NPCPatrol : MonoBehaviour
    8. {
    9.     //Determines whether NPC waits on a node
    10.     [SerializeField]
    11.     bool _patrolWaiting;
    12.  
    13.     //Sight distance
    14.     [SerializeField]
    15.     public float sightDistance = 10f;
    16.  
    17.     //Total time to wait on a node
    18.     [SerializeField]
    19.     float _totalWaitTime = 3f;
    20.  
    21.     //Probability to switch directions
    22.     [SerializeField]
    23.     float _switchProbability = 0.2f;
    24.  
    25.     //List of all patrol points to go to
    26.     [SerializeField]
    27.     List<PatrolPoint> _patrolPoints;
    28.  
    29.     //Private variables for behavior
    30.     NavMeshAgent _navMeshAgent;
    31.     int _currentPatrolIndex;
    32.     bool _travelling;
    33.     bool _waiting;
    34.     bool _patrolForward;
    35.     float _waitTimer;
    36.  
    37.     Transform target;
    38.     Transform pad;
    39.     // Start is called before the first frame update
    40.     void Start()
    41.     {
    42.         target = PlayerTracker.instance.player.transform; //Calls on GameManager's PlayerTracker
    43.         pad = PlayerTracker.instance.pad.transform;
    44.         _navMeshAgent = this.GetComponent<NavMeshAgent>();
    45.  
    46.            if(_navMeshAgent == null) //If true no nav mesh attached
    47.            {
    48.                Debug.LogError("Nav mesh agent is not attached to " + gameObject.name);
    49.            }
    50.            else
    51.            {
    52.                if(_patrolPoints != null && _patrolPoints.Count >= 2) //Checks if patrol points exist and there are enough
    53.                {
    54.                    _currentPatrolIndex = 0;
    55.                    SetDestination();
    56.                }
    57.                else
    58.                {
    59.                    Debug.Log("Insufficient patrol points for basic patrolling behaviour.");
    60.                }
    61.             }
    62.  
    63.     }
    64.  
    65.     // Update is called once per frame
    66.     public void Update()
    67.     {
    68.         float distance = Vector3.Distance(target.position, transform.position);
    69.         //Checks if close to the destination
    70.         if (_travelling && _navMeshAgent.remainingDistance <= 1.0f)
    71.         {
    72.             _travelling = false;
    73.  
    74.             //If going to wait
    75.             if (_patrolWaiting)
    76.             {
    77.                 _waiting = true;
    78.                 _waitTimer = 0f;
    79.             }
    80.             else
    81.             {
    82.                 ChangePatrolPoint();
    83.                 SetDestination();
    84.             }
    85.         }
    86.         //Instead if we're waiting
    87.         if (_waiting)
    88.         {
    89.             _waitTimer += Time.deltaTime;
    90.             if(_waitTimer >= _totalWaitTime)
    91.             {
    92.                 _waiting = false;
    93.  
    94.                 ChangePatrolPoint();
    95.                 SetDestination();
    96.             }
    97.         }
    98.         if (distance <= sightDistance)
    99.         {
    100.             gameObject.SetActive(false);
    101.         }
    102.     }
    103.  
    104.     private void SetDestination() //Sets destination
    105.     {
    106.         if(_patrolPoints != null)
    107.         {
    108.             Vector3 targetVector = _patrolPoints[_currentPatrolIndex].transform.position; //Go to destination
    109.             _navMeshAgent.SetDestination(targetVector);
    110.             _travelling = true;
    111.         }
    112.     }
    113.  
    114.     private void ChangePatrolPoint()
    115.     {
    116.         if(UnityEngine.Random.Range(0f, 1f) <= _switchProbability)
    117.         {
    118.             _patrolForward = !_patrolForward;
    119.         }
    120.  
    121.         if (_patrolForward)
    122.         {
    123.             _currentPatrolIndex = (_currentPatrolIndex + 1) % _patrolPoints.Count;
    124.         }
    125.  
    126.         else
    127.         {
    128.             if(--_currentPatrolIndex < 0)
    129.             {
    130.                 _currentPatrolIndex = _patrolPoints.Count - 1;
    131.             }
    132.         }
    133.     }
    134.     void OnDrawGizmosSelected()
    135.     {
    136.         Gizmos.color = Color.blue; //Makes sight radius sphere blue
    137.         Gizmos.DrawWireSphere(transform.position, sightDistance); //shows radius of sight
    138.     }
    139. }
    140.  
    Script for the GameManager that tracks the player
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class PlayerTracker : MonoBehaviour
    6. {
    7.      #region Singleton
    8.  
    9.     public static PlayerTracker instance;
    10.  
    11.     void Awake()
    12.     {
    13.         instance = this;
    14.  
    15.     }
    16.  
    17.     #endregion
    18.  
    19.     public GameObject player; //References player
    20.     public GameObject pad;
    21. }
    22.  
    If you need anything else to help solve the problem let me know
     
  2. jilleJr

    jilleJr

    Joined:
    Jan 21, 2015
    Posts:
    63
    Multiple ways to approach this. One is to use a trigger around the object and check upon
    OnTriggerEnter
    from the player and then destroy the object. I recommend this variant.

    Consider the following code placed on your player, and having your NPC having a collider with
    isTrigger
    enabled, and perhaps tagged with tag
    NPC
    :

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class NPCDestroyer : MonoBehaviour {
    6.     void OnTriggerEnter(Collider other) {
    7.         if (other.CompareTag("NPC")) {
    8.             Destroy(other.gameObject);
    9.         }
    10.     }
    11. }
    ---

    Alternative 2 is doing it via script. This can be done simply by checking the distance between the two positions of player and the NPC object, much like you're already doing in your patrol script for deciding when to start moving to the next patrol point.

    Consider the following script placed on the NPC game object:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class PlayerTracker : MonoBehaviour {
    6.     public Transform player;
    7.     public float range = 10;
    8.  
    9.     void Update() {
    10.         float distance = Vector3.Distance(player.position, transform.position);
    11.  
    12.         if (distance < range) {
    13.             Destroy(gameObject);
    14.         }
    15.     }
    16. }