using UnityEngine;
using System.Collections;
/// <summary>
/// 类别的选择
/// </summary>
public class CategorySelector : MonoBehaviour, KinectGestures.GestureListenerInterface, CloudFaceListenerInterface
{
[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("Whether to use swipe-left and swipe-right gestures to change the clothing model in the active category.")]
//滑动切换模型
public bool swipeToChangeModel = true;
[Tooltip("Whether to use left and right hand-raise gestures to change the model category.")]
//手上升切换种类
public bool raiseHandToChangeCategory = true;
[Tooltip("Whether to detect user's gender and age, in order to select the suitable model categories.")]
//识别人物的年龄和性别
public bool detectGenderAge = true;
// [Tooltip("Whether to put the clothing model hip and shoulder joints where the user joints are.")]
// public bool fixModelHipsAndShoulders = false;
[Tooltip("GUI-Text used to display information messages.")]
public UnityEngine.UI.Text infoText;
// available model selectors
//可用的模式选择器
private ModelSelector[] allModelSelectors;
//当前选择的类型
private int iCurSelector = -1;
// current model selector
//当前模式选择器
private ModelSelector modelSelector;
// last detected userId;
//最后发现标识;
private long lastUserId = 0;
/// <summary>
/// Gets the active model selector.
/// 得到了现在使用的模式选择器。
/// </summary>
/// <returns>The active model selector.</returns>
public ModelSelector GetActiveModelSelector()
{
return modelSelector;
}
/// <summary>
/// Activate the next model selector.
/// 使用下个模型选择器
/// </summary>
public void ActivateNextModelSelector()
{
//所有的模型选择器的长度
if (allModelSelectors.Length > 0)
{
//如果当前的模型选择器存在
if (modelSelector)
//将模型该为飞活跃的状态
modelSelector.SetActiveSelector(false);
//下标增加
iCurSelector++;
//大于最高数
if (iCurSelector >= allModelSelectors.Length)
//清除
iCurSelector = 0;
//当前的模型选择器为改下标的模型选择器
modelSelector = allModelSelectors [iCurSelector];
//当前选择的模型为活跃的状态
modelSelector.SetActiveSelector(true);
Debug.Log("Category: " + modelSelector.modelCategory);
}
}
/// <summary>
/// Activates the previous model selector.
/// 激活之前的模型选择器
/// </summary>
public void ActivatePrevModelSelector()
{
//如果模型的长度大于0
if (allModelSelectors.Length > 0)
{
//当前模型存在
if (modelSelector)
//转为非活跃的状态
modelSelector.SetActiveSelector(false);
//下标减少
iCurSelector--;
//小于0取最大值
if (iCurSelector < 0)
iCurSelector = allModelSelectors.Length - 1;
//当前的模型为下标的模型选择器
modelSelector = allModelSelectors [iCurSelector];
//当前选择的模型为活跃的状态
modelSelector.SetActiveSelector(true);
Debug.Log("Category: " + modelSelector.modelCategory);
}
}
/// <summary>
/// Refreshes the list of available model selectors.
/// 刷新列表中可用的模式选择器。
/// 根据用户的性别 年龄来选择
/// </summary>
public void RefreshModelSelectorsList(UserGender gender, float age, bool bSelectFirst)
{
//所有的模型选择器不等于空并且长度大于0
if (allModelSelectors != null && allModelSelectors.Length > 0)
{
//如果模型选择器存在
if (modelSelector)
//转化为不活跃的状态
modelSelector.SetActiveSelector(false);
}
// find mono scripts containing model selectors
//找到mono脚本包含模式选择器
//MonoBehaviour[] monoScripts = FindObjectsOfType(typeof(MonoBehaviour)) as MonoBehaviour[];
ModelSelector[] monoScripts = GetComponents<ModelSelector>();
int countEnabled = 0;
//选择的脚本不为空 并且长度大于0
if (monoScripts != null && monoScripts.Length > 0)
{
//foreach(MonoBehaviour monoScript in monoScripts)
//遍历所有的该类的脚本
foreach(ModelSelector monoScript in monoScripts)
{
//if((monoScript is ModelSelector) && monoScript.enabled)
{
//获取该类
ModelSelector modelSel = (ModelSelector)monoScript;
//判断该类是否符合选取的标准
bool genderMatch = gender == UserGender.Unisex || modelSel.modelGender == UserGender.Unisex || modelSel.modelGender == gender;
//判断年龄是否符合范围值
bool ageMatch = age < 0 || (age >= modelSel.minimumAge && age <= modelSel.maximumAge);
//如果都满足
if (modelSel.playerIndex == playerIndex && genderMatch && ageMatch)
//符合数++
countEnabled++;
}
}
}
//创建符合数组的模型选择组
allModelSelectors = new ModelSelector[countEnabled];
//当前的符合数大于0
if (countEnabled > 0)
{
//初始化
int j = 0;
//foreach(MonoBehaviour monoScript in monoScripts)
//遍历所有的选择类型
foreach(ModelSelector monoScript in monoScripts)
{
//if((monoScript is ModelSelector) && monoScript.enabled)
{
//模型选择器实例
ModelSelector modelSel = (ModelSelector)monoScript;
//判断是否符合性别
bool genderMatch = gender == UserGender.Unisex || modelSel.modelGender == UserGender.Unisex || modelSel.modelGender == gender;
//判断是否符合年龄
bool ageMatch = age < 0 || (age >= modelSel.minimumAge && age <= modelSel.maximumAge);
//判断是否符合要求
if (modelSel.playerIndex == playerIndex && genderMatch && ageMatch)
{
//符合的情况加入该模型选择器
allModelSelectors[j] = modelSel;
//该模型选择转为非活跃的状态
modelSel.SetActiveSelector(false);
//自增
j++;
}
}
}
}
//判断长度并且判断是否选择第一个
if (allModelSelectors.Length > 0 && bSelectFirst)
{
//当前选择的为第一个
iCurSelector = 0;
//选择第一个模型组
modelSelector = allModelSelectors[iCurSelector];
//转为活跃的状态
modelSelector.SetActiveSelector(true);
Debug.Log("Category: " + modelSelector.modelCategory);
}
}
/
/// <summary>
/// 厨初始化
/// </summary>
void Start ()
{
// enable or disable the face detector
//启用或禁用云人脸面对探测器
if (CloudFaceDetector.Instance)
{
//云检测识别
CloudFaceDetector.Instance.gameObject.SetActive(detectGenderAge);
}
// create the initial model selectors list
//创建初始模型选择器列表
RefreshModelSelectorsList(UserGender.Unisex, -1f, !detectGenderAge);
// check for KM and hint for calibration pose
//检查体感器和提示校正姿势
KinectManager manager = KinectManager.Instance;
//当前的体感器存在,并且单例有使用
if (manager && manager.IsInitialized ())
{
//提示信息是否不为空当前的状态是否为Tpose状态
if(infoText != null && manager.playerCalibrationPose == KinectGestures.Gestures.Tpose)
{
infoText.text = "Please stand in T-pose for calibration.";
}
}
else
{
//不存在
string sMessage = "KinectManager is missing or not initialized";
Debug.LogError(sMessage);
if(infoText != null)
{
infoText.text = sMessage;
}
}
}
/// <summary>
/// 更新
/// </summary>
void Update()
{
//体感器实例
KinectManager manager = KinectManager.Instance;
//判断当前的体感器是否存在 并且能够识别
if(manager && manager.IsInitialized ())
{
//获取该人物id
long userId = manager.GetUserIdByIndex(playerIndex);
//该用户的id不为空
if (userId != 0)
{
// MonoBehaviour[] monoScripts = FindObjectsOfType(typeof(MonoBehaviour)) as MonoBehaviour[];
// foreach(MonoBehaviour monoScript in monoScripts)
// {
if(typeof(AvatarScaler).IsAssignableFrom(monoScript.GetType()) &&
monoScript.enabled)
// if((monoScript is AvatarScaler) && monoScript.enabled)
// {
// AvatarScaler scaler = (AvatarScaler)monoScript;
//
// if(scaler.scalerInited && scaler.playerIndex == playerIndex &&
// scaler.currentUserId != userId)
// {
// scaler.currentUserId = userId;
//
// if(userId != 0)
// {
// scaler.GetUserBodySize(true, true, true);
//
// if(fixModelHipsAndShoulders)
// scaler.FixJointsBeforeScale();
// scaler.ScaleAvatar(0f);
// }
// }
// }
// }
//最后一个的用户ID和改用户的ID不同
if (lastUserId != userId)
{
//提示文本不为空
if(infoText != null)
{
//发送信息 左右挥动
string sMessage = swipeToChangeModel && modelSelector ? "Swipe left or right to change clothing." : string.Empty;
//上下切换种类
if (raiseHandToChangeCategory && allModelSelectors.Length > 1)
sMessage += " Raise hand to change category.";
infoText.text = sMessage;
}
//将该用户的ID复制给最后的用户ID
lastUserId = userId;
}
}
//如果该用户的ID为空 且用户id不等与最后的用户的ID
if(userId == 0 && userId != lastUserId)
{
//最后的用户ID等与用id
lastUserId = userId;
// destroy currently loaded models
//破坏当前加载模型
foreach (ModelSelector modSelector in allModelSelectors)
{
//摧毁所有选择的模型
modSelector.DestroySelectedModel();
}
//文本输出
if(infoText != null && manager.playerCalibrationPose == KinectGestures.Gestures.Tpose)
{
infoText.text = "Please stand in T-pose for calibration.";
}
}
}
}
/// <summary>
/// 用户识别
/// </summary>
/// <param name="userId"></param>
/// <param name="userIndex"></param>
public void UserDetected(long userId, int userIndex)
{
//获取kinectmanager实例
KinectManager manager = KinectManager.Instance;
if(!manager || (userIndex != playerIndex))
return;
//当用户举手换衣服的种类
if (raiseHandToChangeCategory)
{
//判断当前是使用的左手还是右手
manager.DetectGesture(userId, KinectGestures.Gestures.RaiseRightHand);
manager.DetectGesture(userId, KinectGestures.Gestures.RaiseLeftHand);
}
//当用户滑动
if (swipeToChangeModel)
{
//判断当前是左滑动还是右滑动
manager.DetectGesture(userId, KinectGestures.Gestures.SwipeLeft);
manager.DetectGesture(userId, KinectGestures.Gestures.SwipeRight);
}
}
/// <summary>
///
/// </summary>
/// <param name="userId"></param>
/// <param name="userIndex"></param>
public void UserLost(long userId, int userIndex)
{
if(userIndex != playerIndex)
return;
}
public void GestureInProgress(long userId, int userIndex, KinectGestures.Gestures gesture, float progress, KinectInterop.JointType joint, Vector3 screenPos)
{
// nothing to do here
}
/// <summary>
/// 判断该手势是否完成
/// </summary>
/// <param name="userId"></param>
/// <param name="userIndex"></param>
/// <param name="gesture"></param>
/// <param name="joint"></param>
/// <param name="screenPos"></param>
/// <returns></returns>
public bool GestureCompleted(long userId, int userIndex, KinectGestures.Gestures gesture, KinectInterop.JointType joint, Vector3 screenPos)
{
if(userIndex != playerIndex)
return false;
//判断手势
switch (gesture)
{
//该手势是右手上举
case KinectGestures.Gestures.RaiseRightHand:
//选取下一个类型
ActivateNextModelSelector();
break;
//该手势是左手上举
case KinectGestures.Gestures.RaiseLeftHand:
ActivatePrevModelSelector();
break;
//左滑动
case KinectGestures.Gestures.SwipeLeft:
//选取下一个模型
if (modelSelector)
{
modelSelector.SelectNextModel();
}
break;
//右滑动
case KinectGestures.Gestures.SwipeRight:
//选取上一个模型
if (modelSelector)
{
modelSelector.SelectPrevModel();
}
break;
}
return true;
}
/// <summary>
/// 手势清除
/// </summary>
/// <param name="userId"></param>
/// <param name="userIndex"></param>
/// <param name="gesture"></param>
/// <param name="joint"></param>
/// <returns></returns>
public bool GestureCancelled(long userId, int userIndex, KinectGestures.Gestures gesture, KinectInterop.JointType joint)
{
//如果该用户的下标不等于 返回 false
if(userIndex != playerIndex)
return false;
return true;
}
// invoked by CloudFaceDetector, when data for the player was detected
//调用CloudFaceDetector,当检测到玩家的数据
public void UserFaceDetected(int userIndex, UserGender gender, float age, float smile)
{
//当前的用户的下标是否一致
if(userIndex != playerIndex)
return;
// refresh the model selectors, depending on the gender and age
//刷新模式选择器,根据性别和年龄
RefreshModelSelectorsList(gender, age, true);
}
}