En este momento estás viendo Unity 3D: mueve los músculos de la cabeza humanoide usando un script

 – Unity

Unity 3D: mueve los músculos de la cabeza humanoide usando un script – Unity

Unity 3D: mueve los músculos de la cabeza humanoide usando un script

– UnityAssets3Free

hola , me llamo kein y para hoy os traigo
nueva pregunta curiosa

Meta

Me gustaría rotar la cabeza de un personaje humanoide con valores de rotación x, y, z usando un script (sin usar ningún otro objeto en la escena como la dirección de «mirada»).

Lo que quiero hacer

Al configurar el rigging de un personaje humanoide (prefabricado humanoide –> Equipo –> Tipo de animación: Humanoide –> Configurar –> Músculos y ajustes), verá la siguiente interfaz: https://docs.unity3d.com/Manual/Definiciones musculares.html

En este menú, debajo de Cabeza, puede arrastrar un control deslizante para mover, por ejemplo, su cabeza humanoide hacia arriba y hacia abajo. Quiero lograr lo mismo con un guión, pero no sé cómo hacerlo.

Recursos

Esta pregunta nunca recibió una respuesta adecuada con código de muestra: https://respuestas.unity.com/questions/824628/can-we-using-script-to-moving-the-muscles-in-unity.html

Supongo que tengo que hacer algo con HumanPose.muscles (https://docs.unity3d.com/ScriptReference/HumanPose-muscles.html), sin embargo, con la falta de ejemplos de código, no tengo idea de cómo abordar esto.

editar 3: Este enlace tiene un ejemplo de código para HumanPose, pero todavía no he podido hacerlo funcionar: https://foro.unity.com/threads/humanposehandler.430354/

Pregunta

¿Cómo obtener los músculos de la cabeza de un personaje humanoide y rotarlos dando valores a través de un script? (O cualquier otra forma de rotar la cabeza usando los valores de rotación de la cabeza, sin ningún otro objeto en la escena). Cualquier ayuda sería apreciada.

Edición 1 y 2: código de muestra

Me sale un mensaje en formato JSON del cual extraigo los valores en radianes y los cambio en grados:

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;
    

  • Datos de rotación de la cabeza: 3.208564, 0.4583662, 0.1145916
  • Datos del cuaternión: 0.0280001, 0.003970424, 0.0008876149, 0.9995997

Realmente no estoy seguro de cómo definir el hueso de la cabeza o los músculos. La mayoría de los ejemplos solo proporcionan un fragmento de código, por lo que estoy luchando por descubrir cómo funciona.

editar 2: Siento que me estoy acercando, pero anim.SetBoneLocalRotation(HumanBodyBones.Head, rotation); parece ser ignorado.

Editar 4: puse en Github una versión simple de mi intento de rotación de la cabeza: https://github.com/NumesSanguis/Basic-Unity-Head-Rotación

3 respuestas 3

Después de probar durante un tiempo, lo descubrí.

  1. Primero, establezca el animator por IK Pasar.

  1. así que usa SetBoneLocalRotation en el interior OnAnimatorIK método. Puedes aprender más sobre este método aquí: https://docs.unity3d.com/ScriptReference/MonoBehaviour.OnAnimatorIK.html
    El siguiente es el código modificado que funcionó para mí.
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));
	

¡Gracias a @ZayedUpal, la rotación de los huesos de la cabeza está funcionando y gracias a un amigo que establece valores musculares también funciona!

El proyecto completo de Unity 3D para ambas opciones se puede encontrar aquí: https://github.com/NumesSanguis/Basic-Unity-Head-Rotación

Fragmento de código del enfoque de valores musculares:

//   !!! 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);

Dos adiciones a la respuesta muscular

1, para resolver el problema:

El personaje al que se aplicó se ha movido demasiado lejos de donde debería haber estado cuando humanPoseHandler.SetHumanPose(ref humanPose); Estaba listo.

Necesitas agregar:

humanPose.bodyPosition = transform.position;
humanPose.bodyRotation = transform.rotation;

Esto mantendrá a tu personaje exactamente donde está ubicado.

2, en realidad, la solución muscular sigue siendo válida cuando se adjunta un AnimatorController al personaje humanoide actual. Solo necesitas cambiar modo de actualizacion por física animada y pon tu codigo de musculo Update(). Esto hará que su código muscular (que se ejecuta en Update()) se ejecuta después de los efectos AnimationController (que se ejecutan en FixedUpdate()que se llama antes Update()).

Este enfoque te permitirá controlar directamente algunos músculos y usar el efecto Unity IK al mismo tiempo.

nota: si aun no se resuelve tu pregunta por favor dejar un comentario y pronto lo podremos de nuevo , muchas gracias

eso es todo,hasta la proxima

Deja una respuesta