DEG-170 [Feat] 연출 연동 #65

Merged
Sehyeon merged 1 commits from DEG-170-연출-연동 into main 2025-05-15 00:06:43 +00:00
8 changed files with 84 additions and 30 deletions

BIN
Assets/KSH/TutorialManager.prefab (Stored with Git LFS) Normal file

Binary file not shown.

View File

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

View File

@ -24,10 +24,6 @@ public class TutorialManager : MonoBehaviour
private Canvas overlayCanvas; // RectTransformUtility를 위한 Canvas private Canvas overlayCanvas; // RectTransformUtility를 위한 Canvas
private Action onTutorialComplete; private Action onTutorialComplete;
public void Start( )
{
StartTutorial(null);
}
public void StartTutorial(Action onTutorialEnd, int panelIndex = 0) public void StartTutorial(Action onTutorialEnd, int panelIndex = 0)
{ {
if(parentCanvas == null) if(parentCanvas == null)
@ -45,9 +41,9 @@ public class TutorialManager : MonoBehaviour
if (_tutorialPanelController != null) if (_tutorialPanelController != null)
{ {
onTutorialComplete = onTutorialEnd; onTutorialComplete = onTutorialEnd;
overlay.alpha = 1f; overlay.alpha = 1f;
overlay.blocksRaycasts = true; overlay.blocksRaycasts = true;
RunStep(firstStep); RunStep(firstStep);
} }
else Debug.Log("패널 생성 실패, 튜토리얼 진행이 불가능합니다."); else Debug.Log("패널 생성 실패, 튜토리얼 진행이 불가능합니다.");
} }
@ -97,15 +93,10 @@ public class TutorialManager : MonoBehaviour
if (RectTransformUtility.RectangleContainsScreenPoint( if (RectTransformUtility.RectangleContainsScreenPoint(
targetRt, screenPos, overlayCanvas.worldCamera)) targetRt, screenPos, overlayCanvas.worldCamera))
{ {
Debug.Log("타겟 터치");
targetRt = null; targetRt = null;
_tutorialPanelController.HideTouchTarget(step.touchTargetIndex); _tutorialPanelController.HideTouchTarget(step.touchTargetIndex);
done = true; done = true;
} }
else
{
Debug.Log("타겟이 아닌 곳 터치");
}
} }
} }

View File

@ -90,7 +90,7 @@ public class InteractionAnimationPanelController : MonoBehaviour
/// 패널이 2초후 자동으로 닫히거나 터치시 닫히도록 합니다. /// 패널이 2초후 자동으로 닫히거나 터치시 닫히도록 합니다.
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
private IEnumerator AutoHidePanel(ActionType actionType) private IEnumerator AutoHidePanel(ActionType actionType, bool isTutorial = false)
{ {
float startTime = Time.time; float startTime = Time.time;
while (Time.time - startTime < animationDuration) while (Time.time - startTime < animationDuration)
@ -106,11 +106,11 @@ public class InteractionAnimationPanelController : MonoBehaviour
GameManager.Instance.StopInteractionSound(actionType); GameManager.Instance.StopInteractionSound(actionType);
//패널 닫고 애니메이션 null처리 //패널 닫고 애니메이션 null처리
HidePanel(); HidePanel(isTutorial);
_autoHideCoroutine = null; _autoHideCoroutine = null;
} }
private void HidePanel() private void HidePanel(bool isTutorial = false)
{ {
panel.SetActive(false); panel.SetActive(false);
@ -125,16 +125,19 @@ public class InteractionAnimationPanelController : MonoBehaviour
StopCoroutine(_autoHideCoroutine); StopCoroutine(_autoHideCoroutine);
_autoHideCoroutine = null; _autoHideCoroutine = null;
} }
if (_isAbsenceToday) // 결근한 경우 if (_isAbsenceToday) // 결근한 경우
{ {
PlayerStats.Instance.PerformAbsent(); PlayerStats.Instance.PerformAbsent();
return; return;
} }
// 패널 닫히고 결근 체크, 상호작용 패널과 결근 엔딩 채팅창이 겹치지 않기 위함 if (!isTutorial) // 튜토리얼 시 결근과 말풍선 오류로 인해 조건문 추가
PlayerStats.Instance.CheckAbsent(); {
PlayerStats.Instance.ShowBubble(); // 패널 닫히고 결근 체크, 상호작용 패널과 결근 엔딩 채팅창이 겹치지 않기 위함
PlayerStats.Instance.CheckAbsent();
PlayerStats.Instance.ShowBubble();
}
} }
public void TutorialSleepAnimation() public void TutorialSleepAnimation()
@ -142,7 +145,19 @@ public class InteractionAnimationPanelController : MonoBehaviour
_parentCanvas = FindObjectOfType(typeof(Canvas)) as Canvas; _parentCanvas = FindObjectOfType(typeof(Canvas)) as Canvas;
HousingConstants.interactions.TryGetValue(ActionType.Sleep, out var interactionTexts); 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));
} }
} }

View File

@ -8,7 +8,7 @@ public class MainUIPanelController : MonoBehaviour
public void OnClickStartButton() public void OnClickStartButton()
{ {
GameManager.Instance.ChangeToHomeScene(); GameManager.Instance.ChangeToHomeScene(true);
} }
public void OnClickSettingsButton() public void OnClickSettingsButton()

View File

@ -54,6 +54,8 @@ public class ChatWindowController : MonoBehaviour, IPointerClickHandler
public delegate void OnComplete(); public delegate void OnComplete();
public OnComplete onComplete; public OnComplete onComplete;
private bool isEnded;
private bool isTuto;
private FairyDialogueManager _dialogueManager; private FairyDialogueManager _dialogueManager;
@ -65,12 +67,21 @@ public class ChatWindowController : MonoBehaviour, IPointerClickHandler
private void Start() private void Start()
{ {
isEnded = false;
isTuto = false;
_dialogueManager = new FairyDialogueManager(this); _dialogueManager = new FairyDialogueManager(this);
/*onComplete = () => { onComplete = () => {
// 대화문 종료 call back if (isTuto)
Debug.Log("대화가 완료되었습니다."); {
};*/ isTuto = false;
StartCoroutine(GameManager.Instance.StartTutorialCoroutine());
}
if (isEnded)
GameManager.Instance.ChangeToMainScene();
};
} }
// 외부 호출용 함수 (대화 시작) // 외부 호출용 함수 (대화 시작)
@ -78,6 +89,12 @@ public class ChatWindowController : MonoBehaviour, IPointerClickHandler
{ {
_dialogueManager.SetGamePhase(phase); _dialogueManager.SetGamePhase(phase);
if (phase == GamePhase.End || phase == GamePhase.FailEnd || phase == GamePhase.ZeroEnd)
isEnded = true;
if (phase == GamePhase.Intro)
isTuto = true;
// Gameplay 상태라면 랜덤 대화 출력 // Gameplay 상태라면 랜덤 대화 출력
if (phase == GamePhase.Gameplay) _dialogueManager.ShowRandomGameplayDialogue(); if (phase == GamePhase.Gameplay) _dialogueManager.ShowRandomGameplayDialogue();
} }
@ -139,7 +156,6 @@ public class ChatWindowController : MonoBehaviour, IPointerClickHandler
if (_inputQueue.Count == 0) if (_inputQueue.Count == 0)
{ {
HideWindow(); HideWindow();
onComplete?.Invoke();
return; return;
} }
@ -200,6 +216,9 @@ public class ChatWindowController : MonoBehaviour, IPointerClickHandler
//대화창 클릭 시 호출 함수 //대화창 클릭 시 호출 함수
public void OnPointerClick(PointerEventData eventData) public void OnPointerClick(PointerEventData eventData)
{ {
if (!chatWindowObject.activeSelf) // 실제론 대화창이 off 상태인데 호출되는 상황 방지
return;
if (_typingCoroutine != null) if (_typingCoroutine != null)
{ {
StopCoroutine(_typingCoroutine); StopCoroutine(_typingCoroutine);

View File

@ -26,6 +26,8 @@ public partial class GameManager : Singleton<GameManager>,ISaveable
private PanelManager panelManager; private PanelManager panelManager;
public PanelManager PanelManager => panelManager; public PanelManager PanelManager => panelManager;
private TutorialManager tutorialManager;
private void Start() private void Start()
{ {
// 오디오 초기화 // 오디오 초기화
@ -91,6 +93,11 @@ public partial class GameManager : Singleton<GameManager>,ISaveable
TriggerTimeEnding(); TriggerTimeEnding();
} }
} }
public void ChangeToMainScene()
{
SceneManager.LoadScene("Main");
}
public void ChangeToGameScene() public void ChangeToGameScene()
{ {
@ -99,14 +106,28 @@ public partial class GameManager : Singleton<GameManager>,ISaveable
HandleSceneAudio("Dungeon"); HandleSceneAudio("Dungeon");
} }
public void ChangeToHomeScene() public void ChangeToHomeScene(bool isNewStart = false)
{ {
SceneManager.LoadScene("ReHousing"); // Home Scene SceneManager.LoadScene("ReHousing"); // Home Scene
HandleSceneAudio("Housing"); HandleSceneAudio("Housing");
if(isNewStart) // 아예 메인에서 시작 시 튜토리얼 출력
StartNPCDialogue(GamePhase.Intro); // StartCoroutine(StartTutorialCoroutine());
if (tryStageCount >= 3) FailEnd(); // 엔딩 if (tryStageCount >= 3) FailEnd(); // 엔딩
} }
public IEnumerator StartTutorialCoroutine()
{
yield return new WaitForSeconds(0.5f);
if(tutorialManager == null)
tutorialManager = FindObjectOfType<TutorialManager>();
PlayerStats.Instance.HideBubble();
tutorialManager.StartTutorial(() => PlayerStats.Instance.ShowBubble());
}
// TODO: Open Setting Panel 등 Panel 처리 // TODO: Open Setting Panel 등 Panel 처리
protected override void OnSceneLoaded(Scene scene, LoadSceneMode mode) protected override void OnSceneLoaded(Scene scene, LoadSceneMode mode)

View File

@ -12,8 +12,6 @@ public enum EndingType
public partial class GameManager public partial class GameManager
{ {
private float happyEndReputation = 3.0f;
public void ClearStage() public void ClearStage()
{ {
tryStageCount = 0; // 시도 횟수 초기화 tryStageCount = 0; // 시도 횟수 초기화