Lane change mechanism,I have an algorithm that makes it similar to the one in Subway Surfer and it works. However, as far as I’ve learned, this code should not work properly because for example, (-2.5,0,0) should be in Vector and let’s assume that the target position is 2.5f, so the result (5 ,0,0) but the code works.
And then we multiply moveVector.x by speed, so it should break the code, but it still works.
Despite all this, how can my character switch between -2.5 0 and 2.5 perfectly? How does CharacterController.Move work?
My Code ;
(LANE_DISTANCE = 2.5F BTW)
if (desiredLane == 0) //1 Birim sola kay
targetposition += Vector3.left * LANE_DISTANCE;
else if (desiredLane == 2) //1 Birim saga kay
targetposition += Vector3.right * LANE_DISTANCE;
//Calculate our move delta
Vector3 moveVector = Vector3.zero;
moveVector.x = (targetposition - transform.position).x * playerSpeed;
moveVector.z = playerSpeed;
Vector3 move = new Vector3(moveVector.x, 0,moveVector.z);
controller.Move(move * Time.deltaTime * playerSpeed);
All codes in the Script;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Testcontroller : MonoBehaviour
{
private const float LANE_DISTANCE = 2.5f;
//private const float TURN_SPEED = 0.05f;
private bool isRunning = false;
private CharacterController controller;
private Vector3 playerVelocity;
private bool groundedPlayer;
private float playerSpeed = 2.0f;
private float jumpHeight = 1.5f;
private float gravityValue = -25.81f;
private int desiredLane = 1; // 0 = left, 1 = middle, 2 = right
//Animator
private Animator anim;
private Animator coinAnim;
private float originalSpeed = 7.0f;
private float speedIncreaseLastTick; //En son ne zaman hizi arttirdigimizin kaydini tutuyor
private float speedIncreaseTime = 2.5f;
private float speedIncreaseAmount = 0.1f;
private void Start()
{
//playerSpeed = originalSpeed; => DUZELT
controller = gameObject.GetComponent<CharacterController>();
anim = GetComponent<Animator>();
}
void Update()
{
if(!isRunning)
return;
if(Time.time - speedIncreaseLastTick > speedIncreaseTime)
{
speedIncreaseLastTick = Time.time;
playerSpeed += speedIncreaseAmount;
//Change the modifier text
GameManager.Instance.UpdateModifier(playerSpeed - originalSpeed);
}
groundedPlayer = controller.isGrounded;
anim.SetBool("Grounded",groundedPlayer);
if (groundedPlayer && playerVelocity.y < 0)
{
playerVelocity.y = 0f;
}
//Gather inputs on which lane we should be
if(MobileInput.Instance.SwipeLeft || Input.GetKeyDown(KeyCode.LeftArrow))
MoveLane(false);
if(MobileInput.Instance.SwipeRight || Input.GetKeyDown(KeyCode.RightArrow))
MoveLane(true);
//Calculate where we should be
Vector3 targetposition = transform.position.z * Vector3.forward; //Burada Vector3.zero yazmanin bir sey degistirmeyecegini fark ettim cunku z ekseni zaten asagida move.z kisminda tekrar ayarlaniyor
if (desiredLane == 0) //1 Birim sola kay
targetposition += Vector3.left * LANE_DISTANCE;
else if (desiredLane == 2) //1 Birim saga kay
targetposition += Vector3.right * LANE_DISTANCE;
//Calculate our move delta
Vector3 moveVector = Vector3.zero;
moveVector.x = (targetposition - transform.position).x * playerSpeed;
moveVector.z = playerSpeed;
Vector3 move = new Vector3(moveVector.x, 0,moveVector.z);
controller.Move(move * Time.deltaTime * playerSpeed);
//Karakteri rotate eden kod
if (move != Vector3.zero)
{
gameObject.transform.forward = move;
}
// Changes the height position of the player..
if (Input.GetKeyDown(KeyCode.UpArrow) && groundedPlayer)
{
anim.SetTrigger("Jump");
playerVelocity.y += Mathf.Sqrt(jumpHeight * -3.0f * gravityValue);
}
if (Input.GetKeyDown(KeyCode.DownArrow) && groundedPlayer)
{
StartSliding();
}
if(Input.GetKeyDown(KeyCode.DownArrow))
{
playerVelocity.y -= jumpHeight;
}
playerVelocity.y += gravityValue * Time.deltaTime;
controller.Move(playerVelocity * Time.deltaTime);
}
private void MoveLane(bool goingRight)
{
desiredLane += goingRight ? 1 : -1;
desiredLane = Mathf.Clamp(desiredLane, 0, 2);
}
public void StartRunning()
{
isRunning = true;
anim.SetBool("Running",isRunning);
}
private void StartSliding()
{
anim.SetBool("Sliding",true);
Invoke("StopSliding",1.0f);
controller.height /= 2;
controller.center = new Vector3(controller.center.x,controller.center.y /2,controller.center.z);
}
private void StopSliding()
{
anim.SetBool("Sliding",false);
controller.height *= 2;
controller.center = new Vector3(controller.center.x,controller.center.y *2,controller.center.z);
}
/*
Su an ki Character Controller ayarlari;
Slope limit : 45 - (hic degismedi)
Step Offset : 0.3 - (hic degismedi)
Skin Width : 0.04
Min Move Distance : 0.001
Center X0 Y1 Z0
Radius : 0.3
Height : 2
*/
//Robot skin width yuzunden yerden 0.04 yukseklikte durdugu icin havada suzuluyor gibi gozukuyordu ancak robot modelinin root child objesini biraz asagi indirdigim zaman bu sorun cozuldu
//Skin Width'i 0.050 olarak degistirdim cunku animasyon titriyordu bu sebeple Raycast degerinide 0.2f + 0.5f olarak degistirdim cunku 0.05 olunca yerden 0.05 yukarida baslatiyor.
void OnTriggerEnter(Collider other)
{
if(other.CompareTag("Coin"))
{
GameManager.Instance.GetCoin();
coinAnim = other.GetComponent<Animator>();
coinAnim.SetTrigger("Collected");
//Destroy(other,1.0f);
}
}
private void Crash()
{
anim.SetTrigger("Death");
isRunning = false;
GameManager.Instance.OnDeath();
}
private void OnControllerColliderHit(ControllerColliderHit hit)
{
switch(hit.gameObject.tag)
{
case "Obstacle":
Crash();
break;
}
}
}