- Home /
How do I script a prefab like I would code a class?
I have actually developed the core pieces of a game in C++ before I discovered Unity in my search for platform independence. In C++, I could create, say a "robot" class, and give it public members like "sensors", which would be a struct. This sensors struct would have variables for the x and y location of the sensor (used for rendering in OpenGL), sensor type and so on. To access or manipulate properties of the sensor, all I would have to do is create a robot (call it, "myrobot") and say myrobot.sensors[i].type and I could assign or compare values to myrobot's "i-th" sensor's type.
As far as I understand, prefabs are more or less like creating classes like the robot class I had. For example, I created a cubed robot composed of smaller cubes that are grouped together as a prefab, or in a prefab, whichever is the correct way of saying that. Furthermore, I named these smaller cubes, some of them have names like Sensor0, for example. I would like to be able, in a java script, reference Sensor0 of one of my robot prefabs, and assign attributes to, or query attributes of it. Is it possible in some way to treat a prefab the way I treated my C++ robot class? If so, how?
Thank you in advance for any help with this.
Answer by cagezero · Dec 19, 2012 at 09:59 PM
Yes. What you are wanting to do is totally possible. However, your design will need to change slightly to work in Unity. First off, your understanding of a Prefab is close but not quite there. See this post for a little clarification. Basically a Prefab is not a Class but a collection of one or more GameObjects.
As for accessing individual sensors of your robot, I would suggest creating a Sensor MonoBehaviour and attach it as a Component to any GameObjects in your Robot Prefab hierarchy that you would like to behave as a Sensor. There are probably endless ways of storing references to these Sensors in code, but I will give an example of a way I have done it in the past (sorry for the C# but hopefully it will still give you the right idea).
public class Robot : MonoBehaviour {
Sensor[] sensors;
void Awake() {
//Get all the Sensor Components in the children of the robot prefab root
sensors = GetComponentsInChildren<Sensor>();
//Use Linq to order those sensors by name, assuming they are named Sensor0, Sensor1, etc...
var orderedSensors = from sensor in sensors
orderby sensor.name.Length, sensor.name
select sensor;
//Store the ordered sensor array for later use
sensors = orderedSensors.ToArray();
}
}
cagezero, thank you for your help. I think I can read between the lines, but thought I might ask for some clarification on one point at the moment. In your example code, you have a definition for a class called Robot, which has an array of type Sensor as a member. I am assu$$anonymous$$g there should be a Sensor class somewhere else, also defined as a $$anonymous$$onoBehaviour? In which case, the Sensor class would a) control everything relevant to Sensors and b) be attached to the GameObjects I would like to act as sensors. Likewise, the script that would contain this Robot class you started to define, would cover Robot specific functions and be attached to the Robot prefab (or to instances within the scene, I'm not sure which).
I am also not sure what "Awake" is supposed to do, but assu$$anonymous$$g it's a library thing like "Update", I'll see if I can look that one up.
Yes. You will need to have a Sensor class that extends $$anonymous$$onoBehaviour. Your points a and b are also correct. Theoretically the root of the the Robot prefab hierarchy would have the Robot Class attached as a component and your Sensor Components would be attached where ever you want them (probably to child GameObjects of the Robot prefab).
Awake is called when your Robot instance is being loaded in the scene.
If this answer has helped you please consider marking it as correct :)
Sorry. I have marked the answer as correct. I had been leaving it only because I am still working out the details of implementation. It is odd to write classes that use other classes without "including" them. Not to mention, I am still working on how to use the name I gave a Game Object in the Hierarchy in a (java) script. This is an issue at two levels: referencing prefab instances such as (for the sake of argument) "Robot1" and "Robot2", and referencing Sensor0 through SensorN, which belong to Robot1 or Robot2.
No worries. I am just glad the answer is useful to you!
I am not sure how to sort game objects with your specified na$$anonymous$$g convention in js. You might consider opening another question regarding that. However, I do use that sort of functionality sometimes, and the C# code I posted works like a charm. Have you considered creating a C# script that performs only the sorting? You could then use this from any of your js scripts to sort your arrays.