Im currently working on a basic game and its going well, the only thing I need to add is a timer. The game is made on the basic model of “Roll-a-Ball”.
I have a Player object and PickUp objects, there is 20 objects to pick up on the level.
What I would like here is a timer that starts at the beginning of the level (counting down from 20isch seconds). and adding 5 seconds every time the player picks up an object,
Then when all objects are collected the timer should stop and maybe play a big Guitext with the final time.
This is currently my PlayerController Script:
using UnityEngine;
using System.Collections;
public class PlayerController : MonoBehaviour
{
public float speed;
public GUIText countText;
public GUIText winText;
private int count;
void Start ()
{
count = 0;
SetCountText ();
winText.text = "";
}
void FixedUpdate ()
{
float moveHorizontal = Input.GetAxis("Horizontal");
float moveVertical = Input.GetAxis("Vertical");
Vector3 movement = new Vector3(moveHorizontal, 0, moveVertical);
GetComponent<Rigidbody> ().AddForce (movement * speed * Time.deltaTime);
}
void OnTriggerEnter(Collider other)
{
if (other.gameObject.tag == "PickUp")
{
other.gameObject.SetActive (false);
count = count + 1;
SetCountText ();
}
}
void SetCountText ()
{
countText.text = "Score: " + count.ToString();
if (count >= 20)
{
winText.text = "YOU WIN!";
}
}
}
Is it possible to modify this or should I make a completely new Scripts for the timer?
Any help would be highly appriciated!
I managed to input the code into my script.
But I still need to make a GUItext to show the time and preferably make the timer stop when all pickup objects are collected, do you think you can help me with this?
well as you know your scriptcomponents that inherit from Monobehaviour do not have a constructor. so you need to use Start or Awake to initialize your variables.
and Update is called every Frame automatically, so it makes sense to “update” your timer there.
So it does matter in which method you put it, but not necessarily in which line in this method - if that is your question.
to the part with the GUI. First i wouldn’t recommend using the OnGUI system at all. It is outdated for a good reason.
Instead try to get used to the new UI canvas system.
if you really do insist on using OnGUI() than i suggest using an enum that switches your gamestates. And a switch - case section in your OnGUI() Method that draws the corresponding GUI Elements that belong to each gamestate
edit:
sth like:
public enum EGameState
{
MAINMENU,
RUNNING,
PAUSED,
WON,
LOST
}
public EGameState m_gameState = EGameState.MAINMENU;
void OnGUI()
{
switch (m_gameState)
{
case EGameState.MAINMENU:
break;
case EGameState.RUNNING:
break;
case EGameState.PAUSED:
break;
case EGameState.WON:
GUI.TextArea(new Rect(0, 0, 100, 100), "YOU WON");
break;
case EGameState.LOST:
break;
default:
break;
}
}
if you would now switch your gamestate with your “win-condition” your textbox would also appear
I’m sorry, but I kinda have a hard time to keep up since I dont know how much of this works.
Im not used to Unity and dont know how to use the UI canvas, and with this example you gave me, I’m still not sure what I need to add/change in the scene.
I’m kind of confused tbh.
All I really wanted was the time to be shown somewhere, like the 2 other texts I have.
and then when the objects were collected for the timer to stop.
I’ve basically just added all the code you gave me into the script, but nothing more, dont really know what to do next.
Works really well, the only thing missing is adding 5 sec on pickup. but it doesnt really matter, this is amazing!
Thank you for all your trouble and sorry if I seem a bit slow, like I said. I am completely new to this
using UnityEngine;
using System.Collections;
public class InternalTimer
{
public System.Action OnCompleted;
public System.Action<float> OnProgress;
public float time = 5f;
public bool enabled = true;
public bool oneTime = false;
private float m_internalTimer = 0f;
public InternalTimer(float aTime)
{
time = aTime;
}
public bool Tick()
{
if (!enabled)
return false;
m_internalTimer += Time.deltaTime;
if (OnProgress != null)
OnProgress(Mathf.Clamp01(m_internalTimer / time));
if (m_internalTimer >= time)
{
Reset();
if (oneTime)
enabled = false;
if (OnCompleted != null)
OnCompleted();
return true;
}
return false;
}
public void Reset()
{
m_internalTimer = 0;
}
}
So basically you create the timer instance within Start() method:
public timeNeeded = 5f;
private InternalTimer m_timer;
void Start()
{
m_timer = new Timer( timeNeeded );
}
Then you put it inside your Update() method to invoke Tick() method: