动作检测结算界面更新

This commit is contained in:
terric 2023-11-07 23:28:19 +08:00
parent edfb397ac4
commit f6c45303ad
14 changed files with 251 additions and 26 deletions

View File

@ -201,7 +201,7 @@ AnimationClip:
m_Level: 0
m_CycleOffset: 0
m_HasAdditiveReferencePose: 0
m_LoopTime: 1
m_LoopTime: 0
m_LoopBlend: 0
m_LoopBlendOrientation: 0
m_LoopBlendPositionY: 0

View File

@ -24295,7 +24295,7 @@ AnimationClip:
floatParameter: 0
intParameter: 0
messageOptions: 0
- time: 6.3333335
- time: 6.1666665
functionName: CheckHeadTurnLeft
data:
objectReferenceParameter: {fileID: 0}
@ -24309,10 +24309,17 @@ AnimationClip:
floatParameter: 0
intParameter: 0
messageOptions: 0
- time: 6.6666665
- time: 6.8333335
functionName: CheckHeadTurnLeft
data:
objectReferenceParameter: {fileID: 0}
floatParameter: 0
intParameter: 0
messageOptions: 0
- time: 7
functionName: FinishCurrentActionCheck
data:
objectReferenceParameter: {fileID: 0}
floatParameter: 0
intParameter: 0
messageOptions: 0

View File

@ -0,0 +1,122 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &2741035673910363012
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 5126881112078021239}
- component: {fileID: 3856882301601416915}
- component: {fileID: 3610759867344957577}
- component: {fileID: 8711614252624484816}
m_Layer: 5
m_Name: ClearingSettlementUI
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &5126881112078021239
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2741035673910363012}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 6891999240067574262}
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 100, y: 100}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!95 &3856882301601416915
Animator:
serializedVersion: 7
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2741035673910363012}
m_Enabled: 1
m_Avatar: {fileID: 0}
m_Controller: {fileID: 9100000, guid: 12ae8ac8969c0da4aba2b898164f1b12, type: 2}
m_CullingMode: 0
m_UpdateMode: 0
m_ApplyRootMotion: 0
m_LinearVelocityBlending: 0
m_StabilizeFeet: 0
m_AnimatePhysics: 0
m_WarningMessage:
m_HasTransformHierarchy: 1
m_AllowConstantClipSamplingOptimization: 1
m_KeepAnimatorStateOnDisable: 0
m_WriteDefaultValuesOnDisable: 0
--- !u!225 &3610759867344957577
CanvasGroup:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2741035673910363012}
m_Enabled: 1
m_Alpha: 1
m_Interactable: 1
m_BlocksRaycasts: 1
m_IgnoreParentGroups: 0
--- !u!114 &8711614252624484816
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2741035673910363012}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 8806e03c0fc88604aacf35936e8fe874, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!1 &6838756836509648688
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 6891999240067574262}
m_Layer: 5
m_Name: Contant
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &6891999240067574262
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 6838756836509648688}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 5126881112078021239}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 100, y: 100}
m_Pivot: {x: 0.5, y: 0.5}

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 1c317f5b047ffd047a9577a36fbd3cc2
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -7,12 +7,12 @@ public class RobotController : MonoBehaviour
{
public void CheckHeadTurnLeft()
{
MotionCaptureManager.Instance.ScoreUpdate();
EventManager.Instance.Dispatch("EstimateAction", AvatarAction.HeadTurnLeft);
}
public void FinishCurrentActionCheck()
{
MotionCaptureManager.Instance.ScoreUpdate();
EventManager.Instance.Dispatch("ScoreUpdate");
}
public void CheckHeadTurnRight()

View File

@ -32,7 +32,7 @@ public class EventManager : MonoSingleton<EventManager>
_actionDic[eventName] -= handler;
}
public void DispatchEvent(string eventName)
public void Dispatch(string eventName)
{
if (!_actionDic.ContainsKey(eventName))
return;

View File

@ -0,0 +1,15 @@

public class ClearingSettlementUI : UIPopupBase
{
public override void Init(object[] pageData)
{
base.Init(pageData);
//todo 成果展示
}
public void OnClickOK()
{
UIManager.Instance.CloseCurrent();
LoadingManager.Instance.Load("Boot");
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8806e03c0fc88604aacf35936e8fe874
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -18,7 +18,7 @@ public class GudieAnimationManager : MonoBehaviour
public void FrameEstimate()
{
EventManager.Instance.DispatchEvent("PoseEstimate");
EventManager.Instance.Dispatch("PoseEstimate");
}
}

View File

@ -61,8 +61,21 @@ namespace Yoga
private void OnEnable()
{
EventManager.Instance.AddEventListener("StartMotionCapture", OnStartMotionCapture);
EventManager.Instance.AddEventListener("EstimateAction", EstimateAction);
EventManager.Instance.AddEventListener("ScoreUpdate", ScoreUpdate);
}
private void OnDisable()
{
EventManager.Instance.RemoveEventListener("StartMotionCapture", OnStartMotionCapture);
EventManager.Instance.RemoveEventListener("EstimateAction", EstimateAction);
EventManager.Instance.RemoveEventListener("ScoreUpdate", ScoreUpdate);
}
private void EstimateAction()
{
//检测动作
}
private void OnStartMotionCapture()
{
@ -78,7 +91,7 @@ namespace Yoga
_webCamTextureToMatHelper = gameObject.GetComponent<WebCamTextureToMatHelper>();
_webCamTextureToMatHelper.Initialize();
YogaManager.Instance.Init();
YogaManager.Instance.InitData();
//动作引导界面
var video = Resources.Load<VideoClip>("Video/Action1");
@ -145,7 +158,7 @@ namespace Yoga
_involkCDTime = 0;
}
//#if DEBUG_MODE && UNITY_EDITOR
//#if DEBUG_MODE && UNITY_EDITOR
if (_net == null)
{
Imgproc.putText(img, "model file is not loaded.", new Point(5, img.rows() - 30), Imgproc.FONT_HERSHEY_SIMPLEX, 0.7, new Scalar(255, 255, 255), 2, Imgproc.LINE_AA, false);
@ -174,7 +187,7 @@ namespace Yoga
Imgproc.ellipse(img, points[idTo], new Size(3, 3), 0, 0, 360, new Scalar(0, 0, 255), Core.FILLED);
}
}
//#endif
//#endif
Utils.matToTexture2D(img, texture);
}
}
@ -248,7 +261,7 @@ namespace Yoga
}
private bool CheckResults(float[] box, float[] confidence, float[] classID , Mat rgbaMat)
private bool CheckResults(float[] box, float[] confidence, float[] classID, Mat rgbaMat)
{
if ((int)classID[0] != 0 || confidence[0] < 0.8f) //只检测人体且置信度大于80%
return false;
@ -295,8 +308,6 @@ namespace Yoga
Imgproc.putText(image, label, new Point(left, top), Imgproc.FONT_HERSHEY_SIMPLEX, 0.5, Scalar.all(255), 1, Imgproc.LINE_AA);
}
/// <summary>
/// Raises the destroy event.
/// </summary>
@ -369,18 +380,30 @@ namespace Yoga
}
private bool _isCorrectAction = false;
private int _maxActionCount = 3;
public void ScoreUpdate()
{
//如果达到最大数,则停止检测,跳转到下一个动作/下一个动作引导/奖励界面
if (YogaManager.Instance.CurrentActionCount >= _maxActionCount)
{
//停止检测
_isOnCamCapture = false;
//跳转到下一个动作/下一个动作引导/奖励界面
UIManager.Instance.ShowPanel<ClearingSettlementUI>(false, null);
return;
}
if (_isCorrectAction)
{
//成功
EventManager.Instance.Dispatch("ActionSuccess");
YogaManager.Instance.CurrentSuccessActionCount++;
}
else
{
//失败
EventManager.Instance.Dispatch("ActionFailed");
}
YogaManager.Instance.CurrentActionCount++;
}
}
}

View File

@ -6,8 +6,8 @@ using UnityEngine;
public class GuideUI : UIPanelBase
{
[HideInInspector]
private GameObject _guide;
private Animator _effectAnimator;
public GudieAnimationManager GuideMgr => _guide.GetComponent<GudieAnimationManager>();
private void Awake()
@ -17,11 +17,15 @@ public class GuideUI : UIPanelBase
{
Debug.LogError("Guide is null");
}
_effectAnimator = transform.Find("Content").GetComponentInChildren<Animator>();
}
private void OnEnable()
{
EventManager.Instance.AddEventListener("PlayAnimation", PlayAnimation);
EventManager.Instance.AddEventListener("ActionSuccess", ShowSuccessEffect);
EventManager.Instance.AddEventListener("ActionFailed", ShowFailEffect);
}
@ -29,6 +33,8 @@ public class GuideUI : UIPanelBase
private void OnDisable()
{
EventManager.Instance.RemoveEventListener("PlayAnimation", PlayAnimation);
EventManager.Instance.RemoveEventListener("ActionSuccess", ShowSuccessEffect);
EventManager.Instance.RemoveEventListener("ActionFailed", ShowFailEffect);
}
#region Event Func
@ -55,6 +61,15 @@ public class GuideUI : UIPanelBase
}
}
private void ShowFailEffect()
{
_effectAnimator.Play("WindowEffectError", 0, 0f);
}
private void ShowSuccessEffect()
{
_effectAnimator.Play("WindowEffectCorrect", 0, 0f);
}
#endregion

View File

@ -12,6 +12,7 @@ public static class UILoadConfig
{ "ActionListUIPanel" , "UI/ActionListUI" },
{ "ActionGuideVideoPanel" , "UI/ActionGuideVideoPanel" },
{ "GuideUI" , "UI/GuideUI" },
{ "ClearingSettlementUI" , "UI/ClearingSettlementUI" },
};
public static string GetPath(string typeName)

View File

@ -5,6 +5,7 @@ using UnityEngine;
using System.Linq;
using OpenCVForUnity.CoreModule;
using UnityEngine.SceneManagement;
using Yoga;
public class UIManager : MonoSingleton<UIManager>
{
@ -207,4 +208,23 @@ public class UIManager : MonoSingleton<UIManager>
{
}
public void CloseUI(UIBase targetUI)
{
if (_panelStack.Count <= 0)
{
return;
}
targetUI.OnHide();
targetUI.OnExit();
//从栈中移除
_panelStack = new Stack<UIBase>(_panelStack.Where(ui => ui != targetUI));
//打开顶层页面
if (_panelStack.Count > 0)
{
UIBase nextPanel = _panelStack.Peek();
nextPanel.OnResume();
}
}
}

View File

@ -27,12 +27,16 @@ public class YogaManager : MonoSingleton<YogaManager>
public Action<string> ShowHint { get; internal set; }
public int ActionIndex { get; internal set; }
public int CurrentActionCount { get => _currentActionCount; internal set => _currentActionCount = value; }
public int CurrentSuccessActionCount { get => _currentSuccessActionCount; internal set => _currentSuccessActionCount = value; }
//创建帧数据缓存
private Dictionary<int, List<List<Point>>> _framePoints = new (); // actionID, frameID, points
private int _currActionID;
private int _currentActionCount;
private int _currentSuccessActionCount;
public void Init()
public void InitData()
{
_poseChecks.AddFirst(new IsReady(ModelType.OpenPose));
_poseChecks.AddLast(new HeadTurnLeft(ModelType.OpenPose));
@ -44,8 +48,8 @@ public class YogaManager : MonoSingleton<YogaManager>
_currPose.ShowHint();
_currActionID = 0;
_isInited = true;
_currentActionCount = 0;
_currentSuccessActionCount = 0;
}
public void Dispose()
@ -70,7 +74,7 @@ public class YogaManager : MonoSingleton<YogaManager>
{
if (!_isInited)
{
Init();
InitData();
}
Points = points;