diff --git a/Assets/Resources/Animation/WindowEffectError.anim b/Assets/Resources/Animation/WindowEffectError.anim index 956f8f3..16580af 100644 --- a/Assets/Resources/Animation/WindowEffectError.anim +++ b/Assets/Resources/Animation/WindowEffectError.anim @@ -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 diff --git a/Assets/Resources/Animation/headTurnLeft.anim b/Assets/Resources/Animation/headTurnLeft.anim index 63b26f2..26a4be8 100644 --- a/Assets/Resources/Animation/headTurnLeft.anim +++ b/Assets/Resources/Animation/headTurnLeft.anim @@ -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 diff --git a/Assets/Resources/UI/ClearingSettlementUI.prefab b/Assets/Resources/UI/ClearingSettlementUI.prefab new file mode 100644 index 0000000..085bf95 --- /dev/null +++ b/Assets/Resources/UI/ClearingSettlementUI.prefab @@ -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} diff --git a/Assets/Resources/UI/ClearingSettlementUI.prefab.meta b/Assets/Resources/UI/ClearingSettlementUI.prefab.meta new file mode 100644 index 0000000..ed284ae --- /dev/null +++ b/Assets/Resources/UI/ClearingSettlementUI.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 1c317f5b047ffd047a9577a36fbd3cc2 +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/RobotController.cs b/Assets/RobotController.cs index b58ca00..b887e32 100644 --- a/Assets/RobotController.cs +++ b/Assets/RobotController.cs @@ -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() diff --git a/Assets/Scripts/EventManager.cs b/Assets/Scripts/EventManager.cs index a32fa24..72381b3 100644 --- a/Assets/Scripts/EventManager.cs +++ b/Assets/Scripts/EventManager.cs @@ -32,7 +32,7 @@ public class EventManager : MonoSingleton _actionDic[eventName] -= handler; } - public void DispatchEvent(string eventName) + public void Dispatch(string eventName) { if (!_actionDic.ContainsKey(eventName)) return; diff --git a/Assets/Scripts/PoseCheck/ClearingSettlementUI.cs b/Assets/Scripts/PoseCheck/ClearingSettlementUI.cs new file mode 100644 index 0000000..ad6c9a1 --- /dev/null +++ b/Assets/Scripts/PoseCheck/ClearingSettlementUI.cs @@ -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"); + } +} diff --git a/Assets/Scripts/PoseCheck/ClearingSettlementUI.cs.meta b/Assets/Scripts/PoseCheck/ClearingSettlementUI.cs.meta new file mode 100644 index 0000000..cfd143d --- /dev/null +++ b/Assets/Scripts/PoseCheck/ClearingSettlementUI.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8806e03c0fc88604aacf35936e8fe874 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/PoseCheck/GudieAnimationManager.cs b/Assets/Scripts/PoseCheck/GudieAnimationManager.cs index 33b4662..b172d0b 100644 --- a/Assets/Scripts/PoseCheck/GudieAnimationManager.cs +++ b/Assets/Scripts/PoseCheck/GudieAnimationManager.cs @@ -18,7 +18,7 @@ public class GudieAnimationManager : MonoBehaviour public void FrameEstimate() { - EventManager.Instance.DispatchEvent("PoseEstimate"); + EventManager.Instance.Dispatch("PoseEstimate"); } } diff --git a/Assets/Scripts/PoseCheck/MotionCaptureManager.cs b/Assets/Scripts/PoseCheck/MotionCaptureManager.cs index 8305cf0..e9f912e 100644 --- a/Assets/Scripts/PoseCheck/MotionCaptureManager.cs +++ b/Assets/Scripts/PoseCheck/MotionCaptureManager.cs @@ -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.Initialize(); - YogaManager.Instance.Init(); + YogaManager.Instance.InitData(); //动作引导界面 var video = Resources.Load("Video/Action1"); @@ -144,8 +157,8 @@ namespace Yoga _objEstimation = StartCoroutine(ObjectEstimation(img)); _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); } } @@ -183,7 +196,7 @@ namespace Yoga { if (!_webCamTextureToMatHelper.IsPlaying() || !_webCamTextureToMatHelper.DidUpdateThisFrame()) yield break; - + if (_objectDetector == null) yield break; @@ -224,10 +237,10 @@ namespace Yoga if (_voloResult == null) yield break; - + var box = _voloResult[0]; //对人体进行姿态检测 - OpenCVForUnity.CoreModule.Rect rect = new OpenCVForUnity.CoreModule.Rect((int)box[0], (int)box[1], (int)(box[2] - box[0]), (int)(box[3] - box[1])); + OpenCVForUnity.CoreModule.Rect rect = new OpenCVForUnity.CoreModule.Rect((int)box[0], (int)box[1], (int)(box[2] - box[0]), (int)(box[3] - box[1])); Mat personRectImg = new Mat(_bgrMat, rect);//获取人体区域 _personPoints = _openPoseModel.estimate(personRectImg, (float)threshold).toList(); @@ -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); } - - /// /// Raises the destroy event. /// @@ -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(false, null); + return; + } + if (_isCorrectAction) { - //成功 - + EventManager.Instance.Dispatch("ActionSuccess"); + YogaManager.Instance.CurrentSuccessActionCount++; } else { - //失败 + EventManager.Instance.Dispatch("ActionFailed"); } - + YogaManager.Instance.CurrentActionCount++; } } } diff --git a/Assets/Scripts/UI/GuideUI.cs b/Assets/Scripts/UI/GuideUI.cs index 5ba64ba..d17a62b 100644 --- a/Assets/Scripts/UI/GuideUI.cs +++ b/Assets/Scripts/UI/GuideUI.cs @@ -6,8 +6,8 @@ using UnityEngine; public class GuideUI : UIPanelBase { - [HideInInspector] private GameObject _guide; + private Animator _effectAnimator; public GudieAnimationManager GuideMgr => _guide.GetComponent(); private void Awake() @@ -17,11 +17,15 @@ public class GuideUI : UIPanelBase { Debug.LogError("Guide is null"); } + + _effectAnimator = transform.Find("Content").GetComponentInChildren(); } 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 diff --git a/Assets/Scripts/UI/UILoadConfig.cs b/Assets/Scripts/UI/UILoadConfig.cs index 7ac9371..3f087ba 100644 --- a/Assets/Scripts/UI/UILoadConfig.cs +++ b/Assets/Scripts/UI/UILoadConfig.cs @@ -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) diff --git a/Assets/Scripts/UI/UIManager.cs b/Assets/Scripts/UI/UIManager.cs index d5d8ed9..14d4679 100644 --- a/Assets/Scripts/UI/UIManager.cs +++ b/Assets/Scripts/UI/UIManager.cs @@ -5,6 +5,7 @@ using UnityEngine; using System.Linq; using OpenCVForUnity.CoreModule; using UnityEngine.SceneManagement; +using Yoga; public class UIManager : MonoSingleton { @@ -207,4 +208,23 @@ public class UIManager : MonoSingleton { } + + public void CloseUI(UIBase targetUI) + { + if (_panelStack.Count <= 0) + { + return; + } + + targetUI.OnHide(); + targetUI.OnExit(); + //ջƳ + _panelStack = new Stack(_panelStack.Where(ui => ui != targetUI)); + //򿪶ҳ + if (_panelStack.Count > 0) + { + UIBase nextPanel = _panelStack.Peek(); + nextPanel.OnResume(); + } + } } diff --git a/Assets/Scripts/YogaManager.cs b/Assets/Scripts/YogaManager.cs index 644785f..5f1e786 100644 --- a/Assets/Scripts/YogaManager.cs +++ b/Assets/Scripts/YogaManager.cs @@ -27,12 +27,16 @@ public class YogaManager : MonoSingleton public Action 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>> _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 _currPose.ShowHint(); _currActionID = 0; _isInited = true; - - + _currentActionCount = 0; + _currentSuccessActionCount = 0; } public void Dispose() @@ -70,7 +74,7 @@ public class YogaManager : MonoSingleton { if (!_isInited) { - Init(); + InitData(); } Points = points;