I want to create a checkpoint system for my car game. I have an empty game Object called Checkpoints which has multiple children for the checkpoints themselves (each being called Checkpoint Single
).
Each Checkpoint Single
having three children itself:
· Checkpoint Enter
- used just to get the position where to teleport the player
· Checkpoint Area
- used to detect if the player is on route, if not he gets teleported to the Checkpoint Enter
’s location after a timer with a black fade on screen
· Checkpoint Exit
-used to detect and update the checkpoint where the player needs to go next
The problem I am having is that, whatever I try to do, if the player goes out of the Checkpoint Area
it is not teleported to the right location.
Bonus problem: if the player tries to get out of the first Checkpoint Area
I get an error Here are the scripts I am using:
This is placed on the empty game Object (Checkpoints) with the multiple children:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
public class TrackCheckpoints : MonoBehaviour
{
//Checkpoint GameObject with all the CheckpointSingles
public static GameObject checkpoints;
[Header("Countdown")]
public static GameObject countdownGameObject;
public GameObject assignCountdownText;
[Header("Time to get back on route")]
public static float timeBeforeRespawn;
public float assignTimeBeforRespawn = 5f;
[Header("Black fade in panel")]
public static CanvasGroup blackCanvas;
public CanvasGroup assignBlackCanvas;
void Awake()
{
timeBeforeRespawn = assignTimeBeforRespawn;
countdownGameObject = assignCountdownText;
blackCanvas = assignBlackCanvas;
checkpoints = gameObject;
}
}
This is the script on all Checkpoint Single objects
using System.Collections;
using System.Collections.Generic;
using JetBrains.Annotations;
using UnityEngine;
using TMPro;
using System.Threading;
using System;
public class CheckpointSingle : MonoBehaviour
{
//Player variables
private Transform playerTransform;
private Rigidbody playerRigidBody;
void Start()
{
TrackCheckpoints trackCheckpoints = gameObject.GetComponentInParent<TrackCheckpoints>();
playerTransform = GameObject.FindGameObjectWithTag("Player").GetComponent<Transform>();
playerRigidBody = GameObject.FindGameObjectWithTag("Player").GetComponent<Rigidbody>();
TrackCheckpoints.blackCanvas.alpha = 0;
}
void Update()
{
Countdown();
BlackFade();
}
void BlackFade()
{
if (CheckpointArea.fadeIn == true)
{
TrackCheckpoints.blackCanvas.alpha += (float) 1 * Time.deltaTime;
if ( TrackCheckpoints.blackCanvas.alpha == 1)
{
playerTransform.position = CheckpointExit.currentCheckpointEnter.position + new Vector3 ( 0 , -2 , 0);
playerTransform.eulerAngles = CheckpointExit.currentCheckpointEnter.eulerAngles + new Vector3 ( 0 , 90 , 0) ;
}
}
else
{
TrackCheckpoints.blackCanvas.alpha -= (float) 1 * Time.deltaTime;
if ( TrackCheckpoints.blackCanvas.alpha == 0 )
playerRigidBody.constraints = RigidbodyConstraints.None;
}
}
void Countdown()
{
if (CheckpointArea.outOfRoute == true)
{
CheckpointArea.timer -= 1 * Time.deltaTime;
CheckpointArea.CountdownText.text = string.Format($"Checkpoint Missed! \n {(int)CheckpointArea.timer}");
}
if (CheckpointArea.timer <= 0)
{
CheckpointArea.fadeIn = true;
playerRigidBody.constraints = RigidbodyConstraints.FreezeAll;
}
}
}
This is the script on all Checkpoint Area objects
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
public class CheckpointArea : MonoBehaviour
{
//Bools
public static bool outOfRoute;
public static bool fadeIn;
public static float timer;
//UI Text
public static TMP_Text CountdownText;
void Start ()
{
CountdownText = TrackCheckpoints.countdownGameObject.GetComponent<TMP_Text>();
timer = TrackCheckpoints.timeBeforeRespawn;
fadeIn = false;
}
void OnTriggerExit(Collider collider)
{
if (collider.tag == "Player Body")
{
PlayerOutOfRoute();
}
}
void OnTriggerStay(Collider collider)
{
if (collider.tag == "Player Body")
{
PlayerOnRoute();
}
}
public void PlayerOutOfRoute()
{
outOfRoute = true;
CountdownText.enabled = true;
}
public void PlayerOnRoute()
{
outOfRoute = false;
timer = TrackCheckpoints.timeBeforeRespawn;
fadeIn = false;
CountdownText.enabled = false;
}
}
And finally, this is the script on all Checkpoint Exits objects
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CheckpointExit : MonoBehaviour
{
//Checkpoitn variabels
private Transform currentCheckpointSingle;
public static Transform currentCheckpointEnter;
private int currentCheckpointIndex;
private int totalCheckpointNumber;
void Start()
{
currentCheckpointIndex = 0;
totalCheckpointNumber = TrackCheckpoints.checkpoints.transform.childCount;
}
void OnTriggerEnter(Collider collider)
{
if (collider.tag == "Player Body")
{
if (currentCheckpointSingle == TrackCheckpoints.checkpoints.transform.GetChild(currentCheckpointIndex).transform)
currentCheckpointIndex = (1 + currentCheckpointIndex) % totalCheckpointNumber;
currentCheckpointSingle = TrackCheckpoints.checkpoints.transform.GetChild(currentCheckpointIndex).transform;
currentCheckpointEnter = currentCheckpointSingle.GetChild(0).transform;
}
}
}
From some of the testing I have made, I think the problem is in the Checkpoint Exit
script, but I have added all the scripts in case they interfere with each another