How can I change the class so I can set the number of waypoints in the script too?

Now I can set the number of waypoints(targets) only when the script is attached to a GameObject. Then in the Inspector, I can set the size. For example, if I set the size of Patrol Points to 2, then I have element 0 and element 1 in the Inspector and I can fill/set each element properties.

But each element has a property Target. And since in another script I create GameObjects automatic and randomly, I want to assign them to the Patrol Points array and not to drag each Target and set the size each time.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[System.Serializable]
public class PatrolData
{
   public Transform target = null;
   public float minDistance = 5f;
   public float lingerDuration = 5f;

   public float desiredHeight = 10f;

   public float flightSmoothTime = 10f;
   public float maxFlightspeed = 10f;
   public float flightAcceleration = 1f;

   public float levelingSmoothTime = 0.5f;
   public float maxLevelingSpeed = 10000f;
   public float levelingAcceleration = 2f;
}

public class PatrolOverTerrain: MonoBehaviour
{
   public FlyToOverTerrain flyOverTerrain;
   public LookAtCamera lookAtCamera;
   public enum PatrolMode { Clamp, Wrap, PingPong };
   public PatrolData[] patrolPoints;
   public PatrolMode mode = PatrolMode.Wrap;

   private int iterator = 0;
   private int index = 0;
   private float lingerDuration = 0f;

   public Vector3 distanceFromTarget;

   private void OnEnable()
   {
       if (patrolPoints.Length > 0)
       {
           lingerDuration = patrolPoints[index].lingerDuration;
       }
   }

   private void Update()
   {
       int length = patrolPoints.Length;
       if (!flyOverTerrain) return;
       if (patrolPoints.Length < 1) return;
       if (index < 0) return;

       var patrol = patrolPoints[index];
       if (lingerDuration <= 0)
       {
           iterator++;
           switch (mode)
           {
               case PatrolMode.Clamp:
                   index = (iterator >= length) ? -1 : iterator;
                   break;
               case PatrolMode.Wrap:
                   iterator = Modulus(iterator, length);
                   index = iterator;
                   break;
               case PatrolMode.PingPong:
                   iterator = Modulus(iterator, length * 2);
                   index = length - Mathf.Abs(length - iterator);
                   break;
           }
           if (index < 0) return;

           patrol = patrolPoints[index];

           flyOverTerrain.target = patrol.target;
           flyOverTerrain.desiredHeight = patrol.desiredHeight;
           flyOverTerrain.flightSmoothTime = patrol.flightSmoothTime;
           flyOverTerrain.maxFlightspeed = patrol.maxFlightspeed;
           flyOverTerrain.flightAcceleration = patrol.flightAcceleration;
           flyOverTerrain.levelingSmoothTime = patrol.levelingSmoothTime;
           flyOverTerrain.maxLevelingSpeed = patrol.maxLevelingSpeed;
           flyOverTerrain.levelingAcceleration = patrol.levelingAcceleration;

           lookAtCamera.target = patrol.target;
           lookAtCamera.RotationSpeed = 3;

           lingerDuration = patrolPoints[index].lingerDuration;
       }


       Vector3 targetOffset = Vector3.zero;
       if ((bool)patrol.target)
       {
           targetOffset = transform.position - patrol.target.position;
       }

       float sqrDistance = patrol.minDistance * patrol.minDistance;
       if (targetOffset.sqrMagnitude <= sqrDistance)
       {
           flyOverTerrain.target = null;
           lookAtCamera.target = null;
           lingerDuration -= Time.deltaTime;
       }
       else
       {
           flyOverTerrain.target = patrol.target;
           lookAtCamera.target = patrol.target;
       }

       distanceFromTarget = transform.position - patrol.target.position;
   }


   private int Modulus(int baseNumber, int modulus)
   {
       return (modulus == 0) ? baseNumber : baseNumber - modulus * (int)Mathf.Floor(baseNumber / (float)modulus);
   }
}

This is the array

public PatrolData[] patrolPoints;

But I can’t set in the script the number of elements and then assign the targets automatically.

This is the script I use to create GameObjects:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class InstantiateObjects : MonoBehaviour
{
   public GameObject prefab;
   public Terrain terrain;
   public float yOffset = 0.5f;
   public int objectsToInstantiate;
   public bool parent = true;

   private float terrainWidth;
   private float terrainLength;
   private float xTerrainPos;
   private float zTerrainPos;
   private List<GameObject> prefabs = new List<GameObject>();


   public void Start()
   {
       //Get terrain size
       terrainWidth = terrain.terrainData.size.x;
       terrainLength = terrain.terrainData.size.z;

       //Get terrain position
       xTerrainPos = terrain.transform.position.x;
       zTerrainPos = terrain.transform.position.z;

       generateObjectOnTerrain();
   }

   public void generateObjectOnTerrain()
   {
       for (int i = 0; i < objectsToInstantiate; i++)
       {
           //Generate random x,z,y position on the terrain
           float randX = UnityEngine.Random.Range(xTerrainPos, xTerrainPos + terrainWidth);
           float randZ = UnityEngine.Random.Range(zTerrainPos, zTerrainPos + terrainLength);
           float yVal = Terrain.activeTerrain.SampleHeight(new Vector3(randX, 0, randZ));

           //Apply Offset if needed
           yVal = yVal + yOffset;

           //Generate the Prefab on the generated position       
           GameObject objInstance = Instantiate(prefab, new Vector3(randX, yVal, randZ), Quaternion.identity);
           if (parent)
               objInstance.transform.parent = this.transform;
           prefabs.Add(objInstance);
       }
   }

   public List<GameObject> PrefabsList()
   {
       return prefabs;
   }
}

Now, for example, I created 21 GameObjects. Now I want to get and assign this GameObjects as elements and targets using the PatrolData and the PatrolOVerTerrain. But I can’t figure out how to do it. I mean what to change/add in the PatrolData and the PatrolOVerTerrain script.

You can set the size of the array in code, like so:

variable = new arrayType[size];

You can also resize:

Array.Resize(ref variable, int size);

Does that help? :slight_smile:

1 Like

Yes in the code i change the resize of the array for example:

patrolPoints = new PatrolData[9];

Thanks.

Cool :slight_smile: yw