Reputation: 265
I made a scoring system based on destroyed balls, so on start, the score is 82, and each ball destroyed should decrease the score by 1.
i made a script for the ball, but the score didn't work properly, can you tell me what's wrong in my code?
This is the ball script:
public class Ball : MonoBehaviour {
private int Count;
public Text TextCount;
// Update is called once per frame
Rigidbody rb;
public float destroyTimeOut = 2;
bool hitBase = false;
void Start()
{
rb = GetComponent<Rigidbody>();
Count = 82;
SetTextCount();
}
void Update () {
if(rb.position.y < -3)
{
Destroy(gameObject);
Count = Count - 1;
SetTextCount();
}
if (hitBase)
{
timer += Time.deltaTime;
if (timer > destroyTimeOut)
{
Destroy(gameObject);
Count = Count - 1;
SetTextCount();
}
}
}
float timer;
private void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.CompareTag("base"))
{
hitBase = true;
}
}
void SetTextCount()
{
TextCount.text = Count.ToString();
}
}
Thanks,
Upvotes: 1
Views: 257
Reputation: 11
If you make Count a static, then each Ball object will share the same value in memory. As someone else pointed-out, if there are more than one of these Ball objects, they would each have their own idea of the value for Count.
static int Count;
Make it static in the class (add one word to your source code) and I think it will act as you desire.
Also, you don't need to explicitly declare 'private' it is the default.
public class Ball : MonoBehaviour {
static int Count;
public Text TextCount;
// Update is called once per frame
Rigidbody rb;
public float destroyTimeOut = 2;
bool hitBase = false;
void Start()
{
rb = GetComponent<Rigidbody>();
Count = 82;
SetTextCount();
}
void Update () {
if(rb.position.y < -3)
{
Destroy(gameObject);
Count = Count - 1;
SetTextCount();
}
if (hitBase)
{
timer += Time.deltaTime;
if (timer > destroyTimeOut)
{
Destroy(gameObject);
Count = Count - 1;
SetTextCount();
}
}
}
float timer;
private void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.CompareTag("base"))
{
hitBase = true;
}
}
void SetTextCount()
{
TextCount.text = Count.ToString();
}
}
Upvotes: 0
Reputation: 125375
When you call Destroy(gameObject)
this GameObject is destroyed with this Ball
script that is attached to it.
Separate your score system from the ball collision detection system.
1.Create an Empty GameObject and name it "ScoreSystem".
2.Create a script and name it "ScoreSys" then use the code below inside it.
3.Attach it to the "ScoreSystem". GameObject.
public class ScoreSys : MonoBehaviour
{
public Text TextCount;
private int _Count;
public int Count
{
get
{
return _Count;
}
set
{
if (_Count != value)
{
_Count = value;
TextCount.text = _Count.ToString();
}
}
}
void Start()
{
Count = 82;
TextCount.text = _Count.ToString();
}
}
The score system now has it's own code and GameObject and it won't be destroyed. Also, Text
is also updated when score changes.
Now, you also have to separate the Ball
script. Simply find the "ScoreSystem" GameObject, get the ScoreSys
component attached to it and updated the score. The Ball
script should be attached to the Ball Object that will be destroyed.
Note that I have no idea when the score should update but below is the translation of your current code. You may need to make some changes to get it working properly.
public class Ball : MonoBehaviour
{
ScoreSys scoreSys;
Rigidbody rb;
public float destroyTimeOut = 2;
bool hitBase = false;
void Start()
{
GameObject scoreObj = GameObject.Find("ScoreSystem");
scoreSys = scoreObj.GetComponent<ScoreSys>();
rb = GetComponent<Rigidbody>();
}
void Update()
{
if (rb.position.y < -3)
{
scoreSys.Count--;
Destroy(gameObject);
}
if (hitBase)
{
timer += Time.deltaTime;
if (timer > destroyTimeOut)
{
scoreSys.Count--;
Destroy(gameObject);
}
}
}
float timer;
private void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.CompareTag("base"))
{
hitBase = true;
}
}
}
Upvotes: 1