Camera Shy: Picking Up Speed
Production is almost in full swing now! The team is almost done with our planning, documents, and approval for going through Greenlight. Our next steps are to finish up our remaining documentation and present to our professor before getting approval for our production plan. So far, I think our documentation and our plans are good; nothing is too far out of scope and it doesn’t seem like any discipline is getting less work. My only remaining concern at this point in the process is timelines.
We, as a team, are expected to hit certain milestones at allocated time frames. These milestones include Alpha, Beta, and Release. Currently, the Beta point is creating concern. Beta, for our team, entails every mechanic and system being complete and in the game. From the point we’re at, completing Beta would mean ensuring iteration to make things feel the best that they can along with completing bug fixes to make sure that nothing is broken or is going to break.
As I mentioned, milestones are to be completed at specific times in the semester. This milestone is consequently coming up quickly. We are currently in week 4 of production and Beta is due week 10, leaving us with roughly 6 weeks to get every piece of programming into the game before we become locked out of new things. We have an estimate on what programmers will be spending these next few weeks on. However, due to our recent exposure to these situations, our estimates are often under in time due to our need to elongate the process of finding solutions. This misjudgment is currently something we are talking about as we plan for the upcoming milestone. Our awareness that this has happened in the past weighs into our predictions for the time we’ll spend on contingencies and priorities. As a team, we’ve acknowledged that we have to make sure the important things get through, however we’ve additionally begun to move forward knowing that a shift in time spent on these items is always a real possibility; we can’t always predict everything.
Outside of focusing on the milestone timeline, we’re committing to completing day by day tasks. Together, we are still trying to fix our object detection on our camera. Simultaneously, we have our independent tasks. I’ve been tasked with continuing my work on tools so that we can hit production running. Our other programmer is working on larger systems such as saving and loading. The tools I’ve finished so far are the Art Pipeline Tool and the VR Editing Tool.
Art Pipeline Tool
The Art Pipeline Tool stemmed from a problem the lead artist had last semester. She found that there were a lot of props that were being imported into the Unity project and took a lot of time to import them individually. To import them, she would need to export each model individually, put the FBX into the Unity project, then either a programmer or designer would create a prefab in Unity before adding the necessary MonoBehaviours to the object. This took up a lot of time not only for the artist but those putting the level together. The solution is to just do it all automatically; hence the Art Pipeline Tool. It takes a model FBX file in Unity, creates a prefab variant of it, and adds whatever scripts are needed to it at once while offering an option to pack an FBX and import props. This solution makes it so that an artist doesn’t need to import each prop individually.
In the process of creating the Art Pipeline Tool, I had two big problems getting the tool to work: an expandable way to put MonoBehaviours on a prefab, and working with packed FBX files. I knew I wanted to have a ScriptableObject store the data (they work in editor and are extremely customizable) but wasn’t sure how to store a Type. With a bit of research, I found that there was a function available that I could utilize where it was possible to put a type name in order to get it to spit an actual Type out: Type.GetType(string). This function alleviated the initial difficulty, however it didn’t work with just a type name when in a different assembly; GetType(“Rigidbody”) would not return the Rigidbody type. It took a bit of research to find a solution to this, but I found that you could include the assembly information and it would then give the requested type. This means to get a Rigidbody type I would have to use “UnityEngine.Rigidbody, UnityEngine.PhysicsModule” which can be found by using typeof in a debugger. C# has some really cool stuff while also having some interesting behaviour.
An additional problem I had with the Art Pipeline Tool was with packed FBX. FBX files store a LOT of information in them such as animation data, rigs, models, meshes, and materials to name a few among an endless list of additional information items. This allows someone to export multiple objects at once, and when imported into Unity it will be an Object with models as the children. However, Unity doesn’t allow you to instantiate just a child of an FBX (or any prefab) so I couldn’t make a prefab variant of these specific children. I needed those children to be seperate so they could be put in a scene separately from every other object and have scripts added to them. Ultimately I ended up just instantiating the prefab, making a copy of it as a GameObject, then saving that GameObject as a prefab. This is less than ideal due to changes to the art asset won’t be reflected immediately but this is the only way I found possible to get this to work. Ultimately this tool was pretty painless and came together relatively quickly, it’s expandable so if something else comes up I can quickly add it in and really help artists.
VR Editor Tool
The other tool I did was the VR Editor Tool. Our Level Designer wanted to not work in Unity’s editor while designing and building out a level meant for VR. The solution was to then allow her to edit in VR. However, a problem was that we can’t do anything with VR in Unity unless the game was running. This meant that any changes completed could not be saved. However, ScriptableObjects allow us to completely get around that problem due to the fact that they’re meant to be an intermediary between Editor and Runtime. With a ScriptableObject, I can hold Transform References until I leave Runtime and then take all of the data (position, rotation, local scale, etc.) and save that to my own struct with a reference to what object it is. Once out of Runtime and in Editor, I can then load all this data back into the objects that it came from while marking them as dirty for the scene to allow saving the changes. From here, I came across two problems: Unity doesn’t have a persistent unique identification system and we are using multiscene loading so the object might not be loaded in Editor. I knew of the second problem but didn’t expect the first problem. I was able to identify it while I was looking into a bug that I initially believed to be a callback being called too early but was actually that InstanceIDs in Unity are not persistent.
The solutions to these two problems weren’t very elaborate or difficult but the process was long. It took me a bit to double check InstanceIDs that I was using to find objects and find out that they weren’t persistent. Once I found that out it didn’t take me much time to create a way to generate unique identifiers and keep track of them. The multiscene loading problem I found out there are a ton of Editor callbacks in Unity, namely sceneOpened which calls when a scene is loaded in editor. This allowed me to hook up a function call to load the data from the ScriptableObject and with the new ID system it functioned well and I didn’t have any problems with it.
All in all, these last two weeks have been pretty calm and hectic at the same time. There has been a lot going on with planning and making sure we all are in the loop and aren’t siloing between disciplines. At the same time, I’ve learned a lot about what is capable in the Unity Editor, which still surprises me how much can be done.