Find other script on same GameObject without knowing it's name

Hi,

I’m programming in C# and have made a series of objects which each have two scripts:

  • The first script contains the majority of the functionality, and is applied generically to each object (as each has the same basic operations)
  • The second script contains the specific details that the object needs to run (vital stats, name, etc…), each of which is unique for each GameObject

I need the first script to be able to gather information from the second so that it can operate based on the unique stats of that object.

I can think of two methods to do this:

  1. I can have the second script send the stats during Start() using SendMessage(), attaching a custom class object into it and having the other read the stats and use them.
  2. Set up a variable in the first script that allows it to access the variables and functions of the second script, then have it pull what it needs, when it needs it.

The problems, however, are multiple:

  1. The first technique requires me to fool around with rolling out my own class and requires a bunch of code duplication (and I hate the problems that come with that - not the least of which is brittle code)
  2. The second technique doesn’t seem to work, as the variable to store the second (stats) script needs to be named specifically in line with the script name, which prevents me from having the script dynamically find it.

I’ve tried to resolve the problem I had with the second method by leaving a blank script variable for me to assign in the inspector (not the best solution, but it’d work), however, it doesn’t like that at all.

Any recommendations on tackling this problem? (I really would like the script to be found dynamically as required)

Cheers

Class inheritance, absolutely.

Your second script should be a subclass.

class Script extends MonoBehaviour {
  function EveryoneDoesThis() { }
  function AndThis() { }
}

class ButterScript extends Script {
  // 'is a' Script so it has the default EveryoneDoesThis function
  // and it overwrites the AndThis function:
  function AndThis() { AddButter(); }
}

If I correctly understood the problem, it would be better to place all the info in public variables in the first script, and set the specific info in each prefab instance in the Inspector - you would not even need the second script. The first script could be something like this:

using UnityEngine;
using System.Collections;

public class EnemyScript : MonoBehaviour {
    public string enemyName;
    public float maxHealth;
    public float speed;

    // enemy code
}

Just select the prefab and modify these variables in the Inspector - this will be recorded in the prefab, defining its specific info.

But if you really need to place the info in specific scripts, derive them from a common class - you could use GetComponent to grab the second script by its ancestor name. The common class could be like this:

using UnityEngine;
using System.Collections;

public class EnemyInfo : MonoBehaviour { // common class is EnemyInfo
    public string enemyName;
    public float maxHealth;
}

Ogre script:

using UnityEngine;
using System.Collections;

public class OgreInfo : EnemyInfo { // OgreInfo derived from EnemyInfo
    void Awake(){
        enemyName = "Ogre";
        maxHealth = 150;
    }
}

Ghost script:

using UnityEngine;
using System.Collections;

public class GhostInfo : EnemyInfo {
    void Awake(){
        enemyName = "Ghost";
        maxHealth = 100;
    }
}

Then get the second script as EnemyInfo in the first script and read/modify the variables:

EnemyInfo enemyInfo;

void Start(){
    myInfo = GetComponent<EnemyInfo>();
}

void AddHealth(float health){ // use the variables as myInfo.variableName
    curHealth += health;
    if (curHealth > myInfo.maxHealth) curHealth = myInfo.maxHealth;
}