Home > OS >  Why the ping pong is not working on the waypoints?
Why the ping pong is not working on the waypoints?

Time:01-16

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));
  •  Tags:  
  • Related