Unity
My mashup of Unity experiments (Hydra/Oculus Rift/Spatial Graffiti)
by Dave Buchhofer on Apr.17, 2013, under Interactive, Oculus, Unity, Unity3D
AKA: Things I play with instead of sleeping, after my son goes to bed.
EDIT: hey there people coming from Bruces video! check out the newer version for a nicer demo: cheers!
Architecture – an interactive basketball arena 3d scene to wander around. Loosely based off of a project that we didn’t get paid for, so, mileage ++!
Hydra – for movement, and glory!
Line work – Spatial Graffiti, draw lines in 3d space with the hydra, It’s more fun than you’d think.
Basketball – kinda. It wasn’t too exciting, so it’s more or less removed by now.
How it works:
- Rift, head tracking turns the player’s viewpoint, it just works? Thanks oculus!
- Hydra, unity integration is nice, thanks!
- Base unit:
- Leave yourself enough room between the unit and the monitors! NO MONITOR PUNCHING ON MY WATCH!
- I’ve found it works best if you have the controllers ‘docked’ at game start. It just saves some configuration hassle.
- Pick up the controllers from the base station, move them to a comfortable position closer to your body, about as far away from each other as they appear in the rift view, and click the ‘Start’ buttons (The vertical button between the 1 and the 2 buttons) to take control of the hands.
- Base unit:
[TL,DR]
- Right Hand:
- Thumb stick turns the player body.
- Button 1: Points the finger, begins drawing a line in 3d space.
- While button 1 is down, how much the trigger is depressed controls the width of the line, up to a point.
- button 4 will launch a basketball, holding the button adds power per frame, letting go fires it off.. I know I know, throwing motions.. soon.
- Left Hand:
- Thumb stick moves the players body
- Button 2: Points the finger, Inserts a ‘move’ helper near the hand
- While button 2 is down, hold the trigger down to ‘MOVE’ the player body in 3d space. The movement isn’t 1:1, so go gentle to start.. but everyone I’ve tried it on has been moving this thing almost as fast as you can move your arm within 30 seconds, with minimal icky stomach feels.
- The icky stomach feels is one of the main things I would like some feedback on, so I can pursue or steer differently.
[/TL,DR]
The main OVR menu scripts are in there, so if you manage to say, jump off of the world ‘by accident’ and look up at the things receding, you can hit the Right Shift key, and then Return to reset the scene.
Things I’m working on and experimenting with still
- UI stereoficiation, NGUI draws well, but need something better than shooting a ray out for interaction. So far I don’t like the feel of the sixsense UI bits. working on some things here.
- Networking. Multiple people in a small space drawing stuff, So far it works on lan, but who really has 2 rifts/hydras they can put in a room? I’ll figure it out!
- Fly mode for the hydra, throttle style movement, basics started, but needs some tweaking before it’ll not make people feel strange.
- 1:1 rotations, started, but I wanted some feedback on other stuff first!
- Holding both bumpers will allow you to scale the player height/viewpoint up based on how close/far the ‘hands’ are from each other. nearly works, just a little too fall-thru-the-floory for my tastes to leave it enabled in this version.
I do architectural interactive/animation/work for a paycheck (haha, I know right!), so I spend a lot of time working with the fundamental problem of how to get non-game people empowered to get around in 3d space. I love toying with 3d spatial navigation systems, so being able to immerse in space with the Rift and prototype with the responsiveness of the hydra has been a lot of fun for me this week. There’s a lot more to play with here!
Most of my position/rotation stuff is made for placing items in the world, but the hydra tuscany demo covers a decent portion of the basics of that idea already. Besides, it was fun to mess with the player positions/orients, so that’s what I’m playing with so far.
So, if by chance you made it this far into my ramblings, here is the link to download the test app and give it a go!: 2013-04-18-BuckHydraLines.zip
Fun with Generics and Lists in C#
by Dave Buchhofer on May.19, 2011, under .net, csharp, Scripting, Unity
So I’ve been doing a lot of List juggling lately and have run into a few tidbits that I wish I had learned a few months ago. I figure that is always a good cue to write them down for future reference and for any others who are digging into this C# world headfirst also. this is all sort of an exansion to try and get a concrete example of mike_mac’s lamda/delegates/callback articles
Say I have a custom class that I’m using to store a structured set of data, this time we’ll play with “ArmDefs”. ArmDef’s just hold a little string and int based data and a list of ArmDef’s as children, and a second list of GameObjects that contains all of the models for this section of arm for use to serialize to disk, but thats more a story for another time.
Overall this is used to build up a hierarchy that holds the “contents” of a runtime modular rig, and handles the Saving/Loading/Reloading.
To work with this I needed to set up a pile of recursive functions to edit the tree at runtime, since I don’t know the depth of the hierarchy, and rebuild the system as needed.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | [System.Serializable] //Inheriting from ISerializable gives us //an easy access to Serialization to disk public class ArmDef : ISerializable { public string Name; public List<ArmDef> Children = new List<ArmDef>(); public ArmDef(string iFile) { this.Name= iFile; this.Children = new List<ArmDef>(); } public void AddChild(ArmDef child) { Children.Add(child); //just wrapping the Add so that we can do "extra" //stuff here if we want, like add links to parents etc } } |
not really building these thru scripts out in the wild but just to build something to work with here.
1 2 3 4 5 6 7 8 9 10 | public ArmDef config = new ArmDef("Base Level"); //add a couple children config.AddChild(new ArmDef("Level2a")); config.AddChild(new ArmDef("Level2b")); config.AddChild(new ArmDef("Level2c")); //add a couple grandchildren config.Children[1].AddChild(new ArmDef("Level3a")); config.Children[1].AddChild(new ArmDef("Level3b")); |
ok thats all the boring stuff for now! here is a Generic Recursive function that walks down a tree and does ‘Action<>‘ to all children of ‘parent’. The key here is that the Action<> pretty much rocks. !
1 2 3 4 5 6 7 8 9 10 11 | public void HandleArmDef(Action<ArmDef> item, ArmDef parent) { if (parent.Children.Count > 0) { foreach (ArmDeft in parent.Children) { HandleArmDef(item, ti); } } item(parent); } |
Now the fun begins when you start to chain this stuff together to “act” on all children.
we can define that “Action
This will go through the hierarchy and remove all children with the Name of “Level3a”.
1 2 | string toDelete = "Level3a"; HandleArmDef(item => { item.Children = item.Children.Where(child => child.Name != toDelete).ToList(); }, config); |
In another example, i wanted to search the hierarchy and see if there was a certain value anywhere in the hierarchy. easiest way i found was to just quickly build a flattened list and use the Linq “Any” function to see if the string was found anywhere in the hierarchy.
1 2 3 | List<string> flatList = new List<string>(); HandleArmDef(item => { flatList.Add(item.Name ); }, parent); bool isCurrentlyFlat = flatList.Any(x => x.Contains("Flat")); |
in another case, i wanted to insert a new child into the hierarchy as a child of a specific object.
1 2 3 4 5 6 7 8 9 10 11 12 13 | void AddChildAddon(ArmDef parent, string addAsChildOf, string newChild) { //for each object 'item' down the hierarchy //if the item.Name contains our addAsChildOf string //we'll add the newChild as a child to the item. HandleArmDef(item => { if (item.Name.Contains(addAsChildOf)) { item.Children.Add(new ArmDef(newChild)); } }, parent); } |
there’s plenty more possibilities of things to do here if I’ve explained well enough!
More info on Linq by example
Unity: Toying with Scriptable objects and Custom Editors
by Dave Buchhofer on May.18, 2011, under .net, csharp, Scripting, Unity
Expanding on the previous post about Scriptable Objects as an easy way to save/edit some data at runtime, here’s a small extension looking at an example for a simple custom editor that appears when you select the Scriptable Object we built previously in the Project view.
Here’s what you get clicking on the file previously:

And the result with the custom editor:

Now, this isn’t the sexiest of examples, but hopefully it helps someone along the way!
First a small addition to the data class, lets add a constructor to it, since our input values are going to be basically the same every time (Mimic ‘this’ camera), we’ll add a secondary constructor for the class that just takes a unity Camera as input and records the values for us.
We’ll use the same ‘CameraLocationHolder.cs’ from below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | //File: CameraLocation.cs using UnityEngine; using System.Collections; //the Serializable attribute is key to what makes the custom class visible in the editor ! [System.Serializable] public class CameraLocation { public string name; public bool isOrtho; public float orthoSize; public float fov; public Vector3 position; public Quaternion rotation; //base constructor that builds an empty CamLoc public CameraLocation() { name = string.Empty; isOrtho = false; orthoSize = -1; fov = -1; position = Vector3.zero; rotation = Quaternion.identity; } //build a CamLoc from a supplied camera public CameraLocation(Camera c) { if (c) { name = "New Camera"; isOrtho = c.isOrthoGraphic; orthoSize = c.orthographicSize; fov = c.fov; position = c.transform.position; rotation = c.transform.rotation; } } } |
And we replace the ‘CameraListboxWizard’ that we previously used to edit the Scriptable Object with this (very similar) ‘Custom Editor’
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 | //File: CameraLocationEditor.cs -- Place in an Editor directory under the unity project using UnityEngine; using UnityEditor; //this limits the editor to running on object that have type CameraLocationHolder [CustomEditor(typeof(CameraLocationHolder))] public class CameraLocationEditor : Editor { //This will just be a shortcut to the target, ex: the object you clicked on. private CameraLocationHolder db; void Awake() { db=(CameraLocationHolder)target; } public override void OnInspectorGUI() { GUILayout.BeginVertical(); if (GUILayout.Button("Add current Camera.main position", GUILayout.Height(50))) { Camera m = Camera.main; if(m) { //Add the new camera to the list db.content.Add(new CameraLocation(m)); //tell the unity editor that the list has changed and needs to be serialized EditorUtility.SetDirty(target); } } GUILayout.Space(5); DisplayCurrentCamList(); GUILayout.Space(5); GUILayout.EndVertical(); } void DisplayCurrentCamList() { if (db.content.Count == 0) return; //For each of the cameralocations in the saved scriptable object db for (int i = 0; i < db.content.Count; i++ ) { EditorGUILayout.BeginHorizontal(); //A text field to rename the camera db.content[i].name = GUILayout.TextField(db.content[i].name, GUILayout.Width(200)); //a few simple buttons to juggle the array order if (GUILayout.Button("UP")) { if (i > 0) { CameraLocation item = db.content[i]; db.content.RemoveAt(i); db.content.Insert(i - 1, item); } } if (GUILayout.Button("DN")) { if (i < db.content.Count) { CameraLocation item = db.content[i]; db.content.RemoveAt(i); db.content.Insert(i + 1, item); } } if (GUILayout.Button("Remove")) { db.content.Remove(db.content[i]); } //sets the maincamera to be at the selected cameralocation if (GUILayout.Button("MoveTo")) { MoveToView(db.content[i]); } //updates the cameralocation to match up with the Camera.main (Usable at runtime or at edit time) if (GUILayout.Button("UPDATE")) { UpdateView(db.content[i]); } EditorUtility.SetDirty(target); EditorGUILayout.EndHorizontal(); } } void MoveToView(CameraLocation cam) { Camera MainCamera = Camera.mainCamera; Quaternion currentRotation = cam.rotation; //if we had an ortho cam, lets just set it there before we start moving. MainCamera.orthographicSize = cam.orthoSize; MainCamera.isOrthoGraphic = cam.isOrtho; //a parent check incase we have a 'fpswalker' type script setup also if (MainCamera.transform.parent) { //move the parent object MainCamera.transform.parent.position = cam.position; Vector3 ang = currentRotation.eulerAngles; //rotate the parent object on the Y axis MainCamera.transform.parent.rotation = Quaternion.Euler(0, ang.y , 0); //rotate the child camera on the X and Z axis MainCamera.transform.localRotation = Quaternion.Euler(ang.x , 0, ang.z ); } else // there is no FPSWalker parent, so just move the camera itself { MainCamera.transform.position = cam.position; MainCamera.transform.rotation = currentRotation; } MainCamera.fov = cam.fov; } void UpdateView(CameraLocation cam) { Camera MainCamera = Camera.mainCamera; cam.isOrtho = Camera.main.isOrthoGraphic; cam.orthoSize = Camera.main.orthographicSize; cam.position = Camera.main.transform.position; cam.rotation = Camera.main.transform.rotation; cam.fov = MainCamera.fov; } } |
Now having built that up, we can simply click on the asset file that we had created previously and see the editor in the Inspector panel, making it easier to handle multiple lists.
Some Useful Unity3D resources
by Dave Buchhofer on Feb.16, 2011, under Unity, Unity3D
Since I’m doing a lot of unity here lately, and starting to lay down some teaching to coworkers, here are a couple useful references for unity3d stuff that aren’t too commonly thrown out there.
http://feedity.com/rss.aspx/unifycommunity-com/UVtQUlVb – RSS feed that updates when new scripts are added to the community WIKI (And feedity in general is pretty nifty.)
http://www.google.com/cse/home?cx=002470491425767499270:iugs1ezlsfq a google custom search engine maintained by some anonymous saint, searches the unity references, answers, forums, and a few other popular blogs.
http://www.google.com/cse/home?cx=001712401338047450041:csfhqk-trfa a second google CSE that includes MSDN and the wiki among others, for when you need that extra bit of microsoft reference.
Also, don’t neglect the boys in irc.freenode.net #unity3d, definitely the single most useful resource @ http://webchat.freenode.net/ or your friendly neighborhood irc client.
*Oops! bolger fail. edit to fix the links.













