im making a game where enemies spawn randomly and you get 100 points everytime you kill one enemy, but whenever an enemy dies and a new one spawns the score sets itself to 0 again, i really don’t know how to explain this, maybe the code will help you understand better
EnemyScript in Enemy GameObject:
public ScoreScript scoreScript;
public float health = 100;
public float Score;
void Update()
{
scoreScript = GameObject.FindObjectOfType<ScoreScript>();
Score = GameObject.FindObjectOfType<ScoreScript>().Score;
}
void OnCollisionEnter2D(Collision2D col)
{
if(col.gameObject.tag.Equals("Bullet"))
{
health = health - 15;
Destroy(col.gameObject);
if(health <= 0)
{
StartCoroutine(DeathFrame());
}
else return;
}
if(col.gameObject.tag.Equals("Player"))
{
if(isDashing == true)
{
health = health - 40;
if(health <= 0)
{
StartCoroutine(DeathFrame());
}
else return;
}
}
}
IEnumerator DeathFrame()
{
Score = Score + 100;
scoreScript.SetScore(Score);
yield return new WaitForEndOfFrame();
Destroy(this.gameObject);
}
ScoreScript in ScoreValue TMP Text:
public TMP_Text scoreTxt;
public float Score = 0;
public void Update()
{
Debug.Log(Score); //always prints 0
}
public void SetScore(float Score)
{
Score = GameObject.FindObjectOfType<EnemyScript>().Score;
scoreTxt.text = Score.ToString("0"); //score shows 100 after killing an enemy, shows 0 if killing an enemy while there are more than 2 enemies in the scene unless killing the last one that spawned
}
It can be that simple, but the basic idea is your ScoreScript should not care about what enemies are on the screen. It should only worry about tracking score and displaying it. Thus it just takes input (negative or positive) before displaying it.
Your enemies should just have data on them to determine what needs to be sent off to other scripts. Stuff like how much damage they deal, hp, score value. They can also have methods on them dealing with that data, such as taking damage and adjusting HP, dealing damage, determining if they die, sending off values to the appropriate other scripts.
Your FindObjectOfType calls are definitely screwing things up.
Note that the above is a suggestion and isn’t the only way, but I do think it will improve your code.
This is an excellent fix to the problem. You could, perhaps, go a step further and make the Score value and AdjustScore method static, eschewing the use of a Singleton, as such:
public class ScoreScript : MonoBehaviour
{
private static int score;
public static void AdjustScore(int value)
{
score += value;
//Other code
}
}
In which case, when an enemy dies you’d merely have to call
ScoreScript.AdjustScore(value);
And to repeat what Brathnann said, FindObjectOfType calls aren’t very performant. If you MUST use it, then store the value to a variable or a property, as in this example:
public class ExampleScript : MonoBehaviour
{
private static ScoreScript scoreScript;
public static ScoreScript ScoreScript
{
get
{
if (!scoreScript)
scoreScript = FindObjectOfType<ScoreScript>();
return scoreScript;
}
}
}
Then you could reference the ScoreScript property to retrieve the cached reference to your desired script.