DEG-134-탈진숙면-돌발이벤트-연출 #27

Merged
heain0122 merged 5 commits from DEG-134-탈진숙면-돌발이벤트-연출 into main 2025-05-12 00:37:42 +00:00
21 changed files with 518 additions and 90 deletions

View File

@ -56,6 +56,10 @@ public class PlayerController : CharacterBase, IObserver<GameObject>
Joystick = FindObjectOfType<FixedJoystick>();
}
// isBattle 초기화 (임시)
bool isHousingScene = SceneManager.GetActiveScene().name.Contains("Housing");
_isBattle = !isHousingScene;
AssignCharacterController();
AssignAnimator();
}
@ -67,13 +71,6 @@ public class PlayerController : CharacterBase, IObserver<GameObject>
hitEffectController = GetComponentInChildren<PlayerHitEffectController>();
PlayerInit();
// isBattle 초기화 (임시)
/*bool isHousingScene = SceneManager.GetActiveScene().name.Contains("Housing");
_isBattle = !isHousingScene;
Debug.Log("_isBattle: " + _isBattle);*/
SwitchBattleMode();
}
private void Update()
@ -96,7 +93,9 @@ public class PlayerController : CharacterBase, IObserver<GameObject>
// 공격 입력 처리
if (Input.GetKeyDown(KeyCode.X) && (_currentAction == null || !_currentAction.IsActive)
&& (CurrentState != PlayerState.Win && CurrentState != PlayerState.Dead)) {
&& (CurrentState != PlayerState.Win && CurrentState != PlayerState.Dead))
{
GameManager.Instance.PlayPlayerAttackSound();
StartAttackAction();
}
@ -219,13 +218,18 @@ public class PlayerController : CharacterBase, IObserver<GameObject>
}
public void StartAttackAction() {
public void StartAttackAction()
{
if (!_isBattle) return;
_currentAction = _attackAction;
_currentAction.StartAction(this);
}
public void StartDashAction()
{
if (!_isBattle) return;
// 만약 공격 중이면 강제로 공격 종료
if (_currentAction == _attackAction && _attackAction.IsActive)
{
@ -400,6 +404,7 @@ public class PlayerController : CharacterBase, IObserver<GameObject>
if (character != this) return;
if (CurrentState == PlayerState.Dead) return;
GameManager.Instance.PlayPlayerHitSound();
SetState(PlayerState.Hit);
}

BIN
Assets/LIN/Housing Copy.unity (Stored with Git LFS)

Binary file not shown.

BIN
Assets/LIN/ReHousing Copy.unity (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 86c6ebc5f9b48c345bd9d6f402bdc848
guid: 5324096d5b520144d873395ac6861fe5
DefaultImporter:
externalObjects: {}
userData:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 0e2ae75cada1f20448baf1ac68f1a31d
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

BIN
Assets/LIN/Resources/OvertimeWork.mp3 (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -0,0 +1,23 @@
fileFormatVersion: 2
guid: 6142a6977f91d604d98880bdda758192
AudioImporter:
externalObjects: {}
serializedVersion: 7
defaultSettings:
serializedVersion: 2
loadType: 0
sampleRateSetting: 0
sampleRateOverride: 44100
compressionFormat: 1
quality: 1
conversionMode: 0
preloadAudioData: 0
platformSettingOverrides: {}
forceToMono: 0
normalize: 1
loadInBackground: 0
ambisonic: 0
3D: 1
userData:
assetBundleName:
assetBundleVariant:

BIN
Assets/LIN/Resources/TeamGathering.mp3 (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -0,0 +1,23 @@
fileFormatVersion: 2
guid: 59471df5d383e88478a567ac9b1e83d4
AudioImporter:
externalObjects: {}
serializedVersion: 7
defaultSettings:
serializedVersion: 2
loadType: 0
sampleRateSetting: 0
sampleRateOverride: 44100
compressionFormat: 1
quality: 1
conversionMode: 0
preloadAudioData: 0
platformSettingOverrides: {}
forceToMono: 0
normalize: 1
loadInBackground: 0
ambisonic: 0
3D: 1
userData:
assetBundleName:
assetBundleVariant:

View File

@ -3,17 +3,17 @@ using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Serialization;
using Random = UnityEngine.Random;
[RequireComponent(typeof(Rigidbody))]
public class InteractionController : MonoBehaviour
{
[SerializeField] LayerMask interactionLayerMask;
[FormerlySerializedAs("housingCanvasManager")]
[Header("UI 연동")]
[SerializeField] HousingCanvasController housingCanvasController;
[Header("UI 연동")] [SerializeField]
heain0122 marked this conversation as resolved Outdated

[FormerlySerializedAs("housingCanvasManager")] 요거는 이전 네이밍인가요? 지우셔도 괜찮을 것 같습니다!

[FormerlySerializedAs("housingCanvasManager")] 요거는 이전 네이밍인가요? 지우셔도 괜찮을 것 같습니다!
HousingCanvasController housingCanvasController;
[SerializeField] private InteractionAnimationPanelController interactionAnimationPanelController;
private SuddenEventController _suddenEventController = new SuddenEventController();
private void Start()
{
@ -23,88 +23,95 @@ public class InteractionController : MonoBehaviour
// 상호작용 가능한 사물 범위에 들어올 때
private void OnTriggerEnter(Collider other)
{
if(other.gameObject.layer == LayerMask.NameToLayer("NPC"))
if (other.gameObject.layer == LayerMask.NameToLayer("NPC"))
{
housingCanvasController.ShowNpcInteractionButton(() =>
{
GameManager.Instance.StartNPCDialogue(GamePhase.Gameplay);
});
}
if (interactionLayerMask == (interactionLayerMask | (1 << other.gameObject.layer)))
{
ActionType interactionType = other.gameObject.GetComponent<InteractionProp>().RoutineEnter();
if( interactionType != null )
if (interactionType != null)
{
PopActionOnScreen(interactionType);
}
}
}
// 사물에서 벗어날 때 UI 정리
private void OnTriggerExit(Collider other)
{
if(other.gameObject.layer == LayerMask.NameToLayer("NPC")) housingCanvasController.HideInteractionButton();
if (other.gameObject.layer == LayerMask.NameToLayer("NPC")) housingCanvasController.HideInteractionButton();
if (interactionLayerMask == (interactionLayerMask | (1 << other.gameObject.layer)))
{
housingCanvasController.HideInteractionButton();
housingCanvasController.interactionTextsController.InitInteractionTexts();
}
}
// ActionType 별로 화면에 상호작용 내용 표시, 상호작용 버튼에 이벤트 작성
private void PopActionOnScreen(ActionType interactionType)
{
HousingConstants.interactions.TryGetValue(interactionType, out var interactionTexts);
housingCanvasController.ShowInteractionButton(interactionTexts.ActionText,interactionTexts.DescriptionText,()=>
{
if (PlayerStats.Instance.CanPerformByHealth(interactionType))
{
PlayerStats.Instance.PerformAction(interactionType);
if (interactionType == ActionType.Dungeon)
housingCanvasController.ShowInteractionButton(interactionTexts.ActionText, interactionTexts.DescriptionText,
() =>
{
if (PlayerStats.Instance.CanPerformByHealth(interactionType))
{
GameManager.Instance.ChangeToGameScene();
PlayerStats.Instance.PerformAction(interactionType);
if (interactionType == ActionType.Dungeon)
{
GameManager.Instance.ChangeToGameScene();
}
else
{
GameManager.Instance.PlayInteractionSound(interactionType);
interactionAnimationPanelController.ShowAnimationPanel(interactionType,
interactionTexts.AnimationText);
}
}
else
{
GameManager.Instance.PlayInteractionSound(interactionType);
interactionAnimationPanelController.ShowAnimationPanel(interactionType,interactionTexts.AnimationText);
housingCanvasController.interactionTextsController.ActiveTexts(interactionTexts.LackOfHealth);
}
}
else
{
housingCanvasController.interactionTextsController.ActiveTexts(interactionTexts.LackOfHealth);
}
});
});
}
public Action SuddenEventHappen()
{
return null;
}
#region
public void SuddenAfterWorkEventHappen()
//이벤트 발생 확률 계산기
private AfterWorkEventType SuddenEventCalculator()
{
AfterWorkEvent afterWorkEvent = _suddenEventController.SuddenEventCalculator();
if (afterWorkEvent == AfterWorkEvent.None)
return;
switch (afterWorkEvent)
{
case AfterWorkEvent.OvertimeWork:
housingCanvasController.ShowSuddenEventPanel("부장님이 퇴근을 안하셔.. 야근할까?", () =>
{
//Todo: 컷씬과 스테이터스 변경
housingCanvasController.HideSuddenEventPanel();
});
break;
case AfterWorkEvent.TeamGathering:
housingCanvasController.ShowSuddenEventPanel("갑자기 팀 회식이 잡혔다. 참석 하러 가자", () =>
{
housingCanvasController.HideSuddenEventPanel();
});
break;
}
var index = Random.Range(0, HousingConstants.AFTER_WORK_DENOMINATOR);
return HousingConstants.AfterWorkEvents.GetValueOrDefault(index, AfterWorkEventType.None);
}
// Interaction Controller와 같은 방식으로 작동됩니다.
private void SuddenAfterWorkEventHappen()
{
AfterWorkEventType afterWorkEventType = SuddenEventCalculator();
if (afterWorkEventType == AfterWorkEventType.None) return;
HousingConstants.SuddenEventTexts.TryGetValue(afterWorkEventType, out string suddenEventText);
housingCanvasController.ShowSuddenEventPanel(suddenEventText, () =>
{
housingCanvasController.ShowSuddenEventImage(afterWorkEventType);
GameManager.Instance.PlaySuddenEventSound(afterWorkEventType);
});
}
#endregion
}

View File

@ -1,24 +0,0 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using Random = UnityEngine.Random;
public class SuddenEventController
{
// 랜덤 값에 일치하는 함수를 리턴하기 위한 딕셔너리
// AFTER_WORK_DENOMINATOR 값 확정 후에 키 값 수정
private Dictionary<int, AfterWorkEvent> afterWorkEvents = new Dictionary<int, AfterWorkEvent>();
public SuddenEventController()
{
afterWorkEvents.Add(0, AfterWorkEvent.OvertimeWork);
afterWorkEvents.Add(1, AfterWorkEvent.TeamGathering);
}
//퇴근 후 돌발 이벤트
public AfterWorkEvent SuddenEventCalculator()
{
var index = Random.Range(0,HousingConstants.AFTER_WORK_DENOMINATOR);
return afterWorkEvents.GetValueOrDefault(index, AfterWorkEvent.None);
}
}

View File

@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 26ce8577425c4630903173b182839514
timeCreated: 1745306651

View File

@ -14,7 +14,10 @@ public class HousingCanvasController : MonoBehaviour
[Header("돌발 이벤트")]
[SerializeField] private GameObject suddenPanel;
[SerializeField] private TMP_Text suddenText;
[SerializeField] private GameObject[] suddenEventImages;
private Coroutine _autoHideCoroutine;
public Action OnInteractionButtonPressed;
public Action OnSuddenButtonPressed;
@ -72,6 +75,7 @@ public class HousingCanvasController : MonoBehaviour
#region
public void ShowSuddenEventPanel(string actText, Action onSuddenButtonPressed)
{
Debug.Log("call evenet panel show");
suddenPanel.SetActive(true);
suddenText.text = actText;
OnSuddenButtonPressed += onSuddenButtonPressed;
@ -84,8 +88,54 @@ public class HousingCanvasController : MonoBehaviour
}
public void OnSuddenConfirmButton()
{
suddenText.text = "";
OnSuddenButtonPressed?.Invoke();
}
public void ShowSuddenEventImage(AfterWorkEventType afterWorkEventType)
{
if (_autoHideCoroutine != null) StopCoroutine(_autoHideCoroutine);
switch (afterWorkEventType)
{
case AfterWorkEventType.OvertimeWork:
suddenEventImages[0].SetActive(true);
break;
case AfterWorkEventType.TeamGathering:
suddenEventImages[1].SetActive(true);
break;
}
//사운드 재생
_autoHideCoroutine = StartCoroutine(AutoHideSuddenImage(afterWorkEventType));
}
public void HideSuddenEventImage()
{
foreach (var image in suddenEventImages)
{
image.SetActive(false);
}
}
private IEnumerator AutoHideSuddenImage(AfterWorkEventType afterWorkEventType)
{
float startTime = Time.time;
while (Time.time - startTime < HousingConstants.SUDDENEVENT_IAMGE_SHOW_TIME)
{
if (Input.touchCount > 0 || Input.GetMouseButtonDown(0))
{
break;
}
yield return null;
}
//패널 닫고 효과음 끄기
HideSuddenEventImage();
HideSuddenEventPanel();
GameManager.Instance.StopSuddenEventSound(afterWorkEventType);
_autoHideCoroutine = null;
}
#endregion
}

View File

@ -2,7 +2,8 @@
using System.Collections.Generic;
public enum AfterWorkEvent
public enum AfterWorkEventType
{
None,
TeamGathering,
@ -12,7 +13,9 @@ public enum AfterWorkEvent
public static class HousingConstants
{
//돌발 이벤트 확률 계산
public static int AFTER_WORK_DENOMINATOR = 4;
public static int AFTER_WORK_DENOMINATOR = 2;
//돌발 이벤트 보여줄 시간
public static float SUDDENEVENT_IAMGE_SHOW_TIME = 4.0f;
#region
@ -30,7 +33,6 @@ public static class HousingConstants
"도저히 출근할 체력이 안되는걸..?","출근하는 중")},
{ ActionType.Eat, new InteractionTexts("식사를 하자","1시간 동안 체력 1을 회복한다.","밥 먹는 중") }
};
#endregion
public struct InteractionTexts
{
@ -47,4 +49,35 @@ public static class HousingConstants
AnimationText = animationText;
}
}
#endregion
#region
public static readonly Dictionary<AfterWorkEventType, string> SuddenEventTexts =
new Dictionary<AfterWorkEventType, string>
{
{ AfterWorkEventType.OvertimeWork, "부장님이 퇴근을 안하셔.. 야근할까?" },
{ AfterWorkEventType.TeamGathering, "갑자기 팀 회식이 잡혔다. 참석 하러 가자"}
};
public struct SuddenEventTypes
{
public AfterWorkEventType AfterWorkEvent { get; private set; }
public string AfterWorkEventText { get; private set; }
public SuddenEventTypes(AfterWorkEventType afterWorkEvent, string afterWorkEventText)
{
AfterWorkEvent = afterWorkEvent;
AfterWorkEventText = afterWorkEventText;
}
}
#endregion
// 랜덤 값에 일치하는 함수를 리턴하기 위한 딕셔너리
// TODO: AFTER_WORK_DENOMINATOR 값 확정 후에 키 값 수정
public static readonly Dictionary<int, AfterWorkEventType> AfterWorkEvents = new Dictionary<int, AfterWorkEventType> {
{0, AfterWorkEventType.OvertimeWork},
{1, AfterWorkEventType.TeamGathering}
};
}

View File

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

BIN
Assets/LIN/Sprites/LateWork.PNG (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -0,0 +1,114 @@
fileFormatVersion: 2
guid: ccfd5bb6682e8484d8088d1a70dc9ccb
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 0
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID: 5e97eb03825dee720800000000000000
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:

BIN
Assets/LIN/Sprites/TeamGathering.png (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -0,0 +1,114 @@
fileFormatVersion: 2
guid: 516de2d9e0014d74bbec3c4a248d927c
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 0
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID: 5e97eb03825dee720800000000000000
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:

View File

@ -27,6 +27,10 @@ public partial class GameManager
[SerializeField] private AudioClip eatingSFX;
[SerializeField] private AudioClip sleepingSFX;
[Header("돌발 이벤트 효과음")]
[SerializeField] private AudioClip overtimeWorkSFX;
[SerializeField] private AudioClip teamGatheringSFX;
[Header("게임 결과 효과음")]
[SerializeField] private AudioClip gameOverSFX;
[SerializeField] private AudioClip victorySFX;
@ -83,6 +87,10 @@ public partial class GameManager
if (goToDungeonSFX != null) SafeSoundManager?.LoadAudioClip("Dungeon", goToDungeonSFX);
if (eatingSFX != null) SafeSoundManager?.LoadAudioClip("Eating", eatingSFX);
if (sleepingSFX != null) SafeSoundManager?.LoadAudioClip("Sleeping", sleepingSFX);
// 돌발 이벤트 효과음 등록
if(overtimeWorkSFX != null) SafeSoundManager?.LoadAudioClip("OvertimeWork", overtimeWorkSFX);
if(teamGatheringSFX != null) SafeSoundManager?.LoadAudioClip("TeamGathering", teamGatheringSFX);
// 플레이어 전투 효과음 등록
if (housingFootstepSFX != null) SafeSoundManager?.LoadAudioClip("HousingFootstep", housingFootstepSFX);
@ -297,6 +305,53 @@ public partial class GameManager
}
}
#endregion
#region
public void PlaySuddenEventSound(AfterWorkEventType afterWorkEventType)
{
// 배경음 중지 (페이드아웃)
SafeSoundManager?.StopBGM(true, 0.5f);
// 효과음 재생
switch (afterWorkEventType)
{
case AfterWorkEventType.TeamGathering:
SafeSoundManager?.PlaySFX("TeamGathering");
break;
case AfterWorkEventType.OvertimeWork:
SafeSoundManager?.PlaySFX("OvertimeWork");
break;
}
}
// 상호작용 효과음 종료
public void StopSuddenEventSound(AfterWorkEventType afterWorkEventType, float fadeTime = 0.5f)
{
string sfxName = "";
switch (afterWorkEventType)
{
case AfterWorkEventType.TeamGathering:
sfxName = "TeamGathering";
break;
case AfterWorkEventType.OvertimeWork:
sfxName = "OvertimeWork";
break;
}
if (!string.IsNullOrEmpty(sfxName))
{
SafeSoundManager?.FadeOutSFXByName(sfxName, fadeTime);
// 배경음 재개
if (wasPlayingBGM && previousBGMClip != null)
{
StartCoroutine(FadeOutAndPlayBGM(sfxName, fadeTime));
}
}
}
#endregion
#region