How to smoothly turn character controller in X Direction

Viewed 68

Overview

I'm making an endless runner game. In this game, I have 5 lines, I want to player smoothly switch lines something like this Ref Link

My Game Image

In my case, I have everything the same but instead of a car, I have a player with PlayerController attached to it. I'm changing the player line on Button click and also on IPointerDownHandler & IPointerUpHandler

Code

Full Code

[SerializeField]  private    List<Vector3>    lines; // 5 lines in my case. Vector3 (0,0,0) and so on ...
private int flag;
Vector3 currLine;

private void ChangeLines () 
{
   // Getting Inputs
   if (Input.GetKey(KeyCode.LeftArrow)) { flag = -1; }
   else if (Input.GetKey(KeyCode.RightArrow)) { flag = 1; }
   else flag = 0;
   
   if (flag > 0) MoveRight ();
   else if (flag < 0) MoveLeft ();
}

//I used two approaches to moving but both are not working as indented    
// 1 _ using DoTween
// 2 _ using Vector3.Lerp ()

private void MoveRight ()
{
  // some input delay for Ipointers
  if (inputDelay > 0) return;
  
  if (currLine == lines [lines.Count - 1]) return; // can't move right anymore
  transform.DoRotate (new Vector3(0, 45, 0) , 0.2f); // rotate player toward target
  transform.DoMoveX (currLine.X, 0.3f) // 0.3f is coming from inspector
  .SetEase (Ease.Linear) // i almost tried all Ease 
  .OnComplete ( ()=> DoTween.DoRotate (new Vector3(0, 0, 0) , 0.2f));
  
  // using Lerp  
  LookAt (new Vector3 (currLine.x,Y,Z));
  transform.position = Vector3.Lerp(transform.position, new Vector3(currLine.x, ..,..), lineChangeCurve
                .Evaluate(Time.deltaTime * lineChangeSpeed)); 
}

private void MoveLeft () 
{ 
 // same code as MoveRight
}

Problem

The code I wrote is prettier much working. the player is changing lines and also rotating towards the line but I'm unable to figure out what should i need to do to make this effect look like a reference.

Can you tell me how can I achieve the same smoother effect as the reference for my player?

Here is the link that I made so far

3D Assets link

Player lines distance :

new Vector3 (-8, 0,0)
new Vector3 (-4, 0,0)
new Vector3 (0, 0,0)
new Vector3 (4, 0,0)
new Vector3 (8, 0,0)

Thanks in Advance

2 Answers

You seem to be mixing two different animation techniques.

You do

transform.DoMoveX (currLine.X, 0.3f)
.SetEase (Ease.Linear)
...

which starts a tween animation

and then you also do Evaluate on the lerp which seems to be a bit redundant.


Your issue with the Lerp and Evaluate is

  • a) that you pass in

     Time.deltaTime * lineChangeSpeed
    

    which basically means

     lineChangeSpeed / frame rate (e.g. 60)
    

    => This is a way to small value and will most probably basically mean you don't move at all (depending on your used curve)

    You want to call this every frame and pass in a value increasing from 0 to 1 here (e.g. in a Coroutine)

  • b) you call it only exactly once. This will not result in any movement at all .. or at least only in a single step in the first frame => which probably causes a little "hiccup"

=> get rid of the lerp line all together. At best it interferes with the tween animation and is probably the cause of it looking somewhat off

I used Lerp() for these kind of conditions and it worked well all the time. As I saw your character correctly turns but it look like a snap turn. I couldn't spot an obvious error in your code. Play a little more with the rotation time and you will get your desired result. Sorry this must be a comment but dont have the reps.

Related