- Home /
Question by
Devdu5 · Jan 25, 2021 at 05:36 PM ·
game developmentinfinite runner
How to keep runner on the track in unity?
I,m trying to create a Endless runner game. My goal is to move the player through the road with few bends. So I create a tile with a bends and then when I attach it to the scene player does not take bends. In the straight road he works fine and all the movements are working. But in the bends he does not turn, only go in straight. How to keep player on the road even in the bends??? (my player moves automatically, the user only controls the direction; left or right; think subway surfer). I attached here my tile and example screen shot of the game play.![Screenshot of the gameplay][1] ![This is the shape of the Tile][2]
Here is my player controller code.
using System.Collections;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
private CharacterController controller;
private Vector3 direction;
public float forwardSpeed;
public float maxSpeed;
private int desiredLane = 1;//0:left, 1:middle, 2:right
public float laneDistance = 2.5f;//The distance between tow lanes
public bool isGrounded;
public LayerMask groundLayer;
public Transform groundCheck;
public float jumpForce;
public float Gravity = -20;
public Animator[] animator;
private bool isSliding = false;
private int Index=0;
void Start()
{
controller = GetComponent<CharacterController>();
}
void Update()
{
if (!PlayerManager.isGameStarted)
return;
//Increase Speed
if(forwardSpeed < maxSpeed)
forwardSpeed += 0.1f * Time.deltaTime;
animator[Index].SetBool("isGameStarted", true);
direction.z = forwardSpeed;
Debug.Log("this is animator" + Index);
isGrounded = Physics.CheckSphere(groundCheck.position, 0.15f, groundLayer);
animator[Index].SetBool("isGrounded", isGrounded);
if (isGrounded)
{
if (SwipeManager.swipeUp)
Jump();
if (SwipeManager.swipeDown && !isSliding)
StartCoroutine(Slide());
}
else
{
direction.y += Gravity * Time.deltaTime;
if (SwipeManager.swipeDown && !isSliding)
{
StartCoroutine(Slide());
direction.y = -8;
}
}
//Gather the inputs on which lane we should be
if (SwipeManager.swipeRight)
{
animator[Index].SetTrigger("right");
desiredLane++;
if (desiredLane == 3)
desiredLane = 2;
}
if (SwipeManager.swipeLeft)
{
animator[Index].SetTrigger("left");
desiredLane--;
if (desiredLane == -1)
desiredLane = 0;
}
//Calculate where we should be in the future
Vector3 targetPosition = transform.position.z * transform.forward + transform.position.y * transform.up;
if (desiredLane == 0)
targetPosition += Vector3.left * laneDistance;
else if (desiredLane == 2)
targetPosition += Vector3.right * laneDistance;
//transform.position = targetPosition;
if (transform.position != targetPosition)
{
Vector3 diff = targetPosition - transform.position;
Vector3 moveDir = diff.normalized * 25 * Time.deltaTime;
if (moveDir.sqrMagnitude < diff.magnitude)
controller.Move(moveDir);
else
controller.Move(diff);
}
//Move Player
controller.Move(direction * Time.deltaTime);
}
private void Jump()
{
Debug.Log(jumpForce.ToString());
direction.y = jumpForce;
}
private void OnControllerColliderHit(ControllerColliderHit hit)
{
if(hit.transform.tag == "Obstacle")
{
PlayerManager.gameOver = true;
FindObjectOfType<AudioManager>().PlaySound("GameOver");
}
}
private IEnumerator Slide()
{
isSliding = true;
animator[Index].SetBool("isSliding", true);
controller.center = new Vector3(0, -0.5f, 0);
controller.height = 1;
yield return new WaitForSeconds(1.3f);
controller.center = Vector3.zero;
controller.height = 2;
animator[Index].SetBool("isSliding", false);
isSliding = false;
}
}
Here is my Tile manager code
using System.Collections.Generic;
using UnityEngine;
public class TileManager : MonoBehaviour
{
public GameObject[] tilePrefabs;
public float zSpawn = 0;
public float tileLength = 1010;
public int numberOfTiles = 1;
private List<GameObject> activeTiles = new List<GameObject>();
public Transform playerTransform;
void Start()
{
for (int i = 0; i < numberOfTiles; i++)
{
if(i==0)
SpawnTile(0);
else
SpawnTile(Random.Range(0, tilePrefabs.Length));
}
}
void Update()
{
if(playerTransform.position.z - 1010 > zSpawn -(numberOfTiles * tileLength))
{
SpawnTile(Random.Range(0, tilePrefabs.Length));
DeleteTile();
}
}
public void SpawnTile(int tileIndex)
{
GameObject go = Instantiate(tilePrefabs[tileIndex], transform.forward * zSpawn, transform.rotation);
activeTiles.Add(go);
zSpawn += tileLength;
}
private void DeleteTile()
{
Destroy(activeTiles[0]);
activeTiles.RemoveAt(0);
}
}
Comment