Search Unity

Question Move First Person Character Controller Along a Spline

Discussion in 'World Building' started by kenmarold, May 21, 2023.

  1. kenmarold

    kenmarold

    Joined:
    Jun 11, 2015
    Posts:
    27
    Hi everyone, I haven't worked in Unity in a few years and am just getting into using the new Spline tool for the first time. I've set up a spline and laid out a path, etc. and now I'm needing to move a first person character controller along the spline using two particular scenarios, via keyboard input and also through input via connected Arduinos. The first way, the simplest way, using arrow keys (forward/backward) to increment/decrement the Path Position. Two, more complicated, but ultimately the way I actually need to do it is to move the camera dynamically along the path using an ever changing range of values, fed by an arduino connected to a tachometer on a stationary bike, 0 to 100 for instance, to simulate speed. The main thing I really need to solve in the immediate short term is linking the character controller to the spline and using arrow keys to move forward/backward along the spline path.

    I know this is probably a pretty big question, but if anyone could just point me in the right direction, or if you have particular examples that you've come across that address these questions I would appreciate the help immensely! Thank you!
     
  2. Yuchen_Chang

    Yuchen_Chang

    Joined:
    Apr 24, 2020
    Posts:
    127
    You could use Spline.Evaluate(Vector3 normalizedLength) to get the position and rotation on the spline.

    Here's an example:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.Splines;
    5.  
    6. public class SplineMoving : MonoBehaviour
    7. {
    8.     [SerializeField] private SplineContainer spline;
    9.     [SerializeField] private float maxSpeed = 3f;
    10.  
    11.     private float currentPos;
    12.  
    13.     private void Update()
    14.     {
    15.         UpdatePosOnSpline();
    16.     }
    17.  
    18.     private void UpdatePosOnSpline()
    19.     {
    20.         var splineLength = spline.Spline.GetLength();
    21.         var currentSpeed = GetMoveSpeed();
    22.         // make sure on spline
    23.         currentPos = Mathf.Clamp(currentPos + currentSpeed * Time.deltaTime, 0f, splineLength);
    24.         // most important part: evaluate currentPos on spline
    25.         var normalizedPos = currentPos / splineLength;
    26.         spline.Spline.Evaluate(normalizedPos, out var pos, out var dir, out var up);
    27.         transform.SetPositionAndRotation(pos, Quaternion.LookRotation(dir));
    28.     }
    29.  
    30.     private float GetMoveSpeed()
    31.     {
    32.         // put your evaluating logic here (keyboard or arduino)
    33.         return Input.GetAxis("Vertical") * maxSpeed;
    34.     }
    35. }
    36.  
     
    Sledzislaw likes this.