Search code examples
c#unity-game-engineunityscriptgameobject

Check value of a variable from every gameobject that attached by a script


I have a game object called "student" that has a script attached, then I duplicate it manually (ctrl+D) so every duplicated student object has the same script component. here's the script (not full because too long)

public class StudentScript : MonoBehaviour {

private Animator animator;
float sec;
public int m;
public GameManage gm;

void Start () {
    animator = GetComponent<Animator> ();
    sec = 0f;
    m = 0;
}

void Update () {
    sec+=Time.deltaTime;
    if (m == 5 && animator.GetInteger ("Behav") == 0) {
        animator.SetTrigger ("Finish");
    }
}

//this is called from another script
public void ResetStudentBehaviour(){
    if (animator.GetInteger ("Behav") != 0) {
        animator.SetInteger ("Behav", 0);
        sec = 0f;
        if (m < 5) {
            m++;
        }
    }else
        Debug.Log ("student done <3");
}
}

i want => if every student has m value m == 5, then game finished. what i've done so far is called StudentScript from GameManage script (public, so i have to set all the instance manually), then check the value of m from every student

public StudentScript stu1, stu2;
void Update () {
    if (stu1.m == 5 && stu2.m == 5) {
        StartCoroutine (ChangeScene());
    }
}
IEnumerator ChangeScene(){
    yield return new WaitForSeconds (10);
    SceneManager.LoadScene(5);
}

is there a simple way to check m value of all student object without using if (stu1.m == 5 && stu2.m == 5) because in every level, the number of student is different so i want to make a dynamic script for all level


Solution

  • I would use a List<> and add all your StudentScript objects to it. Then you could use System.Linq's All method to check all of the elements in the list.

    using System.Linq
    
    //Add all your StudentScript objects to this list
    List<StudentScript> studentScripts = new List<StudentScript>();
    
    if(studentScripts.All(x => x.m == 5))
    {
        StartCoroutine (ChangeScene());
    }
    

    This way you can use StudentScripts.Add() to add the scripts and it can be any size and all elements will still be checked. The x => x.m == 5 part is called a lambda expression (just incase you didn't know). It's not as spooky as it looks.

    If you don't want to use Linq and lambdas then you could just iterate over the list and update a variable. You could replace the if statement with:

    private bool isGameOver()
    {
        bool gameOver = true;
    
        for(int i = 0; i < studentScripts.Count; i++)
        {
            if (studentScripts[i].m != 5) 
            {
                gameOver = false;
                break;
            }
        }
    
      return gameOver;
    }
    
    void Update()
    {
        if (isGameOver()) {
        StartCoroutine (ChangeScene());
        }
    }