diff --git a/Assets/KSH/TutorialManager.prefab b/Assets/KSH/TutorialManager.prefab new file mode 100644 index 00000000..080a8508 --- /dev/null +++ b/Assets/KSH/TutorialManager.prefab @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:932016035940d366bd2d239f74bf3b8585d38d05edd6ec2fae3c17fc4462de4f +size 1549 diff --git a/Assets/KSH/TutorialManager.prefab.meta b/Assets/KSH/TutorialManager.prefab.meta new file mode 100644 index 00000000..45d09b2b --- /dev/null +++ b/Assets/KSH/TutorialManager.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: cb1b75d7494cad14fa95ac97aa0c8f74 +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/LIN/Scripts/Tutorial/TutorialManager.cs b/Assets/LIN/Scripts/Tutorial/TutorialManager.cs index 0fef1105..5546e9d7 100644 --- a/Assets/LIN/Scripts/Tutorial/TutorialManager.cs +++ b/Assets/LIN/Scripts/Tutorial/TutorialManager.cs @@ -24,10 +24,6 @@ public class TutorialManager : MonoBehaviour private Canvas overlayCanvas; // RectTransformUtility를 위한 Canvas private Action onTutorialComplete; - public void Start( ) - { - StartTutorial(null); - } public void StartTutorial(Action onTutorialEnd, int panelIndex = 0) { if(parentCanvas == null) @@ -45,9 +41,9 @@ public class TutorialManager : MonoBehaviour if (_tutorialPanelController != null) { onTutorialComplete = onTutorialEnd; - overlay.alpha = 1f; - overlay.blocksRaycasts = true; - RunStep(firstStep); + overlay.alpha = 1f; + overlay.blocksRaycasts = true; + RunStep(firstStep); } else Debug.Log("패널 생성 실패, 튜토리얼 진행이 불가능합니다."); } @@ -97,15 +93,10 @@ public class TutorialManager : MonoBehaviour if (RectTransformUtility.RectangleContainsScreenPoint( targetRt, screenPos, overlayCanvas.worldCamera)) { - Debug.Log("타겟 터치"); targetRt = null; _tutorialPanelController.HideTouchTarget(step.touchTargetIndex); done = true; } - else - { - Debug.Log("타겟이 아닌 곳 터치"); - } } } diff --git a/Assets/LIN/Scripts/UI/InteractionAnimationPanelController.cs b/Assets/LIN/Scripts/UI/InteractionAnimationPanelController.cs index db6d281f..ab58f281 100644 --- a/Assets/LIN/Scripts/UI/InteractionAnimationPanelController.cs +++ b/Assets/LIN/Scripts/UI/InteractionAnimationPanelController.cs @@ -91,7 +91,7 @@ public class InteractionAnimationPanelController : MonoBehaviour /// 패널이 2초후 자동으로 닫히거나 터치시 닫히도록 합니다. /// /// - private IEnumerator AutoHidePanel(ActionType actionType) + private IEnumerator AutoHidePanel(ActionType actionType, bool isTutorial = false) { float startTime = Time.time; while (Time.time - startTime < animationDuration) @@ -107,7 +107,7 @@ public class InteractionAnimationPanelController : MonoBehaviour GameManager.Instance.StopInteractionSound(actionType); //패널 닫고 애니메이션 null처리 - HidePanel(); + HidePanel(isTutorial); _autoHideCoroutine = null; if (actionType == ActionType.Housework) @@ -121,7 +121,7 @@ public class InteractionAnimationPanelController : MonoBehaviour } } - private void HidePanel() + private void HidePanel(bool isTutorial = false) { panel.SetActive(false); @@ -136,16 +136,19 @@ public class InteractionAnimationPanelController : MonoBehaviour StopCoroutine(_autoHideCoroutine); _autoHideCoroutine = null; } - + if (_isAbsenceToday) // 결근한 경우 { PlayerStats.Instance.PerformAbsent(); return; } - - // 패널 닫히고 결근 체크, 상호작용 패널과 결근 엔딩 채팅창이 겹치지 않기 위함 - PlayerStats.Instance.CheckAbsent(); - PlayerStats.Instance.ShowBubble(); + + if (!isTutorial) // 튜토리얼 시 결근과 말풍선 오류로 인해 조건문 추가 + { + // 패널 닫히고 결근 체크, 상호작용 패널과 결근 엔딩 채팅창이 겹치지 않기 위함 + PlayerStats.Instance.CheckAbsent(); + PlayerStats.Instance.ShowBubble(); + } } public void TutorialSleepAnimation() @@ -153,7 +156,19 @@ public class InteractionAnimationPanelController : MonoBehaviour _parentCanvas = FindObjectOfType(typeof(Canvas)) as Canvas; HousingConstants.interactions.TryGetValue(ActionType.Sleep, out var interactionTexts); - ShowAnimationPanel(ActionType.Sleep, interactionTexts.AnimationText); + + // 1) 패널 활성화 + panel.SetActive(true); + // 2) 기존 코루틴 정리 + if (_textAnimCoroutine != null) StopCoroutine(_textAnimCoroutine); + if (_autoHideCoroutine != null) StopCoroutine(_autoHideCoroutine); + + // 3) 텍스트 및 애니메이션 세팅 + doingText.text = interactionTexts.AnimationText; + animator.Play("Sleep"); + + _textAnimCoroutine = StartCoroutine(TextDotsAnimation()); + _autoHideCoroutine = StartCoroutine(AutoHidePanel(ActionType.Sleep, true)); } } \ No newline at end of file diff --git a/Assets/LYM/Scripts/MainUIPanelController.cs b/Assets/LYM/Scripts/MainUIPanelController.cs index 4109a5cc..ddaf0f3e 100644 --- a/Assets/LYM/Scripts/MainUIPanelController.cs +++ b/Assets/LYM/Scripts/MainUIPanelController.cs @@ -8,7 +8,7 @@ public class MainUIPanelController : MonoBehaviour public void OnClickStartButton() { - GameManager.Instance.ChangeToHomeScene(); + GameManager.Instance.ChangeToHomeScene(true); } public void OnClickSettingsButton() diff --git a/Assets/Scripts/Common/Dialogue/ChatWindowController.cs b/Assets/Scripts/Common/Dialogue/ChatWindowController.cs index 8e4c61be..43efa235 100644 --- a/Assets/Scripts/Common/Dialogue/ChatWindowController.cs +++ b/Assets/Scripts/Common/Dialogue/ChatWindowController.cs @@ -54,6 +54,8 @@ public class ChatWindowController : MonoBehaviour, IPointerClickHandler public delegate void OnComplete(); public OnComplete onComplete; + private bool isEnded; + private bool isTuto; private FairyDialogueManager _dialogueManager; @@ -65,12 +67,21 @@ public class ChatWindowController : MonoBehaviour, IPointerClickHandler private void Start() { + isEnded = false; + isTuto = false; + _dialogueManager = new FairyDialogueManager(this); - /*onComplete = () => { - // 대화문 종료 call back - Debug.Log("대화가 완료되었습니다."); - };*/ + onComplete = () => { + if (isTuto) + { + isTuto = false; + StartCoroutine(GameManager.Instance.StartTutorialCoroutine()); + } + + if (isEnded) + GameManager.Instance.ChangeToMainScene(); + }; } // 외부 호출용 함수 (대화 시작) @@ -78,6 +89,12 @@ public class ChatWindowController : MonoBehaviour, IPointerClickHandler { _dialogueManager.SetGamePhase(phase); + if (phase == GamePhase.End || phase == GamePhase.FailEnd || phase == GamePhase.ZeroEnd) + isEnded = true; + + if (phase == GamePhase.Intro) + isTuto = true; + // Gameplay 상태라면 랜덤 대화 출력 if (phase == GamePhase.Gameplay) _dialogueManager.ShowRandomGameplayDialogue(); } @@ -139,7 +156,6 @@ public class ChatWindowController : MonoBehaviour, IPointerClickHandler if (_inputQueue.Count == 0) { HideWindow(); - onComplete?.Invoke(); return; } @@ -200,6 +216,9 @@ public class ChatWindowController : MonoBehaviour, IPointerClickHandler //대화창 클릭 시 호출 함수 public void OnPointerClick(PointerEventData eventData) { + if (!chatWindowObject.activeSelf) // 실제론 대화창이 off 상태인데 호출되는 상황 방지 + return; + if (_typingCoroutine != null) { StopCoroutine(_typingCoroutine); diff --git a/Assets/Scripts/Common/GameManager.cs b/Assets/Scripts/Common/GameManager.cs index 15870731..2cd7a8e3 100644 --- a/Assets/Scripts/Common/GameManager.cs +++ b/Assets/Scripts/Common/GameManager.cs @@ -26,6 +26,8 @@ public partial class GameManager : Singleton,ISaveable private PanelManager panelManager; public PanelManager PanelManager => panelManager; + private TutorialManager tutorialManager; + private void Start() { // 오디오 초기화 @@ -91,6 +93,11 @@ public partial class GameManager : Singleton,ISaveable TriggerTimeEnding(); } } + + public void ChangeToMainScene() + { + SceneManager.LoadScene("Main"); + } public void ChangeToGameScene() { @@ -99,14 +106,28 @@ public partial class GameManager : Singleton,ISaveable HandleSceneAudio("Dungeon"); } - public void ChangeToHomeScene() + public void ChangeToHomeScene(bool isNewStart = false) { SceneManager.LoadScene("ReHousing"); // Home Scene HandleSceneAudio("Housing"); + if(isNewStart) // 아예 메인에서 시작 시 튜토리얼 출력 + StartNPCDialogue(GamePhase.Intro); // StartCoroutine(StartTutorialCoroutine()); + if (tryStageCount >= 3) FailEnd(); // 엔딩 } + public IEnumerator StartTutorialCoroutine() + { + yield return new WaitForSeconds(0.5f); + + if(tutorialManager == null) + tutorialManager = FindObjectOfType(); + + PlayerStats.Instance.HideBubble(); + tutorialManager.StartTutorial(() => PlayerStats.Instance.ShowBubble()); + } + // TODO: Open Setting Panel 등 Panel 처리 protected override void OnSceneLoaded(Scene scene, LoadSceneMode mode) diff --git a/Assets/Scripts/Common/GameUtility/EndingLogic.cs b/Assets/Scripts/Common/GameUtility/EndingLogic.cs index 2db81443..64bd578b 100644 --- a/Assets/Scripts/Common/GameUtility/EndingLogic.cs +++ b/Assets/Scripts/Common/GameUtility/EndingLogic.cs @@ -12,8 +12,6 @@ public enum EndingType public partial class GameManager { - private float happyEndReputation = 3.0f; - public void ClearStage() { tryStageCount = 0; // 시도 횟수 초기화