- Home /
How to I get the timer counter to restart when the player hits the ground and respawns?
So I am creating a 2D platformer and the goal is to go as long as possible without dying, and I need to make it so when the player hits the ground, the text displaying the amount of time the player has ran for restarts. I will post the code that I have already written.
Any and all help is greatly appreciated Score Manager Script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class ScoreManager : MonoBehaviour
{
public Text scoreText;
public Text hiScoreText;
public float scoreCount = 0;
public float hiScoreCount = 0;
public float pointsPerSecond = 2;
public bool scoreIncreasing;
void Update()
{
if (scoreIncreasing)
{
scoreCount += pointsPerSecond * Time.deltaTime;
}
if (scoreCount > hiScoreCount)
{
hiScoreCount = scoreCount;
}
scoreText.text = "Score: " + Mathf.Round(scoreCount);
hiScoreText.text = "High Score: " + Mathf.Round(hiScoreCount);
}
public void ResetPlayerScore()
{
scoreCount = 0;
scoreText.text = "Score: 0";
scoreIncreasing = false;
}
public void EnableScoring()
{
scoreIncreasing = true;
}
}
Caller Script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Caller : MonoBehaviour {
ScoreManager _sm;
void Start()
{
// Get reference to ScoreManager in scene
_sm = GameObject.Find("ScoreManager").GetComponent<ScoreManager>();
}
private void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.layer == LayerMask.NameToLayer("Player"))
{
_sm.ResetPlayerScore(); // sample example of calling a method written in your ScoreManager
}
}
private void OnCollisionExit2D(Collision2D collision)
{
if (collision.gameObject.layer == LayerMask.NameToLayer("Player"))
{
_sm.EnableScoring();
}
}
}
Answer by melsy · Apr 05, 2018 at 11:59 PM
I canhed this post to rewrite your two classes a little cleaner and commented them pretty well to help you understand.
using UnityEngine;
using UnityEngine.UI;
public class ScoreManager : MonoBehaviour
{
// SerializeField is a way to see the privae variable in the inspector.
// When coding it is a good idea to not let a variable be accessed by anything that
// it doesn't need to be. If it is only used in this class it should be private.
[SerializeField]
Text scoreText;
[SerializeField]
Text hiScoreText;
[SerializeField]
float scoreCount = 0;
[SerializeField]
float hiScoreCount = 0;
[SerializeField]
float pointsPerSecond = 2;
// Assign the player to this in the inspector.
[SerializeField]
SimplePlatformScript player;
const string sScore = "Score: ";
const string sHighScore = "High Score: ";
void Update()
{
if (scoreIncreasing)
scoreCount += pointsPerSecond * Time.deltaTime;
if (scoreCount > hiScoreCount)
{
hiScoreCount = scoreCount;
// The high score only needs to be updated when the score is higher. Not every frame.
UpdateHighScoreText();
}
UpdateScoreText();
}
public void ResetPlayerScore()
{
scoreCount = 0;
scoreText.text = "Score: 0";
}
void UpdateScoreText()
{
scoreText.text = string.Format("{0} {1}", sScore, Mathf.Round(scoreCount));
}
void UpdateHighScoreText()
{
hiScoreText.text = string.Format("{0} {1}", sHighScore, Mathf.Round(hiScoreCount));
}
}
public class SimplePlatformScript : MonoBehaviour
{
//[HideInInspector] public bool facingRight = true;
[HideInInspector] public bool jump = false;
//public float moveForce = 365f;
//public float maxSpeed = 5f;
public float jumpForce = 1000f;
public Transform groundCheck;
// Store the layer in this reference so it doesnt have to create a new reference
// every physics frame.
[SerializeField]
LayerMask whatIsGround;
// Changed this to a public so the ScoreManager can see it.
[SerializeField]
public bool grounded = false;
//private Animator anim;
private Rigidbody2D rb2d;
// Use const string anytime you are calling a string more than once.
// Everytime you call a literal string it puts a new one in memory.
// Doing it like this make it only create one.
const string sJump = "Jump";
// Use this for initialization
void Awake()
{
//anim = GetComponent<Animator>();
rb2d = GetComponent<Rigidbody2D>();
}
void Update()
{
if (Input.GetButtonDown(sJump) && grounded)
{
// This is ok to do in update as it feels better to the player.
// This is a physics action but doing an input actions
// feels off to the player if there is a delay.
rb2d.AddForce(new Vector2(0f, jumpForce));
}
}
void FixedUpdate()
{
// Any physics calculations are better done in the FixedUpdate.
grounded = Physics2D.Linecast(transform.position, groundCheck.position, whatIsGround);
}
}
public class SimplePlatformScript : $$anonymous$$onoBehaviour
{
//[HideInInspector] public bool facingRight = true;
[HideInInspector] public bool jump = false;
//public float moveForce = 365f;
//public float maxSpeed = 5f;
public float jumpForce = 1000f;
public Transform groundCheck;
private bool grounded = false;
//private Animator anim;
private Rigidbody2D rb2d;
// Use this for initialization
void Awake()
{
//anim = GetComponent<Animator>();
rb2d = GetComponent<Rigidbody2D>();
}
// Update is called once per frame
void Update()
{
grounded = Physics2D.Linecast(transform.position, groundCheck.position, 1 << Layer$$anonymous$$ask.NameToLayer("Ground"));
if (Input.GetButtonDown("Jump") && grounded)
{
jump = true;
}
}
void FixedUpdate()
{
if (jump)
{
//anim.SetTrigger("Jump");
rb2d.AddForce(new Vector2(0f, jumpForce));
jump = false;
}
}
}
I am getting some compiler errors that I cannot seem to decipher.
UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr)Assertion failed: Assertion failed on expression: 'm_CurrentEntriesPtr != NULL && m_IsGettingEntries'
UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr)Assertion failed: Assertion failed on expression: 'm_CurrentEntriesPtr != NULL && m_IsGettingEntries'
Assets/Scripts/Caller.cs(26,17): error CS1061: Type
Score$$anonymous$$anager' does not contain a definition for
EnableScoring' and no extension methodEnableScoring' of type
Score$$anonymous$$anager' could be found. Are you missing an assembly reference? Assets/Scripts/Score$$anonymous$$anager.cs(28,13): error CS0103: The name `scoreIncreasing' does not exist in the current context
Answer by MiloRoban · Apr 06, 2018 at 02:28 AM
This is my player jump script. using UnityEngine; using System.Collections;
public class SimplePlatformScript : MonoBehaviour
{
//[HideInInspector] public bool facingRight = true;
[HideInInspector] public bool jump = false;
//public float moveForce = 365f;
//public float maxSpeed = 5f;
public float jumpForce = 1000f;
public Transform groundCheck;
private bool grounded = false;
//private Animator anim;
private Rigidbody2D rb2d;
// Use this for initialization
void Awake()
{
//anim = GetComponent<Animator>();
rb2d = GetComponent<Rigidbody2D>();
}
// Update is called once per frame
void Update()
{
grounded = Physics2D.Linecast(transform.position, groundCheck.position, 1 << LayerMask.NameToLayer("Ground"));
if (Input.GetButtonDown("Jump") && grounded)
{
jump = true;
}
}
void FixedUpdate()
{
if (jump)
{
//anim.SetTrigger("Jump");
rb2d.AddForce(new Vector2(0f, jumpForce));
jump = false;
}
}
}
make this a comment to my answer. That is exactly what i thought it would look like. Change my PlayerScript
to yours, Then make your grounded bool public , you can use the attribute [HideInInspector]
above it if you want to not show it in the inspector. Put my stuff inside the score$$anonymous$$anager
and all should work perfect.
Excuse my incompetence, but what do you mean by changing your PlayerScript to $$anonymous$$e?