Unity 3D - 使用脚本移动人形头部肌肉

时间:2018-02-12 06:13:48

标签: unity3d

目标

我想使用脚本旋转一个人形角色的头部,给出x,y,z旋转值(不使用场景中的任何其他对象作为"看"方向)。

我想做什么

在设置Humanoid角色(人形预制 - > Rig - >动画类型:Humanoid - > Configure - > Muscles& Settings)的装配时,您会看到以下界面: https://docs.unity3d.com/Manual/MuscleDefinitions.html

在此菜单中,在“头部”下,您可以拖动滑块以移动,例如你的人形头部上下。我希望用脚本实现相同的目标,但我不知道如何做到这一点。

资源

这个问题从未得到示例代码的正确答案:https://answers.unity.com/questions/824628/can-we-using-script-to-moving-the-muscles-in-unity.html

我认为我必须对HumanPose.muscleshttps://docs.unity3d.com/ScriptReference/HumanPose-muscles.html)执行某些操作,但由于缺少代码示例,我不知道如何处理此问题。

编辑3 :此链接包含HumanPose的代码示例,但我还没有让它工作:https://forum.unity.com/threads/humanposehandler.430354/

问题

如何获得人形角色的头部肌肉并通过脚本给出值来旋转它们? (或者任何其他方式如何使用头部旋转值旋转头部,而不在场景中使用另一个对象)。任何帮助将不胜感激。

编辑1& 2:示例代码

我收到一条JSON格式的消息,从中我提取弧度值并将其更改为度:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Newtonsoft.Json.Linq;  // JSON reader; https://assetstore.unity.com/packages/tools/input-management/json-net-for-unity-11347

public class HeadRotator : MonoBehaviour {

    Quaternion rotation = Quaternion.identity;

    // Radians to degree
    float Rad2Degree = 180 / Mathf.PI;

    // Human muscle stuff
    HumanPoseHandler humanPoseHandler;
    HumanPose humanPose;
    Animator anim;
    //Transform head;

    // Use this for initialization
    void Start () {
        // get attached Animator controller
        anim = GetComponent<Animator>();

        //head = anim.GetBoneTransform(HumanBodyBones.Head);
        //Debug.Log (head);
    }


    // Use JSON message to set head rotation and facial expressions;
    // IEnumerator to run in main thread (needed for SetBlendShapeWeight)
    public IEnumerator RequestHeadRotation(JObject head_pose)
    {
        // rotate head of character with received x, y, z rotations in radian
        List<float> head_rotation = new List<float> ();
        foreach (KeyValuePair<string, JToken> pair in head_pose) {
            //Debug.Log(pair);
            // store head rotation in degrees
            head_rotation.Add(float.Parse(pair.Value.ToString())*Rad2Degree*10);
        }

        Debug.Log ("" + head_rotation[0] + ", " + head_rotation[1] + ", " + head_rotation[2]);
        //Quaternion rotation = Quaternion.Euler(new Vector3(head_rotation[0], head_rotation[1], head_rotation[2]));
        //Debug.Log ("" + rotation[0] + ", " + rotation[1] + ", " + rotation[2] + ", " + rotation[3]);
        // head.Rotate (rotation);

        // https://docs.unity3d.com/ScriptReference/Quaternion-eulerAngles.html
        rotation.eulerAngles = new Vector3 (head_rotation[0], head_rotation[1], head_rotation[2]);

        // Animator.GetBoneTransform()
        anim.SetBoneLocalRotation(HumanBodyBones.Head, rotation);

        yield return null;
    }
}
  • 头部轮换数据:3.208564, 0.4583662, 0.1145916
  • 四元数据:0.0280001, 0.003970424, 0.0008876149, 0.9995997

我不太清楚如何设置头骨或肌肉。大多数示例仅提供代码片段,因此我在努力弄清楚它是如何工作的。

编辑2 :我觉得我已经接近了,但anim.SetBoneLocalRotation(HumanBodyBones.Head, rotation);似乎被忽略了。

编辑4 :我在Github上添加了一个简单版本的头部旋转尝试:https://github.com/NumesSanguis/Basic-Unity-Head-Rotation

2 个答案:

答案 0 :(得分:4)

经过一段时间的测试后,我明白了。

  1. 首先,将animator设为IK通行证。
  2. enter image description here

    1. 然后在SetBoneLocalRotation方法中使用OnAnimatorIK。您可以在此处了解有关此方法的更多信息:https://docs.unity3d.com/ScriptReference/MonoBehaviour.OnAnimatorIK.html以下是修改后的代码,对我有用
    2. &#13;
      &#13;
      using System.Collections;
      using System.Collections.Generic;
      using UnityEngine;
      
      public class HeadRotator : MonoBehaviour
      {
      	public Vector3 rot = new Vector3(20, 30, 10);
      	Animator anim;
      
      	//  Bone stuff
      	Transform head;
      
      	//  !!! Head bone rotation approach !!!
      	void Start () {
      	  	// get attached Animator controller
      		anim = GetComponent<Animator>();
      		head = anim.GetBoneTransform(HumanBodyBones.Head);
      	}
      
      	void OnAnimatorIK (int layerIndex) {
      		print ("OnAnimatorIK - running");
      		anim.SetBoneLocalRotation(HumanBodyBones.Head, Quaternion.Euler(rot));
      	}
      }
      &#13;
      &#13;
      &#13;

答案 1 :(得分:2)

感谢@ZayedUpal头骨旋转正常工作,感谢朋友,设定肌肉值也有效!

可以在此处找到两个选项的完整Unity 3D项目:https://github.com/NumesSanguis/Basic-Unity-Head-Rotation

肌肉价值观的代码片段:

//   !!! Human Pose approach !!!
void Start () {
    // https://forum.unity.com/threads/humanposehandler.430354/

    // get attached Animator controller
    anim = GetComponent<Animator>();

    // run this if you want the indexes to muscles on your character
    LookUpMuscleIndex();

    // TODO keeping body above plane
    //Vector3 current_position = transform.position;

    // get human pose handler
    humanPoseHandler = new HumanPoseHandler(anim.avatar, transform);
    // get human pose
    humanPose = new HumanPose();

    // TODO keeping body above plane
    //humanPose.bodyPosition = current_position;

    // reference pose to pose handler
    humanPoseHandler.GetHumanPose(ref humanPose);

    // set a specific musle; 9: Neck Nod Down-Up
    humanPose.muscles[9] = -20f; 
    Debug.Log(humanPose.muscles[9]);

    // use pose information to actually set the pose;
    humanPoseHandler.SetHumanPose(ref humanPose);
}