kinect笔记 六、简单的虚拟换衣

显示

  1、新建一个空对象,命名为KinectController,在此对象上绑定KinectManager、KinectGestures、OverlayController

  2、KinectManager上的ComputeColorMap和UseMultiSourceReader勾选上

  3、设置Main Camera(这里的摄像头作为一个Foreground Camera)

    (1) Clear Flags设置为Depth only

    (2) Culling Mask 设置为 除Everything外的其他选项都勾选上

    (3) Clipping Plans 的Near设置为0.1 Far设置为10

    (4) Depth设为0

  新建一个camera,命名为BackgroundCamera

    (1)将Clear Flags设置为Solid Color

    (2)Culling Mask设置为Everything

    (3)Depth设为-1

  4、将OverlayController中的BackgroundImage的类型更改为RawImage或Image

    如果改为RawImage则

      if (backgroundImage.texture == null)

             {

                    backgroundImage.texture = manager.GetUsersClrTex();

       }

    如果改为Image则

      if(backgroundImage.GetComponent<Image>().material.mainTexture==null){

        backgroundImage.GetComponent<Image>().material.mainTexture=manager.GetUsersClrTex();

      }

  5、在场景中新建一个Image或RawImage,然后将两个Camera和Image跟OverlayController关联上,然后运行即可

  显示的图像可能是上下颠倒的,在这里我只是将image的Rotation的X改为了180

设置模型的同步和显示

  在模型上绑定AvatarController和AvatarScaler两个脚本

    AvatarController

      勾选上Mirrored Movement

      勾选上Vertical Movement

      Move Rate设为1

      Smooth Factor设为0(或者默认数值也可以)

      将backgroundCamera关联到Pos Relative To Camera上

      勾选上Pos Rel Overlay Color

    Avatar Scaler

      勾选上Mirrored Avatar

      勾选上Continuous Scaling

      Smooth Factor设为5

      将Main Camrera关联到Foreground Camera

   如果是直接拖拽,则使用以上绑定这两个脚本的方法,如果要用代码来写,那还请继续看下去。

  设置画布 Canvas

    将RenderMode设为Screen Space - Camera

    将backgroundCamera关联到Render Camera

    因为之前默认的模式是Screen Space - Overlay,我感觉应该是将UI层置顶了,所以无法显示3D场景中的东西,现在设置为Screen Space - Camera,应该是显示摄像机范围内的物体

以下是根据人体动作来更换显示的衣物模型

1、 

  在场景中创建一个空物体,命名为MyGestureListener,创建一个脚本,命名为MyGestureListener.cs(这是我的一个小习惯,如果不喜欢的话,可以随便放在哪,只要你在用的时候能很快找到就行)

  这个脚本主要用于获取人体的动作

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class MyGestureListener : MonoBehaviour , KinectGestures.GestureListenerInterface
{
    [Tooltip("由该组件跟踪的播放器索引。0代表第一人,1人,第二人,2人,第三人,等等。")]
    public int playerIndex = 0;

    [Tooltip("Text 用于显示监听到的手势动作的信息")]
    public Text gestureInfo;

    //跟踪进程消息是否已显示的内部变量
    private bool progressDisplayed;
    private float progressGestureTime;

    public MyController myController;

    /// <summary>
    /// 当检测到新用户时调用。在这里,可以通过调用KinectManager.DetectGesture()来开始手势跟踪。
    /// </summary>
    /// <param name="userId">User ID</param>
    /// <param name="userIndex">User index</param>
    public void UserDetected(long userId, int userIndex)
    {
        // 只允许主要用户使用手势
        KinectManager manager = KinectManager.Instance;
        if (!manager || (userIndex != playerIndex))
        {
            return;
        }

        // 检测这些用户特定的手势
        manager.DetectGesture(userId, KinectGestures.Gestures.SwipeLeft);
        manager.DetectGesture(userId, KinectGestures.Gestures.SwipeRight);
    }
    /// <summary>
    /// 当用户丢失时调用。此用户的所有跟踪手势都会自动清除
    /// </summary>
    /// <param name="userId">User ID</param>
    /// <param name="userIndex">User index</param>
    public void UserLost(long userId, int userIndex)
    {
        // 只允许主要用户使用手势
        if (userIndex != playerIndex)
        {
            return;
        }
       
    }

    /// <summary>
    /// 当手势正在进行时调用
    /// </summary>
    /// <param name="userId">User ID</param>
    /// <param name="userIndex">User index</param>
    /// <param name="gesture">Gesture type</param>
    /// <param name="progress">Gesture progress [0..1]</param>
    /// <param name="joint">Joint type</param>
    /// <param name="screenPos">Normalized viewport position</param>
    public void GestureInProgress(long userId, int userIndex, KinectGestures.Gestures gesture,
                                  float progress, KinectInterop.JointType joint, Vector3 screenPos)
    {
        // 只允许主要用户使用手势
        if (userIndex != playerIndex)
            return;
        /*Debug.Log("ing");
        Debug.Log(gesture);
        Debug.Log("----ing----");*/
        if ((gesture == KinectGestures.Gestures.ZoomOut || gesture == KinectGestures.Gestures.ZoomIn) && progress > 0.5f)
        {
            if (gestureInfo != null)
            {
                string sGestureText = string.Format("{0} - {1:F0}%", gesture, screenPos.z * 100f);
                gestureInfo.text = sGestureText;

                progressDisplayed = true;
                progressGestureTime = Time.realtimeSinceStartup;
            }

        }
        else if ((gesture == KinectGestures.Gestures.Wheel || gesture == KinectGestures.Gestures.LeanLeft ||
                 gesture == KinectGestures.Gestures.LeanRight) && progress > 0.5f)
        {
            if (gestureInfo != null)
            {
                string sGestureText = string.Format("{0} - {1:F0} degrees", gesture, screenPos.z);
                gestureInfo.text = sGestureText;

                progressDisplayed = true;
                progressGestureTime = Time.realtimeSinceStartup;

            }

        }
        else if (gesture == KinectGestures.Gestures.Run && progress > 0.5f)
        {
            if (gestureInfo != null)
            {
                string sGestureText = string.Format("{0} - progress: {1:F0}%", gesture, progress * 100);
                gestureInfo.text = sGestureText;

                progressDisplayed = true;
                progressGestureTime = Time.realtimeSinceStartup;
            }
        }
        /*if (gesture == KinectGestures.Gestures.Tpose)
        {
            Debug.Log("放大");
        }*/
    }
    /// <summary>
    /// 如果手势完成,则调用。
    /// </summary>
    /// <returns>true</returns>
    /// <c>false</c>
    /// <param name="userId">User ID</param>
    /// <param name="userIndex">User index</param>
    /// <param name="gesture">Gesture type</param>
    /// <param name="joint">Joint type</param>
    /// <param name="screenPos">Normalized viewport position    标准视口位置</param>
    public bool GestureCompleted(long userId, int userIndex, KinectGestures.Gestures gesture,
                                  KinectInterop.JointType joint, Vector3 screenPos)
    {
        // 只允许主要用户使用手势
        if (userIndex != playerIndex)
            return false;

        if (gestureInfo != null)
        {
            string sGestureText = gesture + " detected";
            gestureInfo.text = sGestureText;
        }

        if (gesture == KinectGestures.Gestures.SwipeLeft)
        {
            /*swipeLeft = true;
            //udpClient.SocketSend(gesture.ToString());
            udpClient.SocketSend("xiangZuo");*/
            Debug.Log("swipeLeft");
            //myController.changeModelFunc();
            myController.modelIndex++;
        }
        else if (gesture == KinectGestures.Gestures.SwipeRight)
        {
            /*swipeRight = true;
            //udpClient.SocketSend(gesture.ToString());
            udpClient.SocketSend("xiangYou");*/
            Debug.Log("swipeRight");
            myController.modelIndex--;

        }
        else if (gesture == KinectGestures.Gestures.SwipeUp)
        {
            /*swipeUp = true;
            //udpClient.SocketSend(gesture.ToString());
            udpClient.SocketSend("xiangShang");*/
        }
        else if (gesture == KinectGestures.Gestures.RaiseLeftHand || gesture == KinectGestures.Gestures.RaiseRightHand)
        {
            //udpClient.SocketSend("fangDa");
        }

        return true;
    }
    /// <summary>
    /// 如果手势被取消,则调用
    /// </summary>
    /// <returns>true</returns>
    /// <c>false</c>
    /// <param name="userId">User ID</param>
    /// <param name="userIndex">User index</param>
    /// <param name="gesture">Gesture type</param>
    /// <param name="joint">Joint type</param>
    public bool GestureCancelled(long userId, int userIndex, KinectGestures.Gestures gesture,
                                  KinectInterop.JointType joint)
    {
        // 只允许主要用户使用手势
        if (userIndex != playerIndex)
            return false;

        if (progressDisplayed)
        {
            progressDisplayed = false;

            if (gestureInfo != null)
            {
                gestureInfo.text = String.Empty;
            }
        }

        return true;
    }
    // Use this for initialization
    void Start () {
        
    }
    
    // Update is called once per frame
    void Update () {
        
    }
}

2、  

  模型的显示和跟随着真人的动作而动,主要应该是在于两个脚本,一个是AvatarController,一个是AvatarScaler,其中的AvatarScaler主要作用应该是照着真人适配模型的大小

  创建一个空物体,命名为MyController,生成一个脚本,命名为MyController.cs(呐,如上,这是我的一个小习惯,如果不喜欢的话,可以随便放在哪,只要你在用的时候能很快找到就行)

  这个脚本的作用是更换衣物模型,里面的两个摄像机的命名跟之前创建摄像机的命名相同,对应的关联上就行了

  

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MyController : MonoBehaviour {

    /*public GameObject model1;
    public GameObject model2;
    public GameObject model3;*/

    public Camera backgroundCamera;
    public Camera mainCamera;

    //public GameObject[] models = new GameObject[3];
    public GameObject[] models;//存放所有模型的数组
    public int index=0;//当前选中的模型的索引

    public int playerIndex = 0;//跟字面的意思一样,就是playerIndex
    // Use this for initialization
    void Start () {
        //changeModelFunc();
    }
    
    // Update is called once per frame
    void Update () {
        
    }
    public int modelIndex
    {
        get {
            return index;
        }
        set
        {
            index = value;
            if (index < 0)
            {
                index = models.Length - 1;
            }
            else if (index > models.Length - 1)
            {
                index = 0;
            }
            changeModelFunc(index);
        }
    }
    public void changeModelFunc(int _index=0)//因为直接就能获取到全局的那个index,所以其实这里的 _index没什么用
    {
        //index = 1;
        index = _index;
        Debug.Log(index);
        //model1
        /*Debug.Log("sssssssssssssss");
        Debug.Log(models[index].GetComponent<AvatarController>());
        Debug.Log("eeeeeeeeee");*/

        //只显示当前选择的模型
        for (int i = 0; i < models.Length; i++)
        {
            models[i].SetActive(false);
        }
        models[index].SetActive(true);

        

        AvatarController avatarController = models[index].GetComponent<AvatarController>();

        if (avatarController == null)
        {
            avatarController =models[index].AddComponent<AvatarController>();
            avatarController.playerIndex = playerIndex;
            avatarController.mirroredMovement = true;
            avatarController.verticalMovement = true;
            avatarController.moveRate = 1;
            avatarController.verticalOffset = 0;
            avatarController.forwardOffset = 0;
            avatarController.smoothFactor = 0;
        }
        avatarController.posRelativeToCamera = backgroundCamera;
        avatarController.posRelOverlayColor = true;

        KinectManager km = KinectManager.Instance;
        //ac.Awake();

        if (km && km.IsInitialized())
        {
            long userId = km.GetUserIdByIndex(playerIndex);
            if (userId != 0)
            {
                avatarController.SuccessfulCalibration(userId, false);
            }

            // locate the available avatar controllers
            MonoBehaviour[] monoScripts = FindObjectsOfType(typeof(MonoBehaviour)) as MonoBehaviour[];
            km.avatarControllers.Clear();

            foreach (MonoBehaviour monoScript in monoScripts)
            {
                if ((monoScript is AvatarController) && monoScript.enabled)
                {
                    AvatarController avatar = (AvatarController)monoScript;
                    km.avatarControllers.Add(avatar);
                }
            }
        }

        AvatarScaler avatarScaler = models[index].GetComponent<AvatarScaler>();
        if (avatarScaler == null)
        {
            avatarScaler =models[index].AddComponent<AvatarScaler>();
            avatarScaler.playerIndex = playerIndex;
            avatarScaler.mirroredAvatar = true;
            avatarScaler.continuousScaling = true;
            avatarScaler.smoothFactor = 5;
            avatarScaler.bodyScaleFactor = 1;
            avatarScaler.bodyWidthFactor = 1;
            avatarScaler.armScaleFactor = 1;
            avatarScaler.legScaleFactor = 1;
        }
        avatarScaler.foregroundCamera = mainCamera;
        //avatarScaler.Start();


    }
}

应该就是这样了,如果都做完的话,那就运行看看吧,本来我是把博客当做笔记本了。但是想想吧,博客毕竟是个公开的东西,所以就尽量的多写一些了注释,希望能帮到那些不会的人。

最后,如有问题,还请指出,望请赐教,共同进步。

猜你喜欢

转载自www.cnblogs.com/lingLuoChengMi/p/9708204.html
今日推荐