Join Michael House for an in-depth discussion in this video Creating your own prefab system, part of Advanced Unity 3D Game Programming.
In this video I am going to discuss creating your own Prefab system for increased control over entity data. And allow the end user, the gamer, to be able to create their own entities and mod your game. You might be familiar with prefabs from another course. Unity 4.3 Essential Training with Adam Crespi. Unity prefabs are a very useful tool, allowing us to define complex entities, save them, and then load them as many times as you want, during the execution of the code. While it is very easy and powerful to create new Prefabs in the Editor, it does restrict us to the Editor. This becomes a significant problem if, for example we wanted to allow end users to create their own entities in game.
As modding becomes a more common and popular feature in modern games, it's important to consider how we might enable end user content creation. You can do this with data files that define the state of entities we want to create. This is essentially how Unity creates Prefabs using sterilization. However, the sterilized data generated by Unity Prefabs is not easily accessible to us, or the end user. In order to create our own Prefab system, we're going to need to find our own scripting language. I've created a very simple scripting language here that has a keyword, colon, and data, and in this case, the custom component takes the name of the custom component and the data that will go into the component.
In order to create our own entities, we need to create an object, add components and then set those component values. For this, we've created the Entity Loader. This is the that on start will read each file that ends with .data inside of the directory we defined. It will read all the lines of that data file into an array, get the name of the data file, and then create a new CustomPrefab storing the lines from the data file and the name of the Prefab. This'll also handle adding new entities to the scene by pressing the A or B key.
Let's take a look at the CustomPrefab class. This class will hold the data from the Prefab file as well as the name. When calling instantiate we're going to create a game object, set the name, parse the file and look for keywords. And create components and set data. We're going to use a while loop to parse through our dataLines in the file. I'll explain more on that later. Here, we're skipping any white space and here we're going to check for our keyword tokens. For example, the customcomponent keyword or the Position keyword.
A customcomponent keyword is used when we're defining our own components. And here we would define position as a Unity built in component. Or if we wanted to add other components like mesh, mesh filter, or any colliders, we would add those below here. Let's follow the execution when we come to a customcomponent. When we're reading a customcomponent, we're going to get the componentName. An attempt to add the componentName, using reflection. The componentName here is going to be, AttackInfo, which we have a class of here.
That's going to create as a CustomComponentBase, which is an abstract class. We use an abstract class here, so we don't have to define each class individually. We can just use a base class. And then call this SetData method on that base class which will then in turn call the set data over ridden method in each of our CustomComponents. When setting the data we pass in the dataLines that represent the script file as well as the pointer to where we are in the file. This is because each component sets it's own data.
It's going to read the file and increment the pointer. So here we're going to set our valueX and our valueString, and increment the pointer. It's passed in as a reference so that when we get back to the Custom Prefab, the dataPointer is up to date. And this is the reason we use a while loop instead of a for each, because we're incrementing the dataPointer outside of the control of the Custom Prefab. Let's follow the execution when we hit a position keyword. in this case we are going to read the value after the position. We're going to split that string into components using the String Split method.
Splitting on comma and then creating a new position using those components. You can see here that we have a position of 3-0-1. That's x, y and z. So let's see what this looks like. We hit Play. And now we can either press A or B. And that will create our Test Entities. I can see that we have an attack info component; the value of 55. And this is a string value. And then I'm testing TTA F45352, just as defined in our Script file.
In this video, I've showed you one way you can create your own Prefab system to allow for modification by end users. This system relies on a simple scripting language you define. Using the simple token parser, the system is able to generate some reasonably complex objects. Further extensions to the system will allow for parent-child relationships, more support for built in Unity components, and improved air handling. While this basic system can be very powerful, it's not very user-friendly in it's current state. If you plan on implementing a similar system, consider extensive documentation.
Or create User Interface which writes scripts automatically.
NOTE: This course requires Unity 4.5.5. The newer versions of Unity have done away with the GUI system used in this course, so the interfaces included for many of the scenes will not work with 4.6 and higher. You can download Unity 4.5.5 at http://unity3d.com/get-unity/download/archive.
- Enabling/disabling with scripts
- Translating, rotating, and scaling objects with scripts
- Working with mouse and keyboard input
- Creating custom GUI controls like progress bars
- Loading assets with scripts
- Saving games
- Creating prefabs dynamically
- Making remote procedure calls
- Synchronizing object transforms
- Finding slow code
- Optimizing data access
- Extending the editor