The thing about software development is that if you don’t have an exact direction to go in, you’re probably going to spend a lot of time on some feature and then scrap it. That’s what has happened since my last post. Previously, I decided to take the GUI approach for joining servers and channels and abstracting that into walking through virtual doors that do the exact same thing. The result was cool. It worked well and allowed the user to stay in VR throughout the entire experience.
Centralized Player Hub
After showing off my new prototype to a fellow VR enthusiast and 3D environment designer, he mentioned how it’d be cool if instead of the player having to choose a server and channel from the offline setup room, there was only one door from this room which automatically had everybody join the same persistent channel on the same server. That way, at least in the beginning, everybody is congregated together with zero hassle. From this central networked hub, there would be other doors leading to other persistent channels. Eventually I think it’d be really cool for users to be able to upload their own environments to become one of these other channels.
So I guess I should say my previous work wasn’t completely scrapped, as I just tweaked the old implementation to work for the new one. Next on my list was making the offline setup room have something more than a single door leading to the central hub channel. I wanted players to do all of their setup in the setup room (:P), including things like selecting avatars and setting names. The first issue was how the user was going to see their avatar as they changed it. One option would be to have the user have an “out of body experience” that would allow them to move around the avatar and see it from any direction. Another option would be to add mirrors, allowing the user to see what they looked like in real time. I liked this idea a lot. The main issue here was getting a mirror script/shader/material, which I found after searching the inter-webs for a little bit. The wiki gives the shader code for a mirror but I think the newest version of Unity has a built in mirror shader under FX/Mirror Reflection. I went ahead and used the built in shader but still used the wiki’s mirror script. This worked well enough…for if I wanted more than one mirror in the scene I had to create multiple mirror materials (otherwise I get some really weird reflections). There is room for improvement in the future, but I quite pleased with the results.
In Game Console
One of the issues I’ve started to face as a lone developer is that I don’t have enough time to add everything I want to add. Adding features take time and what takes even more time is designing a way for the user to easily use those new features. In a sense there are two main parts to developing a feature for a program like VRChat – first you have to write the code to actually do whatever it is you want to do (ie. change avatars) and then you have to write code that allows the user to access that that feature (ie. button input or in-game menus). For instance, let’s say I’ve implemented a way to switch avatars. All you have to do now is call SwitchAvatar(string avatarName). Great! Except…how do I let the user do this? There is no correct solution, but no matter the design choice you make, it will take time. A lot of time. And not fun time. I dislike GUI coding…a lot. Therefore, I decided that the easiest way for me to pound out some new features is to completely ignore fancy VR user input and just use a good ol’ fashioned in game console!
The idea struck me when I saw a post to the Unity3D subreddit regarding an open-source Quake style in-game console. User mikelovesrobots had built an in-game console for Unity and man is it cool. I downloaded the package, dragged in the folder and bam, after adding a single prefab I now could bring up the GUI console on screen with the click of the ` key. Adding commands to the console is super easy and I knew this would work perfectly with VRChat. Only one, small, itty bitty issue stood in my way….this console was a full-screen GUI, and that wouldn’t work for VR.
The obvious thing to do was look at how Oculus took a normal Unity GUI menu (OVRMainMenu) and transformed it into an in-game menu that looked really good in the Rift. Unfortunately the OVRMainMenu script is one of my least favorites to work with because I feel that there’s a ton of mumbo jumbo I don’t quite understand (also did I mention I really dislike GUI coding?). I dedicated my entire Sunday to figuring out what witchcraft allowed Oculus to do what they did and after a few hours of tinkering, commenting out code, head-to-desk contact and hacking together code chunks, I finally got things working. I actually don’t understand fully why it works but from what I can tell Oculus is manipulating the GUI.matrix and RenderTexture and applying it to the OVRCameraController to get the GUI to render in both eyes. At this point my console works but as much as I hate to say it, one day I will have to revisit this code and clean it up.
In VRC v0.2.0 I used a drop down menu to allow users to pick and choose which avatar they wanted to use. Based on the chosen avatar, I would instantiate an prefab unique to that avatar. That means I have a saved prefab per avatar. Not a good design. Users also could not see what the avatars looked like in v0.2.0…all they had to go on were names. With the Setup Room, users should be able to easily switch between avatars and see how that avatar looks before joining the online world. My new solution to avatar switching is a single prefab with multiple sets of graphics attached to it. Still not the best solution as I have as many avatar graphics on that single prefab as I do avatar choices, but it’s a step in the right direction. This way, when the user is looking the mirror and wants to change avatars, the switch happens instantly because all we’re doing is turning off the old avatar graphics and turning on the new one. There are few other things that must be updated as well that have to do with the avatar rig and the animator, but it wasn’t too difficult or complicated