private int PingPong(int baseNumber, int limit)
{
if (limit < 2) return 0;
return limit - Mathf.Abs(limit - Modulus(baseNumber, limit + (limit - 2)) - 1) - 1;
}
private int Modulus(int baseNumber, int modulus)
{
return (modulus == 0) ? baseNumber : baseNumber - modulus * (int)Mathf.Floor(baseNumber / (float)modulus);
}
It's part of my script. I thought it should make the object to move between two waypoints back and forward. But it's not.
I can't figure out what this part of the code should do and what it does.
My complete script with the changes I did:
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 UserInformation userinformation;
public enum PatrolMode { Clamp, Wrap, PingPong, Random };
public PatrolData[] patrolPoints;
public PatrolMode mode = PatrolMode.Wrap;
private int iterator = 0;
private int index = 0;
private float lingerDuration = 0f;
private int overallLength = 0;
public bool autoFreedomPatrol = false;
public List<GameObject> Targets = new List<GameObject>();
public string tagName;
public Vector3 distanceFromTarget;
public float k = 0f;
public Vector3 WayPointA;
public Vector3 WayPointB;
public void Start()
{
if (tagName != "")
{
GameObject[] tempObj = GameObject.FindGameObjectsWithTag(tagName);
for (int i = 0; i < tempObj.Length; i++)
{
//Add to list only if it does not exist
if (!Targets.Contains(tempObj[i]))
{
Targets.Add(tempObj[i]);
}
}
//Get the current Size
if (tempObj != null)
{
overallLength = Targets.Count;
}
GeneratePatrolPoints();
}
}
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:
WayPointA = patrolPoints[index].target.position;
WayPointB = patrolPoints[index + 1].target.position;
break;
case PatrolMode.Random:
index = Random.Range(0, patrolPoints.Length);
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;
if (lookAtCamera != null)
{
lookAtCamera.target = patrol.target;
lookAtCamera.RotationSpeed = 3;
}
//userinformation.target = patrol.target;
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;
if (lookAtCamera != null)
lookAtCamera.target = null;
lingerDuration -= Time.deltaTime;
}
else
{
flyOverTerrain.target = patrol.target;
if (lookAtCamera != null)
lookAtCamera.target = patrol.target;
}
distanceFromTarget = transform.position - patrol.target.position;
}
private void PingPong()
{
k = Mathf.PingPong(Time.time, 1);
transform.position = Vector3.Lerp(WayPointA, WayPointB, k);
}
private int Modulus(int baseNumber, int modulus)
{
return (modulus == 0) ? baseNumber : baseNumber - modulus * (int)Mathf.Floor(baseNumber / (float)modulus);
}
public void GeneratePatrolPoints()
{
patrolPoints = new PatrolData[Targets.Count];
for (int i = 0; i < patrolPoints.Length; i++)
{
patrolPoints[i] = new PatrolData();
patrolPoints[i].target = Targets[i].transform;
patrolPoints[i].minDistance = 30f;
patrolPoints[i].lingerDuration = 3f;
patrolPoints[i].desiredHeight = 20f;
patrolPoints[i].flightSmoothTime = 10f;
patrolPoints[i].maxFlightspeed = 10f;
patrolPoints[i].flightAcceleration = 3f;
patrolPoints[i].levelingSmoothTime = 0.5f;
patrolPoints[i].maxLevelingSpeed = 10000f;
patrolPoints[i].levelingAcceleration = 2f;
}
}
}
The changes I did and tried so far:
Added WaypointA and WaypointB as global variables:
public Vector3 WayPointA;
public Vector3 WayPointB;
Then in the case of PingPong I did:
case PatrolMode.PingPong:
WayPointA = patrolPoints[index].target.position;
WayPointB = patrolPoints[index + 1].target.position;
break;
Then created a PingPong method:
private void PingPong()
{
k = Mathf.PingPong(Time.time, 1);
transform.position = Vector3.Lerp(WayPointA, WayPointB, k);
}
But I'm not sure where to call the PingPong method in the Update ?
And maybe I should use a flag bool type to check when it's pingpong mode in the Update ?
What I want to do is if I start the game in PingPong mode case then the object should move between waypoint index 0 and index 1 nonstop.
But if I change the mode to PingPong in the middle while the game is running then the object should move between the current waypoint index and the next one. For example between index 4 and index 5.