How to move PLAYER along the path?

I have a script that allows me to create a path follow

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
 
public class PathCreator : MonoBehaviour {
 
    [HideInInspector]
    public Path path;
 
 
    public Color anchorCol = Color.red;
    public Color controlCol = Color.white;
    public Color segmentCol = Color.green;
    public Color selectedSegmentCol = Color.yellow;
    public float anchorDiameter = .1f;
    public float controlDiameter = .075f;
    public bool displayControlPoints = true;
 
 
 
    public void CreatePath()
    {
        path = new Path(transform.position);
    }
 
    void Reset()
    {
        CreatePath();
    }
}

My question

  1. How to move PLAYER along the path?

I can not find a rare script that would allow it.

Thank you for the answer.

PS. Path Editor script:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
 
[CustomEditor(typeof(PathCreator))]
public class PathEditor : Editor {
 
    PathCreator creator;
    Path Path
    {
        get
        {
            return creator.path;
        }
    }
 
    const float segmentSelectDistanceThreshold = .1f;
    int selectedSegmentIndex = -1;
 
    public override void OnInspectorGUI()
    {
        base.OnInspectorGUI();
 
        EditorGUI.BeginChangeCheck();
        if (GUILayout.Button("Create new"))
        {
            Undo.RecordObject(creator, "Create new");
            creator.CreatePath();
        }
 
        bool isClosed = GUILayout.Toggle(Path.IsClosed, "Closed");
        if (isClosed != Path.IsClosed)
        {
            Undo.RecordObject(creator, "Toggle closed");
            Path.IsClosed = isClosed;
        }
 
        bool autoSetControlPoints = GUILayout.Toggle(Path.AutoSetControlPoints, "Auto Set Control Points");
        if (autoSetControlPoints != Path.AutoSetControlPoints)
        {
            Undo.RecordObject(creator, "Toggle auto set controls");
            Path.AutoSetControlPoints = autoSetControlPoints;
        }
 
        if (EditorGUI.EndChangeCheck())
        {
            SceneView.RepaintAll();
        }
    }
 
    void OnSceneGUI()
    {
        Input();
        Draw();
    }
 
    void Input()
    {
        Event guiEvent = Event.current;
        Vector2 mousePos = HandleUtility.GUIPointToWorldRay(guiEvent.mousePosition).origin;
 
        if (guiEvent.type == EventType.MouseDown && guiEvent.button == 0 && guiEvent.shift)
        {
            if (selectedSegmentIndex != -1)
            {
                Undo.RecordObject(creator, "Split segment");
                Path.SplitSegment(mousePos, selectedSegmentIndex);
            }
            else if (!Path.IsClosed)
            {
                Undo.RecordObject(creator, "Add segment");
                Path.AddSegment(mousePos);
            }
        }
 
        if (guiEvent.type == EventType.MouseDown && guiEvent.button == 1)
        {
            float minDstToAnchor = creator.anchorDiameter * .5f;
            int closestAnchorIndex = -1;
 
            for (int i = 0; i < Path.NumPoints; i+=3)
            {
                float dst = Vector2.Distance(mousePos, Path*);*

if (dst < minDstToAnchor)
{
minDstToAnchor = dst;
closestAnchorIndex = i;
}
}

if (closestAnchorIndex != -1)
{
Undo.RecordObject(creator, “Delete segment”);
Path.DeleteSegment(closestAnchorIndex);
}
}

if (guiEvent.type == EventType.MouseMove)
{
float minDstToSegment = segmentSelectDistanceThreshold;
int newSelectedSegmentIndex = -1;

for (int i = 0; i < Path.NumSegments; i++)
{
Vector2[] points = Path.GetPointsInSegment(i);
float dst = HandleUtility.DistancePointBezier(mousePos, points[0], points[3], points[1], points[2]);
if (dst < minDstToSegment)
{
minDstToSegment = dst;
newSelectedSegmentIndex = i;
}
}

if (newSelectedSegmentIndex != selectedSegmentIndex)
{
selectedSegmentIndex = newSelectedSegmentIndex;
HandleUtility.Repaint();
}
}
}

void Draw()
{
for (int i = 0; i < Path.NumSegments; i++)
{
Vector2[] points = Path.GetPointsInSegment(i);
if (creator.displayControlPoints)
{
Handles.color = Color.black;
Handles.DrawLine(points[1], points[0]);
Handles.DrawLine(points[2], points[3]);
}
Color segmentCol = (i == selectedSegmentIndex && Event.current.shift) ? creator.selectedSegmentCol : creator.segmentCol;
Handles.DrawBezier(points[0], points[3], points[1], points[2], segmentCol, null, 2);
}

for (int i = 0; i < Path.NumPoints; i++)
{
if (i % 3 == 0 || creator.displayControlPoints)
{
Handles.color = (i % 3 == 0) ? creator.anchorCol : creator.controlCol;
float handleSize = (i % 3 == 0) ? creator.anchorDiameter : creator.controlDiameter;
Vector2 newPos = Handles.FreeMoveHandle(Path*, Quaternion.identity, handleSize, Vector2.zero, Handles.CylinderHandleCap);*
if (Path != newPos)
{
Undo.RecordObject(creator, “Move point”);
Path.MovePoint(i, newPos);
}
}
}
}

void OnEnable()
{
creator = (PathCreator)target;
if (creator.path == null)
{
creator.CreatePath();
}
}
}

I haven’t taken a look in your code, but to do what you proposed, the keywords you are looking for are spline and bezier curve.

Anyway, if you are only seeking for a way to make it done, you can use existing free assets in the Asset Store such as `iTween` or `Bezier Solution`.

Here are the links

Solved :slight_smile:
First script

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

public class PathPlacer : MonoBehaviour {

	public float spacing = .1f;
	public float resolution = 1;
	public GameObject someObject;


	void Start () {
		Vector2[] points = FindObjectOfType<PathCreator>().path.CalculateEvenlySpacedPoints(spacing, resolution);


		foreach (Vector2 p in points)
		{
			GameObject g = GameObject.CreatePrimitive(PrimitiveType.Sphere);

			g.transform.parent = someObject.transform;
			g.transform.position = p;
			g.transform.localScale = Vector3.one * spacing * .5f;
		}

		}

	}

Second script :slight_smile:

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

public class PathFollower1 : MonoBehaviour {

	public float speed = 3f;
	public Transform pathParent;
	Transform targetPoint;
	int index;


	public float speedRotate = 7f;
	Vector3 distance;
	Quaternion newRotate;

	// Use this for initialization
	void Start () {
		index = 0;
		targetPoint = pathParent.GetChild (index);

	}
	
	// Update is called once per frame
	void Update () {
		transform.position = Vector3.MoveTowards (transform.position, targetPoint.position, speed * Time.deltaTime);
		rotate ();
		if (Vector3.Distance (transform.position, targetPoint.position) < 0.1f)
		{
			index++;
			index %= pathParent.childCount;
			targetPoint = pathParent.GetChild (index);
	}
}
	void rotate ()
	{

		distance = transform.position - targetPoint.position;
		newRotate = Quaternion.LookRotation (distance, transform.forward);
		newRotate.x = 0;
		newRotate.y = 0;
		transform.rotation = Quaternion.Lerp (transform.rotation, newRotate, speedRotate * Time.deltaTime);

}
}