I knew that we needed to write our dialogs outside of Unity, because it would be way to much text, and editing and keeping track of text within Unity is a pain. I knew from previous experience that XML is used a lot in Unity and AAA games but I only had very basic insights on how to use it. I researched on my own for a while and had a few different approaches based on tutorials from the Unity wiki or some other sites.
For the first few tests I was using the Unity XmlSerializer and I noticed that it had quite a few flaws that would make my work more annoying. For once I had to write three scripts just to read the file properly. I also found out that the serializer only goes to a certain depth of tags, which meant that I would have to create a different XML file for each character, so we would end up with quite a few files.
So eventually I decided to ask Markus, my programming professor, for help. I was quite happy to hear that my approach wasn’t absolutely terrible, but he recommended reading the XML file “directly” instead of using unity’s serializer. He gave me an example Unity Project which explained the method very well, so I could quickly implement it. Now I needed only one script to read the file, and I could put all dialogs in one single XML file too! I had already revised the XML file after our decision on the InventoryItem approach so I only had to tweak that a little bit.
I then wrote a prototype Scene for it, using a few buttons and textfields to test whether it was all working as intended.
Finally, this is the core method for reading the XML-file.
Now we only had to implement this in the main project. That’ll be a whole other post though.
Today I started with Skinning a model that Pierre made, the coolguy_prisoner (was there a character like that?). I’m happy I get to apply the skills I learned from Fridi during our Profil² Woche!
After shortly struggling to find the mesh in the file that Pierre provided I got to work. I hadn’t done anything in maya for a few months now but it was surprisingly fast for me to get back into the controls! I quickly created a few joints along the spine and the left arm just to test whether I still knew how to do this at all!
I tried to let Maya do the skin weights for me but apparently I can’t be that lazy…
So I got to painting the skin weights myself. I wasn’t sure where to start, so I had to try around a bit, but eventually I just flooded the first child of the Arm, the Clavicle with all of the weight for the arm and then went from there. I did pretty much the same for the Spine too.
The model had a pretty complicated structure, with a few hollow areas like the jacket on the arm, which resulted in some weird glitches.
I’ll keep in close contact with Pierre (I’m talking to him right now) in order to optimize our workflow! Eventually I managed to get nice weighting, and it actually looked pretty good for the short amount of time!
As a final test for my rig I made a short animation. Thanks for reading 🙂
Our game is a detective game, we want the player to think while playing, and be able to solve the mysteries themselves instead of being presented the solution at the end of the game. We want investigative dialog and freedom of choice in what they want to ask.
How does the dialog work?
Instead of a set of dialog options for every character, we decided that you should be able to talk to every character about anything that might be relevant. So for example you could talk to a character about another character you met, or maybe about where to get alcohol to fill a bottle of booze. We drew some inspiration from Ace Attorney here where, in similar fashion, you can present an item to the court in order to highlight a discrepancy of a witness’s testimony.
In the beginning we thought about how to limit the amount of things you can talk about. In Ace Attorney, you can highlight any part of a witness’s testimony and try to find a mistake in it. However we knew that we couldn’t allow the player to talk about absolutely everything, because that would require us to write ridiculous amounts of dialog!
We were all agreed on an Items Category, which would contain the different physical objects the player may have with them. We also knew that we had to include persons and locations. For a while I also tried to bring in a sort of “abstract” category, which would contain ideas like money or alcohol or power, and phrases like “the don said I would get a free refill”.
However in the end we found out that we could make that much more intuitive by combining items, like “empty booze bottle” + “the Don” + “Barkeep” to tell the character about getting a refill from the barkeep.
So after 2 meetings and lots of discussion about abstracts and physicals and topics, we came up with three final categories of InventoryItems:
Items, physical objects the player has, like an empty booze bottle. Persons, the characters you can talk to, like the Don. Locations, the unique places of the noir world like the bar.
How does the inventory work?
The inventory is closely related to the dialog, so you’ll already have an idea of it, but we still had to find a way to design it visually!
What was important to us was, like the environment, make it feel good in VR. We liked how the interaction with the environment felt, so we wanted to see how we could do that for the inventory too. The solution was to make the inventory behave pretty much the same like the interactable objects in the world. The InventoryItems would spawn when you opened the Inventory, and you could grab them and move them around and -to be implemented- have them float around you in zero gravity. To give the Item/s to an NPC in oder to talk about them, we would need some kind of container to collect them in, and then give the container to the NPC.
For the first draft we came up with a ring around the player that displayed the different items. It looked very sci-fi so we moved on from that soon. As of writing this (June 21st) we are still not 100% set on the visual look of the inventory, as we got some negative feedback from the intermediate presentation, but intend to make it fit the noir style!
On June 3rd Felix Schade and I sat together to get started on the VR controls for our Game. Although it’s not absolutely necessary for our game per se; we wanted to allow the player to interact with most of the items in their environment, because that’s what players will attempt to do when they first enter a VR game. I had thought of different approaches beforehand, but eventually we decided on the simple childing method for loose items. For hinged objects (like doors or levers) we didn’t do any controls, because we don’t plan on having anything of that sort in the game.
The Controls-system went through a long iteration process. We used the standard Unity SteamVR Plugin from the Assetstore and followed this tutorial for starters. However since the endresult from those tutorials still have a few shortcomings, we still had lots of work to do.
This is the resulting GameObject Hierarchy for our CameraRig. As you can see there are two Controllers (left&right) childed to the CameraRig GameObject. The way we wrote the code is that each of the controllers works independently from the other, so you could theoretically play with just one controller.
Each of the Controllers has these Scripts on it: WandController, InputManager, InteractWithWorld and Teleporter (not implemented yet). They also have a child GameObject which has a Spherecollider (trigger) and the GrabSphereCollDetection Script on it. There is also a ModeManager Script attached to the Camera(eye) GameObject which deals with changing between the noir and the real-world look. All Grabbable items must have the InteractableObj Script, and the “Interactable” tag on them, as well as a rigidbody and a collider.
So how do you grab something?
The position of the controllers are tracked by the Plugin, we didn’t have to write that ourselves. So; you move the controllers to the item in virtual space. The Spheretrigger enters the collider of the interactable object, and the object is saved for this sphere (controller).
Now you press the GripButton. The GripButton is the button labled as 8 in this image. There is a GripButton on both sides of the controller, but they behave as one Button.
The WandController Script checks for that Input (and others) in the Update function, and then makes it available to other Scripts as public bool variables.
Now the InteractWithWorld Script takes action. This script is the main script dealing with grabbing objects.
In the Update function it checks for Input on the GripButton. If the GripButton is pressed, and there is an item in the grabsphere, and the controller is not already holding an object, the object will be grabbed. Also, if the object is already held by the other controller, the other controller will lose connection with the object (DeleteFromHand). The following steps are necessary to grab the object: the rigidbody is set to a velocity of zero and it stops using gravity. Additionally the object is parented to the grabSphere, which is parented to the controller, so now the object directly follows the position and rotation of the controller.
If the GripButton is released while holding an Object, or if the Object leaves the collider of the sphere (outOfSphere), the Object shall be dropped.
When the Object is dropped, it’s parent will be reset to its initial value (just null at the moment), gravity will be enabled again, and all references of the object will be removed from the wand controller (DeleteStuffFromHand). However before the references are deleted, the object will take on the velocity/angular velocity of the wandcontroller, so you can actually throw objects. After trying several of our own approaches on throwing, and none of them working as intended, we eventually found this method from thestonefox and used that. Now you can pick up an Object, move it around, and throw it away. We also made it so that objects cannot go through other objects, so when you move your hands through a virtual wall, the object will get stuck on it, and eventually fall from your hands. Furthermore we made it so that when you switch between real-world and noir mode, you drop those objects in your hands that do not exist in the other mode.