Adding properties to prefabs

How can I add properties to a prefab that I can set at run-time?

Can I simply attach a script to prefab and then access that scripts properties as if they were the prefabs own properties?

e.g. Can I attach this script to a prefab:

public class Tile{
	public int tileX = 0;
	public int tileY = 0;
}

And then create a new prefab like this and access its properties (also, can I cast the GameObject type to Tile like this)?

Tile tile = (Tile)MonoBehaviour.Instantiate(Resources.Load("Tile"), new Vector3(x,0.05f,z), Quaternion.identity);
tile.tileX = 1;
tile.tileY = 2;

What is best practice here?

1 Like

This is how I solved it, but is it the best way?

Create your properties etc in a class (mine is called TileProps) and attach it to your prefab:

using UnityEngine;
using System.Collections;

public class TileProps : MonoBehaviour {
	public int tileX = 0;
	public int tileZ = 0;
	
	public float posX = 0.0f;
	public float posZ = 0.0f;
}

Then you can access the properties in code like this:

// 'tile' is the object
tileProps = (TileProps)tile.GetComponent( "TileProps" );
tileProps.posX = 3.0f; // etc
1 Like

If I understand, you are asking whether it is possible to access properties of a prefab ? Well, it seems to be possible.

Prefab “Sleeping” with component SleepingScript

var hiddenContent : String = "It works.";

Prefab “Working” with component WorkingScript

var hiddenObject : GameObject;

function Start () {
	var content : String = hiddenObject.GetComponent (SleepingScript).hiddenContent;
	print (content);
	content = "None now.";
	print (content);
	
}

Only Working prefab is present in scene, and its content variable is the prefab Sleeping.

Console output :

Thanks Akilae - Yes, I had already figured out the GetComponent method as I detailed in the post above :slight_smile:

However, I wondered if this was the best way?

1 Like

Well, if you don’t want to use GetComponent (ScriptName), you may do a variable theScriptName : ScriptName, drag and drop the component ScriptName of the prefab into the variable theScriptName field.

yes, I understand it can be done that way, but that is at build-time, not run-time.

I don’t have anything against using ‘GetComponent’, I just wondered if it was the best way (with the least overheads) at run-time?

If you call it once, no problem.

Avoid using it in Update or functions called like, try using it at Start, Awake (these one time functions).

For example, instead of :

function Update () {
	print (GetComponent (ComponentName).myString);
}

Do :

var componentName : ComponentName;

function Awake () {
	componentName = GetComponent (ComponentName);
}

function Update () {
	print (componentName.myString);
}

It is longer but less consuming (I tried it to speed up a small OnGUI, I felt the pain and the relief…)

Good tip! I just left a similar tip for someone else, but didn’t think to apply it to my own example…

In response to the actual question: yes, this is the normal way of adding data to prefabs (or game objects in general).

You could improve on this using properties:

public class Player
{
    // Define a private variable
    private int experience;

    // Define a public property with getter and/or setter
    public int Experience
    {
        get
        {
            return experience;
        }
        set
        {
            experience = value;
        }
    }
}

The benefit of this is that it is encapsulated, and also gives you the power to make it read/write only by omitting either get or set.

You could also add more code to either function, if you wanted to modify the value in some way.

There is also a shorthand for this:

    public int Health{ get; set;}
}

The person you’re replying to hasn’t logged into the forum since 2011.

Right… but the thread is still helping people today. Maybe now it will be even more helpful.

3 Likes