- Home /
Picking up Items in VR and keeping hand in position.
Hey all,
Been dealing with this problem for 2 days now so I though Id give it a shot here:
This is as far as I have gotten, Its working quite well. But since I am connecting the sword directly to the wrist bone of the rig to attain this effect, it is pushing the wrist out of the way and giving me a weird hand animation. However its locked position is exactly what I want, something alla blade and sorcery.
I am now however beginning to wonder if my approach is flawed from the outset and am considering doing it all over if anyone has a better approach. I have final ik, puppetmaster to help with the solution. But I cant really seem to get any help anywhere. If anyone wishes to work on thjis with me Id be most grateful and put out a tutorial to make it easier for others in the future.
On the sword is a copy of the hand Object that has been placed in that fingers closed pose and given a handpose script:
public class HandPose : MonoBehaviour
{
public Transform[] transforms { get; private set; }
void Awake()
{
transforms = (Transform[])GetComponentsInChildren<Transform>();
}
}
On the actual hand in the rig hierarchy the hand is given the handTarget script:
public class HandTarget : MonoBehaviour
{
[Range(0f, 1f)] public float weight = 1f;
public HandPose currentPose;
public Transform handBone;
public Transform[] transforms = new Transform[0];
private Vector3 position;
private Vector3 lastPosition;
private Quaternion rotation = Quaternion.identity;
private Quaternion lastRotation = Quaternion.identity;
private Quaternion[] localRotations = new Quaternion[0];
private Quaternion[] lastLocalRotations = new Quaternion[0];
private float lerpWeight;
private float lerpV;
private HandPose lastPose;
void Start()
{
transforms = (Transform[])handBone.GetComponentsInChildren<Transform>();
localRotations = new Quaternion[transforms.Length];
lastLocalRotations = new Quaternion[transforms.Length];
position = transform.position;
rotation = transform.rotation;
lastPosition = position;
lastRotation = rotation;
for (int i = 2; i < transforms.Length; i++)
{
localRotations[i] = transforms[i].localRotation;
lastLocalRotations[i] = transforms[i].localRotation;
}
}
void LateUpdate()
{
if (weight <= 0f) return;
if (currentPose == null) return;
// Changing the pose
if (currentPose != lastPose)
{
position = lastPosition;
rotation = lastRotation;
for (int i = 1; i < transforms.Length; i++)
{
localRotations[i] = lastLocalRotations[i];
}
lerpWeight = 0f;
lastPose = currentPose;
}
lerpWeight = Mathf.SmoothDamp(lerpWeight, 1f, ref lerpV, 0.1f);
Vector3 p = Vector3.Lerp(position, currentPose.transform.position, lerpWeight);
transform.position = weight >= 1f ? p : Vector3.Lerp(transform.position, p, weight);
lastPosition = transform.position;
Quaternion r = Quaternion.Lerp(rotation, currentPose.transform.rotation, lerpWeight);
transform.rotation = weight >= 1f ? r : Quaternion.Lerp(transform.rotation, r, weight);
lastRotation = transform.rotation;
for (int i = 1; i < transforms.Length; i++)
{
Quaternion localR = Quaternion.Lerp(localRotations[i], currentPose.transforms[i].localRotation, lerpWeight);
transforms[i].localRotation = weight >= 1f ? localR : Quaternion.Lerp(transforms[i].localRotation, localR, weight);
lastLocalRotations[i] = transforms[i].localRotation;
}
}
And when picking up the sword a custom event is fired:
/// The pose for holding this Item
[SerializeField] Transform _myRightHandPose;
/// the attachment position of the item to the wrist
[SerializeField] Transform attachmentPos;
/// the IK system of the player
private VRIK ik;
/// the hand we wish to modify
private HandTarget rightHandTarget;
public void MyOnGrabEvent()
{
if (rightHandTarget.weight >= 0.1f)
{
rightHandTarget.weight = 0.03f;
}
rightHandTarget.currentPose = _myRightHandPose.GetComponent<HandPose>();
ik.solver.rightArm.target = attachmentPos;
}
Any help is appreciated.
Have you tried putting the rig and the sword on different collision layers?
Thank you for the input, but the issue here is not pertaining to collisions. what you see in the gif is that the sword becomes part of the rig and the hand has no guidance and so this happens. Im not quite sure how to control the hand correctly from here.