using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using System.Collections;
using System.Collections.Generic;
using System.IO;
public class ModelSelector : MonoBehaviour
{
[Tooltip("Index of the player, tracked by this component. 0 means the 1st player, 1 - the 2nd one, 2 - the 3rd one, etc.")]
//用户的下标
public int playerIndex = 0;
[Tooltip("The model category. Used for model discovery and title of the category menu.")]
//选择的内容
public string modelCategory = "Clothing";
[Tooltip("Total number of the available clothing models.")]
//模型的数量
public int numberOfModels = 2;
// [Tooltip("Screen x-position of the model selection window. Negative values are considered relative to the screen width.")]
// public int windowScreenX = -160;
[Tooltip("Reference to the dresing menu.")]
//穿着菜单
public RectTransform dressingMenu;
[Tooltip("Reference to the dresing menu-item prefab.")]
//穿着项目预制体
public GameObject dressingItemPrefab;
[Tooltip("Makes the initial model position relative to this camera, to be equal to the player's position, relative to the sensor.")]
//对准人物的相机
public Camera modelRelativeToCamera = null;
[Tooltip("Camera used to estimate the overlay position of the model over the background.")]
//前景的相机
public Camera foregroundCamera;
[Tooltip("Whether to keep the selected model, when the model category gets changed.")]
//保持选择模型
public bool keepSelectedModel = true;
[Tooltip("Whether the scale is updated continuously or just once, after the calibration pose.")]
//是否一直刷新比例
public bool continuousScaling = true;
[Tooltip("Full body scale factor (incl. height, arms and legs) that might be used for fine tuning of body-scale.")]
[Range(0.0f, 2.0f)]
//身体比例因素
public float bodyScaleFactor = 1.0f;
[Tooltip("Body width scale factor that might be used for fine tuning of the width scale. If set to 0, the body-scale factor will be used for the width, too.")]
[Range(0.0f, 2.0f)]
//身体宽度比例因素
public float bodyWidthFactor = 1.0f;
[Tooltip("Additional scale factor for arms that might be used for fine tuning of arm-scale.")]
[Range(0.0f, 2.0f)]
//手臂的比例因素
public float armScaleFactor = 1.0f;
[Tooltip("Additional scale factor for legs that might be used for fine tuning of leg-scale.")]
[Range(0.0f, 2.0f)]
//腿部的比例因素
public float legScaleFactor = 1.0f;
[Tooltip("Vertical offset of the avatar with respect to the position of user's spine-base.")]
[Range(-0.5f, 0.5f)]
//上下移动
public float verticalOffset = 0f;
[Tooltip("Forward (Z) offset of the avatar with respect to the position of user's spine-base.")]
[Range(-0.5f, 0.5f)]
//前后移动
public float forwardOffset = 0f;
[Tooltip("Whether to apply the humanoid model's muscle limits to the avatar, or not.")]
//是否应用化身人形肌肉模型的限制,
private bool applyMuscleLimits = false;
[Tooltip("Gender filter of this model selector.")]
//性别筛选器
public UserGender modelGender = UserGender.Unisex;
[Tooltip("Minimum age filter of this model selector.")]
//最小的年龄
public float minimumAge = 0;
[Tooltip("Maximum age filter of this model selector.")]
//最大的年龄
public float maximumAge = 1000;
[HideInInspector]
//是否使用选择器
public bool activeSelector = false;
// [Tooltip("GUI-Text to display the avatar-scaler debug messages.")]
// public UnityEngine.UI.Text debugText;
// Reference to the dresing menu list title
//穿着菜单标题
private Text dressingMenuTitle;
// Reference to the dresing menu list content
//穿着菜单内容
private RectTransform dressingMenuContent;
// list of instantiated dressing panels
//实例化菜单内容
private List dressingPanels = new List();
//private Rect menuWindowRectangle;
//衣服的名字
private string[] modelNames;
//衣服的图片
private Texture2D[] modelThumbs;
//滚动
private Vector2 scroll;
//选择
private int selected = -1;
//之前的选择
private int prevSelected = -1;
//选择的模型
private GameObject selModel;
//当前的比例因素
private float curScaleFactor = 0f;
//当前的偏移
private float curModelOffset = 0f;
bool isSelcetone = false;
///
/// Sets the model selector to be active or inactive.
/// 将模型选择器设置为活动或非活动。
///
/// If set to true b active.
public void SetActiveSelector(bool bActive)
{
//获取选择
activeSelector = bActive;
//判断穿着是否使用
if (dressingMenu)
{
dressingMenu.gameObject.SetActive(activeSelector);
}
//如果选择和不保持当前的模型
if (!activeSelector && !keepSelectedModel)
{
//摧毁选择的模型
DestroySelectedModel();
}
}
///
/// Gets the selected model.
/// 获取选怎的模型
///
/// The selected model.
public GameObject GetSelectedModel()
{
return selModel;
}
///
/// Destroys the currently selected model.
/// 销毁当前选择的模型
///
public void DestroySelectedModel()
{
//当前选择了模型
if (selModel)
{
//获取模型的骨骼控制器
AvatarController ac = selModel.GetComponent();
//获取kinect
KinectManager km = KinectManager.Instance;
//都不为空
if (ac != null && km != null)
{
//移除骨骼控制器
km.avatarControllers.Remove(ac);
}
//销毁模型
GameObject.Destroy(selModel);
//模型选择为空
selModel = null;
//记录为-1
prevSelected = -1;
}
}
///
/// Selects the next model.
/// 选择下一个模型
///
public void SelectNextModel()
{
//选择数++
selected++;
//大于最大数 归0
if (selected >= numberOfModels)
selected = 0;
//LoadModel(modelNames[selected]);
OnDressingItemSelected(selected);
}
///
/// Selects the previous model.
///
public void SelectPrevModel()
{
selected--;
if (selected < 0)
selected = numberOfModels - 1;
//LoadModel(modelNames[selected]);
OnDressingItemSelected(selected);
}
void Start()
{
// get references to menu title and content
if (dressingMenu)
{
Transform dressingHeaderText = dressingMenu.transform.Find("Header/Text");
if (dressingHeaderText)
{
dressingMenuTitle = dressingHeaderText.gameObject.GetComponent();
}
Transform dressingViewportContent = dressingMenu.transform.Find("Scroll View/Viewport/Content");
if (dressingViewportContent)
{
dressingMenuContent = dressingViewportContent.gameObject.GetComponent();
}
}
// create model names and thumbs
//创建名字的数组和衣服图片的数组
modelNames = new string[numberOfModels];
modelThumbs = new Texture2D[numberOfModels];
//清空链表
dressingPanels.Clear();
// instantiate menu items
//创建菜单的实例
for (int i = 0; i < numberOfModels; i++)
{
//获取名字
modelNames[i] = string.Format("{0:0000}", i);
//获取图片的路径
string previewPath = modelCategory + "/" + modelNames[i] + "/preview.jpg";
//从resources中加载纹理
TextAsset resPreview = Resources.Load(previewPath, typeof(TextAsset)) as TextAsset;
//如果纹理为空
if (resPreview == null)
{
//就加载nopreview.jpg的图片
resPreview = Resources.Load("nopreview.jpg", typeof(TextAsset)) as TextAsset;
}
//if(resPreview != null)
{
modelThumbs[i] = CreatePreviewTexture(resPreview != null ? resPreview.bytes : null);
}
//实例化穿着菜单栏
InstantiateDressingItem(i);
}
// select the 1st item
//默认选择第一个
if (numberOfModels > 0)
{
selected = 0;
}
// set the panel title
//设置菜单栏的名称
if (dressingMenuTitle)
{
dressingMenuTitle.text = modelCategory;
}
// save current scale factors and model offsets
//保存当前规模因素和补偿模型
curScaleFactor = bodyScaleFactor + bodyWidthFactor + armScaleFactor + legScaleFactor;
curModelOffset = verticalOffset + forwardOffset + (applyMuscleLimits ? 1f : 0f);
}
void Update()
{
// check for selection change
//检查选择改变
//能够选择为true 在选择的范围内 之前的选择和选择不同
if (activeSelector && selected >= 0 && selected < modelNames.Length && prevSelected != selected)
{
//获取体感控制器
KinectManager kinectManager = KinectManager.Instance;
//如果体感控制器存在 并且能够单例 能够识别用户
if (kinectManager && kinectManager.IsInitialized () && kinectManager.IsUserDetected(playerIndex))
{
//穿上选择的衣服
OnDressingItemSelected(selected);
}
}
//如果选择的不为空
if (selModel != null)
{
// update model settings as needed
//根据需要更新模型的设置
float curMuscleLimits = applyMuscleLimits ? 1f : 0f;
//当前的偏移-(上下的偏移+前后的偏移+是否使用肌肉的限制)
if (Mathf.Abs(curModelOffset - (verticalOffset + forwardOffset + curMuscleLimits)) >= 0.001f)
{
// update model offsets
//更新模型的偏移
curModelOffset = verticalOffset + forwardOffset + curMuscleLimits;
//获取模型的骨骼控制器
AvatarController ac = selModel.GetComponent();
//模型控制器不为空
if (ac != null)
{
//获取上下的偏移
ac.verticalOffset = verticalOffset;
//获取前后的偏移
ac.forwardOffset = forwardOffset;
//获取肌肉的限制数
ac.applyMuscleLimits = applyMuscleLimits;
}
}
//当前当前的大小因素-(身体的因素+身体宽度的因素+肩膀的因素+腿部的因素)大于0.001
if (Mathf.Abs(curScaleFactor - (bodyScaleFactor + bodyWidthFactor + armScaleFactor + legScaleFactor)) >= 0.001f)
{
// update scale factors
//更新
curScaleFactor = bodyScaleFactor + bodyWidthFactor + armScaleFactor + legScaleFactor;
//获取骨骼的比例
AvatarScaler scaler = selModel.GetComponent();
//不为空的话
if (scaler != null)
{
//获取当前的比例
scaler.continuousScaling = continuousScaling;
scaler.bodyScaleFactor = bodyScaleFactor;
scaler.bodyWidthFactor = bodyWidthFactor;
scaler.armScaleFactor = armScaleFactor;
scaler.legScaleFactor = legScaleFactor;
}
}
}
}
///
/// 创建显示的图片
///
///
///
private Texture2D CreatePreviewTexture(byte[] btImage)
{
Texture2D tex = new Texture2D(4, 4);
//Texture2D tex = new Texture2D(100, 143);
//字节组的图片不为空
if (btImage != null)
{
//加载
tex.LoadImage (btImage);
}
return tex;
}
// instantiates dressing menu item
//实例化着装菜单项
private void InstantiateDressingItem(int i)
{
if (!dressingItemPrefab && i >= 0 && i < numberOfModels)
return;
GameObject dressingItemInstance = Instantiate(dressingItemPrefab);
GameObject dressingImageObj = dressingItemInstance.transform.Find("DressingImagePanel").gameObject;
dressingImageObj.GetComponentInChildren().texture = modelThumbs[i];
if(!string.IsNullOrEmpty(modelNames[i]))
{
EventTrigger trigger = dressingItemInstance.GetComponent();
EventTrigger.Entry entry = new EventTrigger.Entry();
entry.eventID = EventTriggerType.Select;
entry.callback.AddListener ((eventData) => { OnDressingItemSelected(i); });
trigger.triggers.Add(entry);
}
if (dressingMenuContent)
{
dressingItemInstance.transform.SetParent(dressingMenuContent, false);
}
dressingPanels.Add(dressingItemInstance);
}
// invoked when dressing menu-item was clicked
//菜单项的单击时调用
private void OnDressingItemSelected(int i)
{
//在选择的范围呢,并且与之前选择是不一样
if (i >= 0 && i < modelNames.Length && prevSelected != i)
{
//改变参数
prevSelected = selected = i;
//加载选择的模型
LoadDressingModel(modelNames[selected]);
}
}
int count = 0;
public GameObject currenthat;
// sets the selected dressing model as user avatar
//设置所选模型打扮成用户骨骼
private void LoadDressingModel(string modelDir)
{
//设置路径
string modelPath = modelCategory + "/" + modelDir + "/model";
//获取预制体
UnityEngine.Object modelPrefab = Resources.Load(modelPath, typeof(GameObject));
//如果为空
if (modelPrefab == null)
return;
Debug.Log("Model: " + modelPath);
//不为空删除当前的模型
if (selModel != null)
{
if (modelDir != "0001")
{
GameObject.Destroy(selModel);
}
else if(modelDir == "0001")
{
print(isSelcetone);
if (isSelcetone)
{
Destroy(selModel);
}
isSelcetone = true;
}
}
//实例一个新的模型
selModel = (GameObject)GameObject.Instantiate(modelPrefab, Vector3.zero, Quaternion.Euler(0, 180f, 0));
//名字为路径名
selModel.name = "Model" + modelDir;
if (isSelcetone&& modelDir=="0000")
{
Destroy(selModel);
}
//获取骨骼控制器
AvatarController ac = selModel.GetComponent();
//骨骼控制器为空
if (ac == null)
{
//获取当前的骨骼控制器
ac = selModel.AddComponent();
//下标对应
ac.playerIndex = playerIndex;
//镜像使用
ac.mirroredMovement = true;
//允许上下移动
ac.verticalMovement = true;
//获取肌肉的限制度
ac.applyMuscleLimits = applyMuscleLimits;
//获取上下的偏移量
ac.verticalOffset = verticalOffset;
//获取前后的偏移量
ac.forwardOffset = forwardOffset;
//平滑度
ac.smoothFactor = 0f;
}
//将骨骼对准选择的摄像头
ac.posRelativeToCamera = modelRelativeToCamera;
//是否覆盖彩色摄像头
ac.posRelOverlayColor = (foregroundCamera != null);
//获取单例
KinectManager km = KinectManager.Instance;
//ac.Awake();
//如果存在并且具有单例模式
if (km && km.IsInitialized())
{
//获取用户的下标
long userId = km.GetUserIdByIndex(playerIndex);
//下标不等于0
if (userId != 0)
{
//成功的校准用户的位置
ac.SuccessfulCalibration(userId, false);
}
// locate the available avatar controllers
//查找可以使用的体感控制器
MonoBehaviour[] monoScripts = FindObjectsOfType(typeof(MonoBehaviour)) as MonoBehaviour[];
//对kinect的骨骼控制器清空
km.avatarControllers.Clear();
//遍历所有的mono
foreach (MonoBehaviour monoScript in monoScripts)
{
//当前的类是骨骼控制器类 并且正在使用
if ((monoScript is AvatarController) && monoScript.enabled)
{
//获取当前的骨骼控制器
AvatarController avatar = (AvatarController)monoScript;
//添加
km.avatarControllers.Add(avatar);
}
}
}
//获取骨骼尺寸类
AvatarScaler scaler = selModel.GetComponent();
//等于空的情况
if (scaler == null)
{
//添加骨骼尺寸
scaler = selModel.AddComponent();
//获取人物的下标
scaler.playerIndex = playerIndex;
//镜像模式
scaler.mirroredAvatar = true;
//添加参数
scaler.continuousScaling = continuousScaling;
scaler.bodyScaleFactor = bodyScaleFactor;
scaler.bodyWidthFactor = bodyWidthFactor;
scaler.armScaleFactor = armScaleFactor;
scaler.legScaleFactor = legScaleFactor;
}
//获取前景摄像机
scaler.foregroundCamera = foregroundCamera;
//scaler.debugText = debugText;
//scaler.Start();
}
}