别忘了设置好pico的设置和导入需要的样式
一、动画设置
1.1设置Avatar 遮罩;
1.2创建动画、手指动画的话,我创建了四个,分别对应的是(平展、弯曲食指、弯曲其他手指、握拳)
1.3建立分层、我建了三层,默认层,左手遮罩层、右手遮罩层;同时建立了BlendTree混合树
1.4添加参数和运动、混合类型选择2d Freeform Cartesian、并选择对应的运动和对应的参数
二、IK设置使用 Animation Rigging实现IK制作程序化的动画手臂跟随手自动移动等效果
三、完成以上操作后,下述完整代码(基本完成了以上操作、但是还要优化、比如移动、抓取等)
using System.Collections; // 引入 System.Collections 命名空间,提供了一些通用的集合类型
using System.Collections.Generic; // 引入 System.Collections.Generic 命名空间,提供了一些泛型集合类型
using UnityEngine; // 引入 Unity 引擎的基本功能和类
using UnityEngine.InputSystem; // 引入 Unity 的输入系统相关的类和功能
public class NewBehaviourScript : MonoBehaviour
{
//头部控制器(vr头盔)
public Transform XROrigin;
//头部控制器(vr头盔)
public Transform headController;
//左手控制器(左手柄)
public Transform leftHandController;
//右手控制器(右手柄)
public Transform rightHandController;
public Transform player;
//头部rig
public Transform head;
//左手rig
public Transform leftHand;
//右手rig
public Transform rightHand;
//设置默认的模型身高
public float playerHeight = 2.0f;
public Animator animator;
//
// 公开的输入动作属性 - 捏合动作
public InputActionProperty lpinchActionProperty;
// 公开的输入动作属性 - 握取动作
public InputActionProperty lgripActionProperty;
// 私有变量,存储捏合动作
private InputAction lpinchAction;
// 私有变量,存储握取动作
private InputAction lgripAction;
// 公开的输入动作属性 - 捏合动作
public InputActionProperty rpinchActionProperty;
// 公开的输入动作属性 - 握取动作
public InputActionProperty rgripActionProperty;
// 私有变量,存储捏合动作
private InputAction rpinchAction;
// 私有变量,存储握取动作
private InputAction rgripAction;
// Start is called before the first frame update
void Start()
{
/*初始化身高
float playerzoom = headController.position.y / playerHeight;
player.localScale = new Vector3(playerzoom, playerzoom, playerzoom);*/
// 如果没有手动设置Animator,则获取当前物体上的Animator组件
if (animator == null)
{
animator = GetComponent<Animator>();
}
//设置后在物体上添加脚本,进行绑定pico的值
// 将 pinchActionProperty 中的动作赋值给 pinchAction
lpinchAction = lpinchActionProperty.action;
// 将 gripActionProperty 中的动作赋值给 gripAction
lgripAction = lgripActionProperty.action;
// 将 pinchActionProperty 中的动作赋值给 pinchAction
rpinchAction = rpinchActionProperty.action;
// 将 gripActionProperty 中的动作赋值给 gripAction
rgripAction = rgripActionProperty.action;
/* */
}
// Update is called once per frame
void Update()
{
//修改角色朝向和启动转向动画(我这里没有启动动画)
Vector3 cameraForward = headController.forward;
cameraForward.y = 0;
player.rotation = Quaternion.LookRotation(cameraForward);
//修改角色位置
Vector3 newPosition = XROrigin.position ;
transform.position = newPosition;
//头部旋转
Quaternion headControllerRotationQuaternion = headController.rotation;
head.rotation = headControllerRotationQuaternion;
//根据头盔高度修改模型蹲的数值、修改动画(我这里没有写)
//左手操作
// 计算旋转差值(四元数表示)
Quaternion rotationDifference = Quaternion.Euler(0, -90, -90);
HandRotation(leftHandController, leftHand, rotationDifference);
//右手操作
// 计算旋转差值(四元数表示)
Quaternion rightrotationDifference = Quaternion.Euler(0, 90, 90);
HandRotation(rightHandController, rightHand, rightrotationDifference);
/*
animator.Play("LForeFinger");
animator.Play("LFinger");
*/
// 读取捏合动作的值并转换为 float 类型
float ltriggerValue = lpinchAction.ReadValue<float>();
// 设置动画器的 "Trigger" 参数为读取到的捏合值
animator.SetFloat("IsLForeFinger", ltriggerValue);
// Debug.Log("ltriggerValue" + animator.GetFloat("IsLForeFinger"));
// Debug.Log("ltriggerValue2" + ltriggerValue);
// 读取握取动作的值并转换为 float 类型
float lgripValue = lgripAction.ReadValue<float>();
// Debug.Log("lgripValue" + lgripValue);
// 设置动画器的 "Grip" 参数为读取到的握取值
animator.SetFloat("IsLFinger", lgripValue);
// 读取捏合动作的值并转换为 float 类型
float rtriggerValue = rpinchAction.ReadValue<float>();
// 设置动画器的 "Trigger" 参数为读取到的捏合值
animator.SetFloat("IsRForeFinger", rtriggerValue);
// Debug.Log("rtriggerValue" + rtriggerValue);
// 读取握取动作的值并转换为 float 类型
float rgripValue = rgripAction.ReadValue<float>();
Debug.Log("rgripValue"+rgripValue);
// 设置动画器的 "Grip" 参数为读取到的握取值
animator.SetFloat("IsRFinger", rgripValue);
/**/
}
/*动画剪切*/
//修改手部的位置和旋转
void HandRotation(Transform HandController, Transform Hand, Quaternion rotationDifference ) {
//修改角色手位置
Hand.position = HandController.position;
// 获取手控制器的旋转(四元数表示)
Quaternion aRotationQuaternion = HandController.rotation;
// 应用差值到手控制器的旋转并获取新的四元数
Quaternion bRotationQuaternion = aRotationQuaternion * rotationDifference;
// 将新的四元数设置给左手的旋转
Hand.rotation = bRotationQuaternion;
}
}