Block input on first loop
This commit is contained in:
@@ -1,3 +1,5 @@
|
|||||||
|
using System.Collections;
|
||||||
|
using System.Linq;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using Pixelplacement;
|
using Pixelplacement;
|
||||||
using Minigames.DivingForPictures;
|
using Minigames.DivingForPictures;
|
||||||
@@ -10,17 +12,18 @@ public class DivingTutorial : MonoBehaviour, ITouchInputConsumer
|
|||||||
public DivingGameManager divingGameManager;
|
public DivingGameManager divingGameManager;
|
||||||
public bool playTutorial;
|
public bool playTutorial;
|
||||||
|
|
||||||
|
// gating for input until current state's animation finishes first loop
|
||||||
|
private bool canAcceptInput = false;
|
||||||
|
private Coroutine waitLoopCoroutine;
|
||||||
|
|
||||||
// Start is called once before the first execution of Update after the MonoBehaviour is created
|
// Start is called once before the first execution of Update after the MonoBehaviour is created
|
||||||
void Start()
|
void Start()
|
||||||
{
|
{
|
||||||
if (playTutorial==true)
|
if (playTutorial == true)
|
||||||
{
|
{
|
||||||
InitializeTutorial();
|
InitializeTutorial();
|
||||||
}
|
}
|
||||||
else { RemoveTutorial(); }
|
else { RemoveTutorial(); }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void InitializeTutorial()
|
void InitializeTutorial()
|
||||||
@@ -30,19 +33,35 @@ public class DivingTutorial : MonoBehaviour, ITouchInputConsumer
|
|||||||
InputManager.Instance.RegisterOverrideConsumer(this);
|
InputManager.Instance.RegisterOverrideConsumer(this);
|
||||||
stateMachine.OnLastStateExited.AddListener(RemoveTutorial);
|
stateMachine.OnLastStateExited.AddListener(RemoveTutorial);
|
||||||
|
|
||||||
|
// prepare gating for the initial active state
|
||||||
|
SetupInputGateForCurrentState();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoveTutorial()
|
void RemoveTutorial()
|
||||||
{
|
{
|
||||||
Debug.Log("Remove me!");
|
Debug.Log("Remove me!");
|
||||||
Destroy(gameObject);
|
if (waitLoopCoroutine != null)
|
||||||
|
{
|
||||||
|
StopCoroutine(waitLoopCoroutine);
|
||||||
|
waitLoopCoroutine = null;
|
||||||
|
}
|
||||||
InputManager.Instance.UnregisterOverrideConsumer(this);
|
InputManager.Instance.UnregisterOverrideConsumer(this);
|
||||||
divingGameManager.DoResume();
|
divingGameManager.DoResume();
|
||||||
|
Destroy(gameObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnTap(Vector2 position)
|
public void OnTap(Vector2 position)
|
||||||
{
|
{
|
||||||
|
if (!canAcceptInput) return; // block taps until allowed
|
||||||
|
|
||||||
|
// consume this tap and immediately block further taps
|
||||||
|
canAcceptInput = false;
|
||||||
|
|
||||||
|
// move to next state
|
||||||
stateMachine.Next(true);
|
stateMachine.Next(true);
|
||||||
|
|
||||||
|
// after the state changes, set up gating for the new active state's animation
|
||||||
|
SetupInputGateForCurrentState();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnHoldStart(Vector2 position)
|
public void OnHoldStart(Vector2 position)
|
||||||
@@ -59,4 +78,98 @@ public class DivingTutorial : MonoBehaviour, ITouchInputConsumer
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void SetupInputGateForCurrentState()
|
||||||
|
{
|
||||||
|
if (waitLoopCoroutine != null)
|
||||||
|
{
|
||||||
|
StopCoroutine(waitLoopCoroutine);
|
||||||
|
waitLoopCoroutine = null;
|
||||||
|
}
|
||||||
|
waitLoopCoroutine = StartCoroutine(WaitForFirstLoopOnActiveState());
|
||||||
|
}
|
||||||
|
|
||||||
|
private IEnumerator WaitForFirstLoopOnActiveState()
|
||||||
|
{
|
||||||
|
// wait a frame to ensure StateMachine has activated the correct state GameObject
|
||||||
|
yield return null;
|
||||||
|
|
||||||
|
// find the active child under the StateMachine (the current state)
|
||||||
|
Transform smTransform = stateMachine != null ? stateMachine.transform : transform;
|
||||||
|
Transform activeState = null;
|
||||||
|
for (int i = 0; i < smTransform.childCount; i++)
|
||||||
|
{
|
||||||
|
var child = smTransform.GetChild(i);
|
||||||
|
if (child.gameObject.activeInHierarchy)
|
||||||
|
{
|
||||||
|
activeState = child;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (activeState == null)
|
||||||
|
{
|
||||||
|
// if we can't find an active state, fail open: allow input
|
||||||
|
canAcceptInput = true;
|
||||||
|
yield break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// look for a legacy Animation component on the active state
|
||||||
|
var anim = activeState.GetComponent<Animation>();
|
||||||
|
if (anim == null)
|
||||||
|
{
|
||||||
|
// no animation to wait for; allow input immediately
|
||||||
|
canAcceptInput = true;
|
||||||
|
yield break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// determine a clip/state to observe
|
||||||
|
string clipName = anim.clip != null ? anim.clip.name : null;
|
||||||
|
AnimationState observedState = null;
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(clipName))
|
||||||
|
{
|
||||||
|
observedState = anim[clipName];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// fallback: take the first enabled state in the Animation
|
||||||
|
foreach (AnimationState st in anim)
|
||||||
|
{
|
||||||
|
observedState = st;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (observedState == null)
|
||||||
|
{
|
||||||
|
// nothing to observe; allow input
|
||||||
|
canAcceptInput = true;
|
||||||
|
yield break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// wait until the animation starts playing the observed clip
|
||||||
|
float safetyTimer = 0f;
|
||||||
|
while (anim.isActiveAndEnabled && activeState.gameObject.activeInHierarchy && !anim.IsPlaying(observedState.name) && safetyTimer < 2f)
|
||||||
|
{
|
||||||
|
safetyTimer += Time.deltaTime;
|
||||||
|
yield return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// wait until the first loop completes (normalizedTime >= 1)
|
||||||
|
while (anim.isActiveAndEnabled && activeState.gameObject.activeInHierarchy)
|
||||||
|
{
|
||||||
|
// if state changed (not playing anymore), allow input to avoid deadlock
|
||||||
|
if (!anim.IsPlaying(observedState.name)) break;
|
||||||
|
|
||||||
|
if (observedState.normalizedTime >= 1f)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
yield return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
canAcceptInput = true;
|
||||||
|
waitLoopCoroutine = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user