Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

[Code review] wandering NPC's on a NavMesh

Discussion in 'Scripting' started by davidson27, Jun 21, 2019.

  1. davidson27

    davidson27

    Joined:
    Feb 10, 2018
    Posts:
    18
    Hey, I'm looking for some insight on this script I made for wandering NPC's.

    If anyone has any critiques, suggestions, refactoring tips, or any comments I would love to hear them.



    The specific script I am asking for a review on if called NCP_Patroll.cs

    it can be found in my github project under nav-Experiments/Assets/This-Project/Scripts/NPC_Patrol.cs

    The main ideas behind the script are for an NPC to cast rays out in a view range, collect a series of hit navigation points into an array, pick the farthest point and navigate to it.
    once the NPC has a nav point it will stop casting rays for overhead reasons.



    the project can be found here https://github.com/Davidson2727/nav-Experiments

    Here is the code for the script if that is better

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.AI;
    5.  
    6. public class NPC_Patrol : MonoBehaviour
    7. {
    8.  
    9.   // The number of rays
    10.   [SerializeField]
    11.   public int _rayNumber = 5;
    12.  
    13.   // The view range in degrees.
    14.   [SerializeField]
    15.   public int _viewRange = 210;
    16.  
    17.   // The distance between the rays.
    18.   [SerializeField]
    19.   public int _separation;
    20.  
    21.   // The direction of the ray.
    22.   [SerializeField]
    23.   public Vector3 _rayVector;
    24.  
    25.   // The length of the ray.
    26.   [SerializeField]
    27.   public float _rayLength = 10f;
    28.  
    29.   // The distance between NPC and navPoint.
    30.   [SerializeField]
    31.   public float _dist;
    32.  
    33.   // The height of the ray from the ground.
    34.   [SerializeField]
    35.   Vector3 _rayHeight = new Vector3(0.12f,.05f,0);
    36.  
    37.   // May have to move this back into update
    38.   [SerializeField]
    39.   public RaycastHit _hit;
    40.  
    41.   // Array of navPoints hit by the NPC
    42.   [SerializeField]
    43.   public Vector3[] _hitNavPoints;
    44.  
    45.   // The destination chosen from _hitNavPoints
    46.   [SerializeField]
    47.   public Vector3 _destination;
    48.  
    49.   // The
    50.   [SerializeField]
    51.   public float _maxDistance;
    52.  
    53.   // Check to see in the NPC is moving
    54.   [SerializeField]
    55.   public bool _onRoute = false;
    56.  
    57.   // NavMeshAgent component
    58.   NavMeshAgent _agent;
    59.  
    60.  
    61.     // Start is called before the first frame update
    62.     void Start()
    63.     {
    64.       _agent = this.GetComponent<NavMeshAgent>();
    65.       _destination = transform.position;
    66.       if (_agent == null)
    67.       {
    68.         Debug.LogError("The nav mesh agent component is not attached to " + gameObject.name);
    69.       }
    70.       _hitNavPoints = new Vector3[_rayNumber];
    71.       // When _hitNavPoints is initialized all the indicies are given a Vector3 and (0,0,0),
    72.       // if all the rays do not hit a navPoint on the first call,
    73.       for (int i = 0; i < _rayNumber; i++)
    74.       {
    75.         _hitNavPoints[i] = transform.position;
    76.       }
    77.     }
    78.  
    79.     // Update is called once per frame
    80.     void Update()
    81.     {
    82.       if(_onRoute==false)
    83.       {
    84.         _hitNavPoints = drawRays();
    85.         _destination = findDestination(_hitNavPoints);
    86.         setDestination(_destination);
    87.  
    88.         turnAround(_hitNavPoints);
    89.  
    90.       }
    91.       //drawRays();
    92.  
    93.       if(_onRoute && _agent.remainingDistance <= 1.0f)
    94.         {
    95.             _destination = transform.position;
    96.             _onRoute = false;
    97.         }
    98.     }
    99.     Vector3[] drawRays()
    100.     {
    101.       _rayVector = transform.TransformDirection(Vector3.right);
    102.       // the view range divided by the number of rays.
    103.       _separation = _viewRange/_rayNumber;
    104.       for(int i = 0; i < _rayNumber; i++)
    105.       {
    106.         //Need to figure out why there is not a ray for when i == 0
    107.         _rayVector = Quaternion.Euler(0, (_separation)%_viewRange, 0) * _rayVector;
    108.         Debug.DrawRay(transform.position + _rayHeight, -_rayVector*_rayLength, Color.green);
    109.         //**************************************
    110.         //******This is what works for now******
    111.         //**************************************
    112.         if (Physics.Raycast(transform.position+ _rayHeight, -_rayVector , out _hit, _rayLength))
    113.         {
    114.           _hit.collider.gameObject.tag = "NPC_Hit";
    115.           _hitNavPoints[i] = _hit.point;
    116.         }
    117.         else
    118.         {
    119.           _hitNavPoints[i] = transform.position;
    120.         }
    121.       }
    122.       return _hitNavPoints;
    123.     }
    124.  
    125.  
    126.     Vector3 findDestination(Vector3[] hitNavPoints)
    127.     {
    128.       Vector3 nextDestination = transform.position;
    129.       _maxDistance = 0;
    130.  
    131.       for(int i = 0; i<hitNavPoints.Length;i++)
    132.       {
    133.         _dist = Vector3.Distance(hitNavPoints[i], transform.position);
    134.         if (_dist>_maxDistance)
    135.         {
    136.           _maxDistance = _dist;
    137.           nextDestination = hitNavPoints[i];
    138.         }
    139.       }
    140.       return  nextDestination;
    141.     }
    142.  
    143.     void setDestination(Vector3 destination)
    144.     {
    145.  
    146.       if (destination!=transform.position)
    147.       {
    148.         _onRoute = true;
    149.         _agent.SetDestination(_destination);
    150.       }
    151.     }
    152.  
    153.     void turnAround(Vector3[] _hitNavPoints)
    154.     {
    155.  
    156.     }
    157. }
    158.  
     
  2. Joe-Censored

    Joe-Censored

    Joined:
    Mar 26, 2013
    Posts:
    11,847
  3. davidson27

    davidson27

    Joined:
    Feb 10, 2018
    Posts:
    18
    Access modifies aren't my strong suit, but I had them like that so I could see everything in the inspector, thanks for the info.