我想使用脚本旋转一个人形角色的头部,给出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.muscles
(https://docs.unity3d.com/ScriptReference/HumanPose-muscles.html)执行某些操作,但由于缺少代码示例,我不知道如何处理此问题。
编辑3 :此链接包含HumanPose的代码示例,但我还没有让它工作:https://forum.unity.com/threads/humanposehandler.430354/
如何获得人形角色的头部肌肉并通过脚本给出值来旋转它们? (或者任何其他方式如何使用头部旋转值旋转头部,而不在场景中使用另一个对象)。任何帮助将不胜感激。
我收到一条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
答案 0 :(得分:4)
经过一段时间的测试后,我明白了。
animator
设为IK
通行证。SetBoneLocalRotation
方法中使用OnAnimatorIK
。您可以在此处了解有关此方法的更多信息:https://docs.unity3d.com/ScriptReference/MonoBehaviour.OnAnimatorIK.html以下是修改后的代码,对我有用
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;
答案 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);
}