The goal is when pressing the P key make a ping pong nonstop between the next waypoint and the last waypoint. including if the P key pressed when the transform start moving from his original position so make a ping pong between the first waypoint and the transform original position.
The way it is now when I press the P key the whole game is freezing the editor is freezing and I need to shut it down.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Waypoints : MonoBehaviour
{
public List<GameObject> WayPoints;
private int CurrentWayPoint = 0;
private bool IsPatrolling = false;
private void Start()
{
StartPatrol();
}
private void Update()
{
if (Input.GetKeyDown(KeyCode.R))
{
ReversePatrolWayPoints();
}
if (Input.GetKeyDown(KeyCode.P))
{
PingPong();
}
}
public void StartPatrol()
{
if (!IsPatrolling)
{
StartCoroutine(Patrol());
}
}
public void ReversePatrolWayPoints()
{
WayPoints.Reverse();
}
bool pingPongEnabled = false;
Vector3 pingPongStart;
public void PingPong()
{
pingPongEnabled = true;
pingPongStart = transform.position;
}
private IEnumerator Patrol()
{
if (WayPoints == null || WayPoints.Count == 0)
{
Debug.Log("Waypoints list is null or empty");
yield break;
}
IsPatrolling = true;
while (CurrentWayPoint < WayPoints.Count)
{
if (pingPongEnabled)
{
transform.position = Vector3.MoveTowards(pingPongStart, WayPoints[CurrentWayPoint].transform.position, Mathf.PingPong(Time.time * 1, 1) * Time.deltaTime);
continue;
}
float distanceToWayPoint = Vector3.Distance(transform.position, WayPoints[CurrentWayPoint].transform.position);
transform.position = Vector3.MoveTowards(transform.position, WayPoints[CurrentWayPoint].transform.position, Time.deltaTime * 1f);
if (distanceToWayPoint <= 1f)
{
Debug.LogFormat("Reached Waypoint {0}", CurrentWayPoint);
CurrentWayPoint ;
if (CurrentWayPoint >= WayPoints.Count)
{
CurrentWayPoint = 0;
}
}
yield return null;
}
IsPatrolling = false;
yield break;
}
}
Edit : This is the script after the changes :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Mover : MonoBehaviour
{
public List<GameObject> WayPoints;
private int CurrentWayPoint = 0;
private bool IsPatrolling = false;
private void Start()
{
StartPatrol();
}
private void Update()
{
if (Input.GetKeyDown(KeyCode.R))
{
ReversePatrolWayPoints();
}
if (Input.GetKeyDown(KeyCode.P))
{
PingPong();
}
}
public void StartPatrol()
{
if (!IsPatrolling)
{
StartCoroutine(Patrol());
}
}
public void ReversePatrolWayPoints()
{
WayPoints.Reverse();
}
bool pingPongEnabled = false;
Vector3 pingPongStart;
public void PingPong()
{
pingPongEnabled = true;
pingPongStart = transform.position;
}
private IEnumerator Patrol()
{
if (WayPoints == null || WayPoints.Count == 0)
{
Debug.Log("Waypoints list is null or empty");
yield break;
}
IsPatrolling = true;
while (CurrentWayPoint < WayPoints.Count)
{
if (pingPongEnabled)
{
transform.position = Vector3.Lerp(pingPongStart, WayPoints[CurrentWayPoint].transform.position, Mathf.PingPong(Time.time, 1));
yield return null;
}
float distanceToWayPoint = Vector3.Distance(transform.position, WayPoints[CurrentWayPoint].transform.position);
transform.position = Vector3.MoveTowards(transform.position, WayPoints[CurrentWayPoint].transform.position, Time.deltaTime * 1f);
if (distanceToWayPoint <= 1f)
{
Debug.LogFormat("Reached Waypoint {0}", CurrentWayPoint);
CurrentWayPoint ;
if (CurrentWayPoint >= WayPoints.Count)
{
CurrentWayPoint = 0;
}
}
yield return null;
}
IsPatrolling = false;
yield break;
}
}
Edit :
This is working almost as I wanted :
When it's making the ping pong it's doing between the last transform position and the next waypoint position and I wanted it to be between the last waypoint and the next waypoint. but the ping pong is now working.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Mover : MonoBehaviour
{
public List<GameObject> WayPoints;
private int CurrentWayPoint = 0;
private bool IsPatrolling = false;
private void Start()
{
StartPatrol();
}
private void Update()
{
if (Input.GetKeyDown(KeyCode.R))
{
ReversePatrolWayPoints();
}
if (Input.GetKeyDown(KeyCode.P))
{
PingPong();
}
}
public void StartPatrol()
{
if (!IsPatrolling)
{
StartCoroutine(Patrol());
}
}
public void ReversePatrolWayPoints()
{
WayPoints.Reverse();
}
bool pingPongEnabled = false;
Vector3 pingPongStart;
public void PingPong()
{
pingPongEnabled = true;
pingPongStart = transform.position;
}
private IEnumerator Patrol()
{
if (WayPoints == null || WayPoints.Count == 0)
{
Debug.Log("Waypoints list is null or empty");
yield break;
}
IsPatrolling = true;
while (CurrentWayPoint < WayPoints.Count)
{
if (pingPongEnabled)
{
transform.position = Vector3.Lerp(pingPongStart, WayPoints[CurrentWayPoint].transform.position, Mathf.PingPong(Time.time, 1));
yield return null;
}
else
{
float distanceToWayPoint = Vector3.Distance(transform.position, WayPoints[CurrentWayPoint].transform.position);
transform.position = Vector3.MoveTowards(transform.position, WayPoints[CurrentWayPoint].transform.position, Time.deltaTime * 1f);
if (distanceToWayPoint <= 1f)
{
Debug.LogFormat("Reached Waypoint {0}", CurrentWayPoint);
CurrentWayPoint ;
if (CurrentWayPoint >= WayPoints.Count)
{
CurrentWayPoint = 0;
}
}
yield return null;
}
}
IsPatrolling = false;
yield break;
}
}
CodePudding user response:
Your editor freezes because in the case that pingPongEnabled is set to true you do
if (pingPongEnabled)
{
transform.position = Vector3.MoveTowards(pingPongStart, WayPoints[CurrentWayPoint].transform.position, Mathf.PingPong(Time.time * 1, 1) * Time.deltaTime);
continue;
}
without yielding within the loop -> due to continue it immediately goes to the next iteration without the exit condition ever fulfilled.
You want to make sure to always do
if (pingPongEnabled)
{
transform.position = Vector3.MoveTowards(pingPongStart, WayPoints[CurrentWayPoint].transform.position, Mathf.PingPong(Time.time * 1, 1) * Time.deltaTime);
yield return null;
continue;
}
in order to at least wait until the next frame with the next iteration
Anyway, this
transform.position = Vector3.MoveTowards(pingPongStart, WayPoints[CurrentWayPoint].transform.position, Mathf.PingPong(Time.time * 1, 1) * Time.deltaTime);
doesn't really "ping-pong" like you would probably expect. It always starts back at pingPongStart and moves a single step towards the waypoint and only goes a bit further or less.
You probably rather ment
transform.position = Vector3.Lerp(pingPongStart, WayPoints[CurrentWayPoint].transform.position, Mathf.PingPong(Time.time, 1));
