Software Archive
Read-only legacy content
17060 Discussions

Unity Tip: Resetting A RealSense-Powered Object's Rotation with Slerp

MartyG
Honored Contributor III
625 Views

Hi everyone,

If you have used RealSense with Unity to create an object that uses complex positioning, one of the challenges can be resetting the object back to a precise default position.  A type of rotation called a Quaternion Slerp is excellent for this, as it changes the rotation coordinates of the X, Y and Z axes to whatever you want them to be.  

Furthermore, a Slerp type rotation will actually rotate the object smoothly from its current position to the desired reset position, instead of doing an unsightly "teleport" where the angle suddenly snaps from one point to another.

However, there is a critical flaw with the basic Sletp formula that can make it impractical for object resets.  You have to specify exact coordinates for X, Y and Z (e.g 0, 0, 0). and do not have the option to only change one axis and leave the other two unchanged   This means that the Slerped object may reset to the default whilst leaving the other objects that lack the Slerp script non-rotated, resulting in the Slerped object facing in the wrong direction after the reset.

In my company's own full-body avatar project, the primary effect of this was that if Slerp was used to reset the legs from a crouch position to the default standing position, the legs would end up pointing back to front after the reset, because the leg rotation had changed but the rest of the body had not!

However, we have finally found a solution that enables a single axis to be Slerped whilst not altering the other two axes.  How this is accomplished is that the current values of the axes that we want left unchanged are stored in a variable.  That variable is then substituted into the Slerp formula in place of a numeric value, meaning that when the script runs, Unity reads the current rotation values in the variables and transposes them into the Slerp formula.

For example, if we store the current value of the 'Y; rotation axis in a variable called 'Y' then by putting 'Y' into the Slerp formula in place of a number such as '0', the object will use 'Y' as the value to rotate that axis to.  But because the object is already at that angle, it will not move when the script runs because that axis is already at its destination angle.

In our avatar example, that means that when the Slerp script tells the legs to rotate up out of the crouch position to resume the default standing stance, the legs do not spin back to front because they have effectively been told to stay exactly where they are at that moment.

The basic formula for a special Slerp that reads the current rotation value from a specific axis is shown in the JavaScript script below.

var [NAME OF AXIS VARIABLE]  = GameObject.Find("[NAME OF THE OBJECT THE SLERP SCRIPT IS IN]").transform.eulerAngles.[NAME OF AXIS VARIABLE];

In our own project,, where we rotate our avatar's master parent object called 'Player' and store our current axis rotation value in a variable called 'y', the code looks like this:

var y = GameObject.Find("Player").transform.eulerAngles.y;

If we wanted to store the value of the X or Z axes instead, we would simply change 'y' to 'x' or 'z'.

In the next line of the script, we can specify our variable name in the Slerp foruma:

 var target = Quaternion.Euler (0, y, 0);

If you were seeking to substitute the current value of axis X into the equation, you would use:

 var target = Quaternion.Euler (x, 0, 0);

And Z would be:

 var target = Quaternion.Euler (0, 0, z);

Remembering that each of the three bracket values represent X, Y and Z axes in that order, you place your custom variable name into the appropriate part of the bracket - the first value for X, the second value for Y and the third value for Z.

The bracket axes that lack a custom variable contain the values of the angles that you want your Slerp script to rotate your object to.  So if you had defined an 'x' variable to keep rotation the same on that axis but wanted to change axis Y to '40' degrees and the Z axis to '90' degrees, the equation would look like this:

 var target = Quaternion.Euler (40, y, 90);

Here is the full JavaScript script that we use for our Slerp rotation.

function Update () {
	
	 var y = GameObject.Find("Player").transform.eulerAngles.y;
	
 var target = Quaternion.Euler (0, y, 0);
		transform.rotation = Quaternion.Slerp(transform.rotation, target,
		                               Time.deltaTime * 4);
		
	}

The transform.Rotation line that follows after the Slerp bracket line basically defines how quickly the object will rotate.  In the script above, we use the value '4' to define our speed.  If you wanted your object to rotate slower then you would use a smaller number and if you wanted it to rotate faster then you would use a larger number.  Through trial and error, you can find the rotation speed that best suits the objects in your project.

When we used this script in the master 'Player' object of our avatar, it was able to reset to default position whilst remaining pointing in the direction it was currently looking in.  Before, we had the annoying situation where the avatar would be viewed from behind when walking but would then spin around 180 degrees to the '0' angle when the reset was activated, meaning that the player had the hassle of having to turn the avatar around to face back in the direction that they were trying to go in.  This problem was now solved with the new code.

Also, when used in the legs of our avatar, it was able to reset from a crouch to its default standing position from whatever angle the legs were currently at without twisting the legs into the wrong direction as it did so. 

You can easily activate a Slerp reset for your object at will by unticking your object's Slerp script in Unity's Inspector panel (so that it does not run when your application begins) and then setting up a 'SendMessageAction' RealSense SDK script in the same object to initiate the function 'Update' (the name of the function in the Slerp script) whenever a particular gesture is made by the hands or face, and thus reset your object to the defined default position each time the camera recognizes that gesture.

If you have any questions about this process, please feel free to ask them in the comments below.  Best of luck!

0 Kudos
0 Replies
Reply