I wanted to have a character ride an electric scooter. I am not going to worry initially about mounting and dismounting, but I do want the character to have the hands on the handlebars as the scooter turns left and right as it moves.
Later I would want to scooter to follow a target, but that is relatively straightforward – you compute the direction of the target and turn towards that (turning more sharply if moving slower), slowing the scooter down if moving away from the target, speeding it up if moving towards the target and a fair distance away, and slowing the scooter down as it approaches the target. A bit of maths, but not the goal of this post.
Handlebars Attempt #1
My first attempt at the handlebars was to put to container objects on the handlebars and set the position of the hands to the position of these containers. While the hands did move, the arms did not bend appropriately. The end result is … interesting.
This is where a new capability in Unity 2020.1 comes in handy, Rigging Animation.
What Unity has introduced is the ability to define constraints on how things move. The particular constraint we are going to use here is a two bone IK (inverse kinematics) constraint. This is ideal for arms and legs with two bones and a joint in the middle. What it allows you to do is move the hand, and the constraint will work out how to move the two arms (or leg) bones appropriately.
Once these constraints are added to a character, instead of moving the hand directly, we move an “effector” and the arm bones are then moved to achieve the desired hand position.
The VRoid Character Structure
VRoid Studio characters all of the same internal structure (they just visually look different). In particular I have expanded out the skeleton hierarchy to point out the location of the left/right hands and legs (that is, J_Bip_L_Hand, J_Bip_R_Hand, J_Bip_L_UpperLeg, and J_Bip_R_UpperLeg).
In addition to the default VRoid character bone structure, you have to set up additional rigging animation constraints. I strongly recommend viewing at least the first half of this video https://youtu.be/hs2goLjUz4U as a good introduction. I race through the steps here to give a taste of what is required.
First enable “Preview” packages in the package manager “Project Settings” / “Package Manager” / “Advanced Settings” / “Enable Preview Packages” and import the package.
Next you build up the following additional game objects under the character (see “Rig Setup”).
The root layer of your character gets a “Rig Builder” component that references the “Rig Setup” child object. (You can have multiple independent Rig Setups if you want to turn them on and off individually.) The Rig Setup child object must have a “Rig” component added. Then add a child object per constraint (we are going to add one for each arm and leg). Add the “Two Bone IK Constraint” component to the 4 constraints. Finally under each constraint have a “xxx_target” and “xxx_hint” object. The target object is what we going to change the position of, which in turn will trigger the constraint computations to move the character’s two arm/leg bones. You set this to have the same position as the “J_Bip_L_Hand” etc objects. The hint object is used to flex the elbow/knee joint in the right direction.
The end result is you can move the target objects and override the current animation clip that is running (with a blend control to move from the current animation clip to the override).
Free Electric Scooter
I grabbed the free scooter from the asset store here: https://assetstore.unity.com/packages/p/electric-scooter-prop-171335.
There are a few variations of the scooter, I am using the one with the following structure.
The ElectricScooter_T is the steering column that we rotate to steer the scooter.
Next add some additional objects to the scooter as follows.
Move the Left/Right Hand objects to just above the handle bars where the rider should hold on to. (I also had to set the rotation to 180 degrees so the hands pointed forwards.) By using child objects these objects will automatically be updated with the correct position when the steering wheel turns. The script I describe below copies the position of these objects over the target objects above.
The other additional object “Rider Positioning” is a wrapper around the VRoid Character set up with rigging animation as above. This allows the character to be raised to stand on the scooter base etc. (It cannot be done to the root of the character as animation clips take over control of the root layer.)
I don’t have it working 100% yet (I can control the hands but not the feet for some reason), but it is working somewhat. Towards the end of the video you can see the arms moving as the steering wheel changes.
The current script can be found on GitHub in ElectricScooterLocomotion.cs.