Where can I modify the grip state value to include my own hand animations?

That is the question:

Where can I modify the grip state value to include my own hand animations?

I don’t have too much experience with the animation part of unreal, so I’m kind of a bit lost here.

Thanks in advance for the help!

Cheers.

You would want to store the grip value as a normalized float (0…1) and use an animation blueprint to read in this value and use it correspondingly in the animations. You’ll need to apply bone rotations to your skeletal mesh. Here is a short video I created a week or two ago which uses the capacitive touch on the Oculus Touch controllers.

Ok, but what I can´t find is where can I define the value assigned to the enumerator.

As an example I added one more animation to the blend space, and now the Grab animation is at 0.75 and the Point animation is at 1, but I can´t find a way to tell it that the “Grab” value in the Enumerator now should be 0.75 instead of 1.0, so I always get a pointing hand when I grab something.

Thanks for the help :slight_smile:

Uh… you’re very confused.

An enumerator is just a human readable integer value. The values are defined in the declaration of the enumerator. The enum values don’t mean anything to the compiler, the meaning is only given to them based on how the application reacts to them. Unless specified, by default each enum value is incremented by 1, and starts at 0. Here’s an example:



UENUM(BlueprintType)
enum class EMotionControllerType : uint8
{
	None = 0,
	//using only the leap motion controller
	LeapMotion = 1,

	//using only the oculus touch motion controller
	OculusTouch = 2,

	//using both oculus touch and leap motion controller
	LeapAndTouch = 3,

	//using only HTC Vive motion controller
	ViveWand = 4,

	//using both HTC Vive motion controller and Leap motion controller
	LeapAndVive = 5
};


Sometimes, if you want to be really tricky, you can make your enum values grow in powers of 2, starting at 1. These would be super useful for bitmasking flags. This would let you compact 32 boolean values into one integer value. Windows programming does this a lot, and I’ve seen it in the engine backend a few times. It’s a good trick to know :slight_smile:

It’s not 100% obvious from the code above, but I do support this bitmasking based upon the order of my enums. Leap motion is 1 (2^0), Oculus Touch is 2 (2^1), Vive is 4 (2^2), and if I combine the leap motion with the touch, I have 2+1 = 3, and leap motion can also be combined with the vive, which is 4+1=5; But it gets funky if you try to combine vive with touch 4+2, so I leave out 6. If there was a fourth hardware input device I wanted to support (PSVR), the next integer value would be set at 8 because its 2^3;

Anyways…

In my VR game, I have each finger have a “curl” value which ranges between 0…1, and by default, the finger is curled at 0.2
0 is completely open hand, 1.0 is completely closed hand, with a fist. The curl value is just an alpha value which is used to lerp between a min and max rotation value for each bone in the finger.

Since I’m specifying per finger curls, I can set the position of a hand with five float values, one for each finger. The thumbs up set would be: {0, 1, 1, 1, 1}

One other polish thing I do: rather than instantly setting a finger to a curl value, I do a smooth linear blend from the fingers current state to a desired state. If you don’t do this, the fingers pop and that looks unnatural – fingers move through space over time without discontinuities!

Hi Slayemin

Thanks for your explanation, it’s great!

I know that the Enumerator is a holder with some values and it does not hold any value, but your explanation has been very educative and I’ve learned asome things I did not know :slight_smile:

When I mean to assign the value is that in the VR Template you have the hands and you have an animation blend space, adn in the Blueprints you see whne you activate the different Enumerator states, but what I can’t find at all is the place where they set the corresponding Blend Space values to the corresponding Enumerator values, so when the hand is in the “open” value of the enumerator, the Blend Space value is 0, but when it’s in the “Grip” value the Blend Space value is 1.0.
Now I added a third value, so the “Open” should still be 0, the “Grip” should be 0.75 and the “Point” value should be 1.0, but I don’t find where did they set those correspondences, where is the if/else or something similar in the blueprints.

A lot of thanks for your help Slayemin!

Cheers.

I haven’t used the VR templates.

Hmm, that’s an interesting approach to use blend spaces between hand gestures based on enum values. So, what are the limitations of this approach?
It works great if you are blending between an open hand and a closed hand because you only have two animation states to move between. But, if you have more gestures, such as thumbs up, or point, you shouldn’t use blend spaces anymore. If your last blend was a pointer finger and your middle blend was a fist, and between that was a thumbs up, you’d hit the thumbs up gesture as your blending from closed fist to pointer gesture. You could go directly to the blend value instead of blending, but that would create popping in your animations.

I personally still think my approach is better. I can do hard coded hand gestures to respond to capacitive touch sensors, or I can use leap motion to replicate any hand gesture the IR camera sees, and there is no worries about animation blending between gestures. Maybe I’ll do a write up in another post on how I did it.

Did you ever get an answer to this? I’m having the same problem.

The conversion from the Enum value to the Grip value happens in the Event Graph of the AnimBP (in a bit of convoluted manner if you ask me). See the attachment.

I was looking at that but for the life of me and can’t follow what it’s doing, or more specifically, how it’s collating an animation to an enum value. What would I need to change to add a few new animations?

I saw that, but I can’t for the life of me figure out what it’s actually doing. How would I go about adding a new animation?

Thanks!

Ok, I am going to show a method to add a single extra animation (Pointing pose) to the VR template without altering the AnimBP. It’s not elegant, but it works.

  1. Add a bPointing boolean variable to the BP_MotionController. Set its initial state to FALSE.
  2. Add the following portion to the Event Tick of the BP_MotionController as shown below.

  1. You need a way to set and reset the bPointing variable depending on the status of the Motion Controller. The Oculus has specific input event for capacitive touch, one dedicated to pointing. Inside your MotionControllerPawn add the following:

That’s it. Now your hands can also point! See video below.

https://i.imgur.com/tgsUF5C.gif

Ok, I forgot to explain how the code in the AnimBP works in case you would like to understand it better.

So, the BlendSpace 1D in the AnimGraph needs a number between 0 and 1 to drive the transition between the Open, the CanGrab and the Grab poses. This value is stored in the Grip variable, which happens to be a float. In the BP_MotionController however the hand state is tracked via an enum of type GripEnum. This takes the Open, CanGrab and Grab values.

In order to work with it, the AnimBP needs to convert the GripEnum value into a Float first. It also has to make sure the transition from one state to the next happens smoothly over time. Here is when FInterp comes into play.

Basically, the AnimBP uses FInterp to Constant (Float interpolation to constant) to drive the transition of the Grip value (between 0 and 1) over a given time so it takes place smoothly. The Current value is the current Grip value (say 0) and the Target value is derived from the enum GripEnum.

Here is the tricky part. In order to work with it in Finterp, the GripEnum enum is first converted to an int and then to a float. How is this possible? Well. the values of an enum are mapped to integers behind the scenes, so the first value (Open) is 0, the second (CanGrab) is 1 and the third (Grab) is 2. You can therefore convert an enum to an integer and then, this is easier, an integer to a float.

This is the kind of “magic” which happens in the Event Graph of the AnimBP. It is not straightforward if you ask me. It’s more a kind of programmer’s trick, but it does the job.

Hope this helps!

Thank you! Your explanation of Enums pointed me in the right direction.

**I was trying to add a state to this hand graph myself and finally figured out how. Here’s how to do it with pictures.

  1. I added the enum in a logical place, my new grip is between can grab and grab. So logically it goes between the two:**

2) As you can see the blendspace goes from 0 to 1 (left to right). This is why the order matters, I put my new state at 0.75 You’ll see why in the next step:

**3) The way they are handling this in the Anim bp is awful so I changed how it’s done… The position on the blendspace can be whatever you want but I left everything as is for the three states which were:
Open: 0
CanGrab: 0.5
Grab: 1

And I added my own state hold at 0.75.
So below it returns the desired position we want to be in the blend space depending on what the enum is. Much simpler, the old way was doing division to figure out the position. This is a better solution.**


**So that’s the basis of you get this done, now you have an intermediate state between the default two. If you wanted to add more states in diff position you’d have to just figure out what position along the blend space you’d want to return for different states.

Hope this helps someone!**

Because the enum can be converted to integer, so its values become 0, 1 and 2. But for the Blendspace you need a value between 0 and 1, so dividing by 2 does the trick.

I’ve been trying to implement a point finger animation to my VR hands and followed this video here: He’s essentially using a state machine to call the animation and an actor has tag node in the motion controllers. However, it’s not working with me.
Would you mind taking a look at my screens please? What could be wrong here? Point Finger - Album on Imgur
Thank you!!!