- Home /
How do I rotate finger joints using controller input?
Suppose I have an index finger composed of 3 cubes which all contain Rigidbody which have isKinematic
set to true
. In a hierarchy they are the parent and children like this cube1 -> cube2 -> cube3
I want to control how my finger curls using the controller which outputs strength in range 0-1
, e.g. the ArrowUp button. Put simply, if I hold the up button, all the cubes would rotate around Z for 60 degrees. And if I release the button, it would rotate back to 0 degrees. (All degrees in between 0-60
are valid when the up strength is between 0-1
)
How do I rotate the finger while also making it collide with other objects? For example, you could use the finger to kick a ball.
If I don't care about the collision, I can just use transform.Rotate(0, 0, buttonUpStrength)
in the Update()
function and attach this script to all the cubes. But I care about collision and rigidbody.MoveRotation()
is not enough because the position of each child will stay at the same absolute position when I use it. So I need to use rigidbody.MovePosition()
to move the children relative to the parent also. But it's still not enough, the animation is not smooth, I want the animation to be smooth so I'm thinking that AddTorque()
might be a better way out, but I don't know how to use it as isKinematic=true
objects cannot be used with AddTorque()
.
What is a smarter, simpler way of making the finger kick a ball, without the finger being pushed back by the ball?
This is how my finger looks like, it's just a cube. This is my script, that I attach to all cubes, in the inspector, I set cube1
's angle to be 60. The children will just copy the angle of the parent:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TestJointRotation : MonoBehaviour
{
public float angle;
private Rigidbody rb, rbParent;
private Vector3 originalPos;
private Quaternion originalRot;
void Start()
{
rb = GetComponent<Collider>().attachedRigidbody;
if (transform.parent != null)
{
rbParent = transform.parent.GetComponent<Collider>().attachedRigidbody;
}
originalPos = transform.localPosition;
originalRot = transform.localRotation;
}
void Update()
{
if (rbParent)
{
angle = rbParent.GetComponent<TestJointRotation>().angle;
}
var rotation = Quaternion.identity;
if (rbParent)
rotation *= rbParent.rotation;
rotation *= originalRot;
rotation *= Quaternion.Euler(0, 0, Input.GetAxis("Vertical") * angle);
rb.MoveRotation(rotation);
if (rbParent)
rb.MovePosition(transform.parent.TransformPoint(originalPos));
}
}