Bizarre Respawn Bug
I'm a fairly experienced programmer, but I'm new to Unity and its scripting API (and C# for that matter, though I know Java). I'm going through Sam's Teach Yourself Unity in 24 Hours, and I've just built a very simple "racer" game according to the instructions given in the book. The game consists of running from an initial spawn down a winding path to a finish point. If you fall into the water on either side of the path, you respawn at the initial spawn point, and if you finish, you have the option to play again. Programmatically, these features are managed by three scripts, a main script called GameManager
and the other two implementing OnTriggerEnter
for when the player collides with the water or the finish point, respectively. The GameManager
script is attached to an empty object.
The first indication that something was wrong was that the empty object holding GameManager
did not automatically appear in the list of available objects to link to from the other scripts, even though it was clearly referenced in the code. I had to drag and drop it manually. Then, when I tried to play, the player would not teleport to the spawn from either the finish or the water line. Both OnTriggerEnter
and the GameManager
method it delegates to were called, in fact. They simply didn't have any observable effect on the player.
I know someone who's working on the same project and his game has a bug that seems identical to mine. We are all using the same pre-made scripts for this (this is part of a college course), so I'm almost certain the causes of our bugs are the same. Notably, we are both using version 2018.3 of Unity, and everything worked fine for those with earlier versions. On his, the player actually did teleport to spawn, but only stayed there for one frame and then went back to where he was. I haven't verified this for mine, but there's a good chance it is doing the same thing. (Note: This is not just an attempt to get someone to do my assignment for me. Scripting isn't even part of this one (it's covered later), and even our professor is at a loss as to what might be causing the bug. In fact, he encouraged me to post this here.)
Here's the code:
PlayerRespawn.cs
using UnityEngine;
using System.Collections;
public class PlayerRespawn : MonoBehaviour
{
//A reference to the game manager
public GameManager gameManager;
// Triggers when the player enters the water
void OnTriggerEnter(Collider other)
{
// Moves the player to the spawn point
gameManager.PositionPlayer();
}
}
FinishZone.cs
public class FinishZone : MonoBehaviour
{
//A reference to the game manager
public GameManager gameManager;
// When an object enters the finish zone, let the
// game manager know that the current game has ended
void OnTriggerEnter(Collider other)
{
gameManager.FinishedGame();
}
}
GameManager.cs
using UnityEngine;
using UnityStandardAssets.Characters.FirstPerson;
public class GameManager : MonoBehaviour
{
// Place holders to allow connecting to other objects
public Transform spawnPoint;
public GameObject player;
// Flags that control the state of the game
private float elapsedTime = 0;
private bool isRunning = false;
private bool isFinished = false;
// So that we can access the player's controller from this script
private FirstPersonController fpsController;
// Use this for initialization
void Start ()
{
// Finds the First Person Controller script on the Player
fpsController = player.GetComponent<FirstPersonController> ();
// Disables controls at the start.
fpsController.enabled = false;
}
//This resets to game back to the way it started
private void StartGame()
{
elapsedTime = 0;
isRunning = true;
isFinished = false;
// Move the player to the spawn point, and allow it to move.
PositionPlayer();
fpsController.enabled = true;
}
// Update is called once per frame
void Update ()
{
// Add time to the clock if the game is running
if (isRunning)
{
elapsedTime = elapsedTime + Time.deltaTime;
}
}
//Runs when the player needs to be positioned back at the spawn point
public void PositionPlayer()
{
player.transform.position = spawnPoint.position;
player.transform.rotation = spawnPoint.rotation;
}
// Runs when the player enters the finish zone
public void FinishedGame()
{
isRunning = false;
isFinished = true;
fpsController.enabled = false;
}
//This section creates the Graphical User Interface (GUI)
void OnGUI() {
if(!isRunning)
{
string message;
if(isFinished)
{
message = "Click or Press Enter to Play Again";
}
else
{
message = "Click or Press Enter to Play";
}
//Define a new rectangle for the UI on the screen
Rect startButton = new Rect(Screen.width/2 - 120, Screen.height/2, 240, 30);
if (GUI.Button(startButton, message) || Input.GetKeyDown(KeyCode.Return))
{
//start the game if the user clicks to play
StartGame ();
}
}
// If the player finished the game, show the final time
if(isFinished)
{
GUI.Box(new Rect(Screen.width / 2 - 65, 185, 130, 40), "Your Time Was");
GUI.Label(new Rect(Screen.width / 2 - 10, 200, 20, 30), ((int)elapsedTime).ToString());
}
else if(isRunning)
{
// If the game is running, show the current time
GUI.Box(new Rect(Screen.width / 2 - 65, Screen.height - 115, 130, 40), "Your Time Is");
GUI.Label(new Rect(Screen.width / 2 - 10, Screen.height - 100, 20, 30), ((int)elapsedTime).ToString());
}
}
}
Your answer
Follow this Question
Related Questions
My Brain is fogged: How do I move a networked object with user input 0 Answers
Vector3.Lerp not working properly, making the player bounce around 2 Answers
Using components through a coroutine not working 1 Answer
Hi! I am trying to use SceneManagement, but I keep getting errors. 1 Answer
If all tagged objects are destroyed 1 Answer