Search Unity

  1. Unity 2019.2 is now released.
    Dismiss Notice

Changing values in multiple scripts as best as possible

Discussion in 'Scripting' started by Azux, Sep 11, 2019.

  1. Azux

    Azux

    Joined:
    Mar 3, 2015
    Posts:
    17
    Hello i'd like to know how can i change values in different scripts. For example i have warrior script and priest script both of those have bool isActive value. Now from other script i want to take those 2 and change bool to false;

    Take into account that i mean many object at once and many different scripts so if it is possible to do in some king of list and loop or something like that it would be great.
     
  2. WarmedxMints

    WarmedxMints

    Joined:
    Feb 6, 2017
    Posts:
    739
    If the scripts don't all derive from the same base class then I would use an event and have each class listen to said event.
     
  3. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    6,837
    It sounds like you want to learn to use polymorphism and inheritance (which, if you need information beyond my answer here, is what you will want to google). Basically, you have objects of multiple types, but they all have something in common. As of now, the compiler doesn't have any way to know that the "isActive" variable on each of these represents the same thing; polymorphism is how you tell the compiler that.

    What you need to do is create a base class that all objects with "isActive" can inherit from. This can contain shared functionality, variables, and function definitions that can be inherited and overridden, but for now, let's just make it have the "isActive" variable and nothing more. I'll call this base class GameCharacter.
    Code (csharp):
    1. public class GameCharacter : MonoBehavior {
    2. public bool isActive = true;
    3. }
    Now, your code for, say, the warrior, might look like this right now:
    Code (csharp):
    1. public class Warrior : MonoBehaviour {
    2. public bool isActive = true;
    3.  
    4. void Update() {
    5. if (isActive) Debug.Log("We're active!");
    6. }
    7. }
    We're going to change it to look like this (note the end of the first line, that's the key):
    Code (csharp):
    1. public class Warrior : GameCharacter {
    2. // we don't need to define isActive here, as we have inherited it from GameCharacter
    3. void Update() {
    4. if (isActive) Debug.Log("We're active!");
    5. }
    6. }
    You can do the same thing for your priest, your bard, your wizard, your whatever else scripts. Now, somewhere else, you can do something like this:
    Code (csharp):
    1. GameCharacter[] allCharacters = FindObjectsOfType<GameCharacter>();
    2. for (int c=0;c<allCharacters.Length;c++) {
    3. allCharacters[c].isActive = false;
    4. }
    And hopefully that's enough to get you where you need to go.

    You can have multiple levels of inheritance too. (In fact, you already do: by default you inherit from MonoBehaviour, which is where you get most of your Unity functionality in your scripts.) If you want, say, doors to also have this isActive property, you could make a "GameEntity" class where you put isActive (and Door inherits from that), then GameCharacter inherits from GameEntity, and your character classes inherit from GameCharacter. Inheritance is one of the most powerful features of modern programming languages!
     
    Azux likes this.
  4. Dameon_

    Dameon_

    Joined:
    Apr 11, 2014
    Posts:
    533
    At that point, rather than more levels of inheritance, it's better to use an Interface. Inheritance is a powerful feature, but you have to be careful not to grow your levels of inheritance every time you want something new, and keep some separation. Too much inheritance is actually a bad thing and can introduce unnecessary complexity.
     
  5. Joe-Censored

    Joe-Censored

    Joined:
    Mar 26, 2013
    Posts:
    6,743
    If you're not going to use inheritance, and these are intended to be separate scripts, you could have a master script with a single method for turning these on/off. Then you'd just loop through all these objects and call that single method on the master script. I do this kind of thing when I have a bunch of scripts on a GameObject but some action requires many sub-actions (is that a word?) across several scripts.
     
  6. Azux

    Azux

    Joined:
    Mar 3, 2015
    Posts:
    17
    What i did before i read Your answers was that i made another script (activeChecker)with value isActive. For my Champion script I added RequireComponent(typeof(activeChecker)) which I add to every champion in game so now from the script if want to change that value I take GameObject of champion from list and i GetComponent<activeChecker>() so i change it there and in my main champion script in Update() isActive = activeChecker.isAvtive; Propably it is not the most efficient way but sounds pretty much like @StarManta answer. On another project i will check Your way i think the difference is that now i have two MonoBehaviour Scripts on my champion. Thank You all for help.