Virtual Reality (VR) development is an innovative and exciting field to work in. Once a project gets rolling it can be so much fun to invent, program, and problem solve to create the solutions and experiences required for each project. Getting to that point always involves passing through a process that is often vastly more complicated than it needs to be, the process of setting up the initial VR framework for a new project. Since the field of VR is so rapidly changing and evolving, each time a new project is started there is usually some aspect of setup that runs into issues and disconnects between updates in various editors, packages, or plugins. Luckily for my teammates and I, our manager Zac has put together a fantastic framework called PuppetJump that streamlines most of this project setup.

In order to familiarize myself with the functionality built into PuppetJump, I decided to start building small demo projects that center on implementing specific aspects of the framework. In this post I will cover the development process for a small demo I have been referring to as the Magnetics Lab.

 

Magnetics Lab Development Video Playlist


This post will cover the following development steps I took while creating this demo


The Focus

The reason for developing this demo was to familiarize myself with various aspects of the PuppetJump framework. The specific focus was to learn more about the Forcibles system, which creates VR interactions through physics based interactions (rather than the smoke and mirrors we developers usually use to mimic the results of such interactions). To accomplish this, I needed a physics based process to recreate using the PuppetJump tools. I decided to replicate the basics of magnetic interactions, since they would be a simple enough interaction type that wouldn’t be overly complex and could be a fun demo to play around with once finished.


Attractors

In my mind the clear first step was to create a type of basic attractor using PuppetJump Forcibles. These attractors would be simple objects that, as the name implies, attract other objects to them. Creating these attractions meant learning how Forcibles apply physics to game objects, how to dynamically add and manipulate those applied physics, and how the various settings for the applied physics would alter and effect the interactions.

I decided to keep the initial setup as simple as possible, so I created one type of object that would act as a magnetic field, and another type that would act as a magnetically reactive object. With a little bit of tinkering, a little bit of code examination, and a bit of reading the documentation, I was able to get some simple interactions up and running.

This was accomplished by creating a medium sized sphere, setting it up as a trigger collider, and adding some code to react to any magnetic object entering or leaving the sphere. This trigger sphere would be my magnetic field. When any object entered the trigger sphere, the magnetic field would check if it was a magnetic object. If the object was a magnetic object, then the magnetic field would notify the Forcible on the magnetic object to dynamically add a motor (physical force) which would start moving the magnetic object toward the center of the magnetic field.

 

 


Dual Charges

As everyone knows, magnetic fields have two primary types of interactions based on the magnetic poles, or polarity, of the fields and objects involved in the interaction. Now that I knew I could dynamically create attractive forces using Forcibles, the next step was to create repulsion. Once again, with a little tinkering I was able to implement code and logic to identify each magnetic field and magnetic object as being positive or negative, and to enact their interactions accordingly.

(Side Note: I am fully aware that the magnetic poles are normally denoted as North and South, and that most magnetically reactive fields and objects have both a North and South magnetic pole. But for simplicity’s sake at this point I decided it was more straight forward to create/use magnetic mono poles and to label them as positive/negative rather than North/South)

With the magnetic fields and magnetic objects now identified as one of two polarity types, I was able to create attraction between opposite polarity types, and repulsion between matching polarity types.

 

 


Multi-Field Interactions

The next level of complexity I decided to tackle was the inclusion of multi-field interactions. Up until this point, the code I created only dealt with interactions between a single magnetic field and a single magnetic object. This was a great stepping-stone for setting up the core functionality that ran these magnetic interactions but caused issues when more than one magnetic field and magnetic object were introduced to the interactions. When a magnetic object encountered a second magnetic field it would completely forget about the first magnetic field and would only interact with the second magnetic field. So, my next step was to create code to manage multiple magnetic fields simultaneously. Accomplishing this task required a bit of bug testing to avoid complications and oversights such as a magnetic field enacting duplicate influences on the same magnetic object, or magnetic objects continuing to be influenced by magnetic fields that were no longer in contact range. After a little fiddling, I was able to get a robust and dynamic interaction system up and running, allowing magnetic objects to be influenced by multiple magnetic fields at the same time.

 

 


Inverse Square Law

Now that I had the basic interactions functioning, I decided to find out if I could make the magnetic interactions a bit more realistic. To do this I found the equation that determines the strength of magnetic interactions and attempted to implement this equation into my magnetic interaction code. This equation is called the Inverse Square Law and states that the strength of magnetic influence is equal to the inverse square of the distance between the objects involved.

Implementing this equation into my code brought the magnetic interactions to a whole new level. Prior to this point, when a magnetic object was influenced by a magnetic field it would move at a uniform speed toward or away from the magnetic field creating the influence. With this equation at work, a magnetic object now moved with exponentially increasing speed as it gets closer to the center of the magnetic field influencing it.

 

 


Ignore List

Attempting to make one step closer to realism, I noticed that unlike real magnets, the magnetic fields in my demo had no effect on each other. As we know, real world magnets effect not only non-magnet objects like paper clips, but also have a strong effect on other magnets. This step was easy enough to create in my demo by simply attaching a magnetic object as part of each magnetic field. At first glance this worked without issue, but upon closer inspection I noticed that this was creating additional and unnecessary calculation while the program was running. This arose due to each magnetic field attempting to influence its own magnetic object. Visually this didn’t look like anything at all, but behind the scenes this added a constant additional force pushing the magnetic object toward the center of its connected magnetic field. So my next step was to create an “Ignore List” for each magnetic field which informed it to, as the name suggests, ignore any magnetic objects in the list. This prevents the magnetic fields from attempting to influence their own magnetic object.


Magnetize / Demagnetize

At this point I was feeling pretty confident about my familiarity with the Forcibles aspect of PuppetJump but wanted to continue learning more about the framework. So, the next element I decided to play around with was the button rig setup used in PuppetJumps 3D-UI system. I decided to build a 3D button pad which would allow me to toggle on/off the magnetic interactions in the scene. After a little trial and error I was able to create this button and it’s accompanying magnetic control toggle functionality. Building this button not only gave me some experience working with the 3D-UI button rig setup, but also gave me some exposure to a new Unity feature called ArticulationBodys. This also helped me find, track down, and fix a bug in the magnetics system. When the magnetic interactions between the magnetic fields and magnetic objects was disabled and then enabled again, the magnetic fields failed to re-establish influence on any magnetic objects already inside their trigger sphere when re-activation occurred. A little tinkering led me to find and implement a solution to this issue.