Attaching values to runtime objects

What is the accepted best-practice method for assigning values to a runtime created object? I want to create many of these from a prefab, each of which will have unique values.

If I do this via public variables in a script attached to the pre-fab, how do I reference these during runtime.

If you provide code example, please use C#.

While equalsequals' answer works, the question is specifically asking about "Best Practice", so I'll add this to go a bit further in explaining a couple of techniques to streamline the code and remove redundancy.

First, to remove some of the redundant casting you mentioned, (in c# only, not Unity's Javascript) you can use the 'generic' version of GetComponent. Instead of:

ClassName thisThing = (ClassName) obj.GetComponent(typeof(ClassName));

You can do this:

ClassName thisThing = obj.GetComponent<ClassName>();

(the angle-brackets here are actually part of the syntax, and should be included in your code)

Much nicer. However your code can be better still!

Most often, when you're instantiating an instance of a prefab at runtime, you are generally interested in either its Transform, or a script of your own attached to that prefab. In many cases, a reference to the GameObject serves only as a 'middle-man' which you use to get to some other component, and is therefore a bit redundant.

When this is the case, a good technique is to instantiate your object using a reference to the actual component that you're interested in, rather than a reference to the root gameobject of the prefab.

For example, if you have a prefab called "Projectile Prefab", with a script attached called "Projectile", you might at first - quite reasonably - think of instatiating it and setting values like this, using a reference to the root GameObject of the prefab:

public GameObject projectilePrefab; // drag reference to prefab in here

void FireProjectile () {

    // instantiate a projectile:
    GameObject projectileObj = (GameObject) Instatiate( projectilePrefab, pos, rot );

    // get reference to Projectile script instance:
    Projectile projectile = projectileObj.GetComponent<Projectile>();

    // set value on projectile script instance:
    projectile.damageAmount = 10;

}

This works, but it's quite verbose when all we really want is the 'projectile' script reference at the end.

We can clean this up because of a neat feature of the "Instantiate" function - it's possible instead to make your initial prefab based on a reference to that particular component on the prefab.

This means your initial 'projectilePrefab' variable (which you drag your prefab on to, to create the reference) will actually be a reference to the script on the prefab, rather than the prefab root gameobject. This doesn't mean that only the script will be instantiated - the entire prefab to which the script is attached will still be constructed. All that changes is that the "Instantiate" function gives you back a direct reference to the script instance, rather than to the GameObject!.

For example:

(remember, the name of the script attached to the projectile prefab is called “Projectile”):

public Projectile projectilePrefab; // drag reference to prefab in here

void FireProjectile () {

    // instantiate an projectile (now returns reference to script instance!):
    Projectile projectile = (Projectile) Instatiate( projectilePrefab, pos, rot );

    // set value on projectile script instance:
    projectile.damageAmount = 10;

}

In my opinion, this is 'Best Practice' when instantiating prefabs and setting values on those runtime-created instances.

static public T InstantiateAndGetBehaviour< T >( GameObject prefab ) where T: Behaviour
{
    GameObject go = ( GameObject )Object.Instantiate( prefab );
    return go.GetComponent< T >();
}

One thing we did in our game is used generics to make getting a specific script on a game object prefab a little simpler. The usage is pretty simple.

MyClass myClass = InstantiateAndGetBehaviour< MyClass >( prefab );

If you instantiate something, you have reference to the GameObject which was just instantiated.

From there you can use

<ClassName> myComponent = (<ClassName>) instantiatedGameObject.GetComponent(typeof(<ClassName>));

to retrieve any component attached to said GameObject.

Once you have reference to the component you can access any of the public properties simply by saying:

myComponent.myPublicPropery = value;

Hope that helps.

==