집씬으로 넘기기
This commit is contained in:
@@ -45,4 +45,8 @@ public class DialogNode : ScriptableObject
|
||||
|
||||
[Header("Event")]
|
||||
public string EventKey; // 비어있지 않으면 이 노드가 재생될 때 DialogPlayer가 같은 Key의 이벤트를 호출
|
||||
|
||||
[Header("Story")]
|
||||
[Tooltip("0이 아니면 이 노드 재생 시 화자(비우면 대화 주인 NPC)의 호감도를 이만큼 증감")]
|
||||
public int Affection;
|
||||
}
|
||||
|
||||
@@ -368,6 +368,13 @@ private async Awaitable PlayNode(DialogNode node)
|
||||
|
||||
RaiseNodeEvent(node.EventKey); // EventKey 있으면 매칭 이벤트 호출
|
||||
|
||||
// 호감도 증감 — 화자 기준, 화자가 비어 있으면 대화 주인 NPC
|
||||
if (node.Affection != 0)
|
||||
{
|
||||
var affectionTarget = node.Speaker != null ? node.Speaker : _voice.Character;
|
||||
StoryManager.Instance.AddAffection(affectionTarget, node.Affection);
|
||||
}
|
||||
|
||||
// 전용 BGM: 설정돼 있으면 교체, 비어 있으면 기본 BGM으로 복귀
|
||||
if (SoundManager.Instance != null)
|
||||
{
|
||||
|
||||
@@ -97,6 +97,7 @@ public override void OnImportAsset(AssetImportContext ctx)
|
||||
dn.LookAtPlayer = GetInputPortValue<bool>(gn.GetInputPortByName(DialogLineNode.PORT_LOOKAT));
|
||||
dn.ForcePlayerLook = GetInputPortValue<bool>(gn.GetInputPortByName(DialogLineNode.PORT_FORCELOOK));
|
||||
dn.WaitForInput = GetInputPortValue<bool>(gn.GetInputPortByName(DialogLineNode.PORT_WAITINPUT));
|
||||
dn.Affection = GetInputPortValue<int>(gn.GetInputPortByName(DialogLineNode.PORT_AFFECTION));
|
||||
|
||||
string eventKey = null;
|
||||
line.GetNodeOptionByName(DialogLineNode.OPTION_EVENT_KEY)?.TryGetValue(out eventKey);
|
||||
@@ -143,6 +144,7 @@ static void FillStagingNode(DialogStagingNode gn, DialogNode dn)
|
||||
dn.LineDuration = GetInputPortValue<float>(gn.GetInputPortByName(DialogStagingNode.PORT_DURATION));
|
||||
dn.LookAtPlayer = GetInputPortValue<bool>(gn.GetInputPortByName(DialogStagingNode.PORT_LOOKAT));
|
||||
dn.ForcePlayerLook = GetInputPortValue<bool>(gn.GetInputPortByName(DialogStagingNode.PORT_FORCELOOK));
|
||||
dn.Affection = GetInputPortValue<int>(gn.GetInputPortByName(DialogStagingNode.PORT_AFFECTION));
|
||||
|
||||
string eventKey = null;
|
||||
gn.GetNodeOptionByName(DialogStagingNode.OPTION_EVENT_KEY)?.TryGetValue(out eventKey);
|
||||
|
||||
@@ -27,6 +27,7 @@ internal class DialogLineNode : DialogGraphNode
|
||||
public const string PORT_LOOKAT = "LookAtPlayer";
|
||||
public const string PORT_FORCELOOK = "ForcePlayerLook";
|
||||
public const string PORT_WAITINPUT = "WaitForInput";
|
||||
public const string PORT_AFFECTION = "Affection";
|
||||
public const string PORT_QUESTION = "ChoiceQuestion";
|
||||
|
||||
public const string OPTION_CHOICE_COUNT = "ChoiceCount";
|
||||
@@ -74,6 +75,8 @@ protected override void OnDefinePorts(IPortDefinitionContext context)
|
||||
context.AddInputPort<bool>(PORT_FORCELOOK).WithDisplayName("Force Player Look")
|
||||
.WithTooltip("이 대사 시작 시 플레이어(카메라)가 화자를 바라보도록 강제 회전").Build();
|
||||
context.AddInputPort<bool>(PORT_WAITINPUT).WithDisplayName("Wait For Input").Build();
|
||||
context.AddInputPort<int>(PORT_AFFECTION).WithDisplayName("Affection ±")
|
||||
.WithTooltip("0이 아니면 이 대사 재생 시 화자(비우면 대화 주인 NPC)의 호감도를 이만큼 증감").Build();
|
||||
|
||||
int choiceCount = 0;
|
||||
GetNodeOptionByName(OPTION_CHOICE_COUNT)?.TryGetValue(out choiceCount);
|
||||
|
||||
@@ -19,6 +19,7 @@ internal class DialogStagingNode : DialogGraphNode
|
||||
public const string PORT_DURATION = "Duration";
|
||||
public const string PORT_LOOKAT = "LookAtPlayer";
|
||||
public const string PORT_FORCELOOK = "ForcePlayerLook";
|
||||
public const string PORT_AFFECTION = "Affection";
|
||||
|
||||
public const string OPTION_EVENT_KEY = "EventKey";
|
||||
|
||||
@@ -48,6 +49,8 @@ protected override void OnDefinePorts(IPortDefinitionContext context)
|
||||
.WithTooltip("대상 캐릭터가 플레이어를 바라봄").Build();
|
||||
context.AddInputPort<bool>(PORT_FORCELOOK).WithDisplayName("Force Player Look")
|
||||
.WithTooltip("플레이어가 대상 캐릭터를 바라봄").Build();
|
||||
context.AddInputPort<int>(PORT_AFFECTION).WithDisplayName("Affection ±")
|
||||
.WithTooltip("0이 아니면 이 연출 재생 시 대상(비우면 대화 주인 NPC)의 호감도를 이만큼 증감").Build();
|
||||
|
||||
AddExecOutput(context, EXEC_OUT, string.Empty);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
using UnityEngine.InputSystem;
|
||||
|
||||
public class InputManager : MonoBehaviour, GameInput.IPlayerActions
|
||||
@@ -13,6 +14,9 @@ public class InputManager : MonoBehaviour, GameInput.IPlayerActions
|
||||
public event Action OnJump_Event;
|
||||
public event Action OnDialogNext_Event;
|
||||
|
||||
// 테스트용
|
||||
[SerializeField] private UnityEvent _testEvents;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (Instance == null)
|
||||
@@ -45,4 +49,10 @@ public void OnDialogNext(InputAction.CallbackContext ctx)
|
||||
if (ctx.phase == InputActionPhase.Started)
|
||||
OnDialogNext_Event?.Invoke();
|
||||
}
|
||||
|
||||
public void OnTestButton(InputAction.CallbackContext ctx)
|
||||
{
|
||||
if (ctx.phase == InputActionPhase.Started)
|
||||
_testEvents?.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
using UnityEngine.Rendering;
|
||||
using UnityEngine.Rendering.Universal;
|
||||
|
||||
public class LocalManager : MonoBehaviour
|
||||
public class LocalManager : MonoBehaviour,ISceneInitializable
|
||||
{
|
||||
[SerializeField] private string _nextSceneName;
|
||||
[SerializeField] private AudioClip _caffebeneBGM;
|
||||
@@ -19,6 +19,9 @@ public class LocalManager : MonoBehaviour
|
||||
[SerializeField] private Volume _globalVolume;
|
||||
[SerializeField] private GameObject CaffebeneImgObj;
|
||||
|
||||
// 이 씬 전용 스카이박스 (비우면 SceneLoadManager의 기본 스카이박스 사용)
|
||||
[SerializeField] private Material _sceneSkybox;
|
||||
|
||||
public void NextScene(int delay)
|
||||
{
|
||||
_ = Util.RunDelayed((float)delay,()=>SceneLoadManager.Instance.RequestSceneChange(_nextSceneName));
|
||||
@@ -95,4 +98,13 @@ private async Awaitable FadeToGrayscale(float duration)
|
||||
}
|
||||
_globalVolume.weight = 1f;
|
||||
}
|
||||
|
||||
// 씬 로드 시 이 씬 전용 스카이박스를 적용
|
||||
// (SceneLoadManager가 기본 스카이박스를 깐 뒤에 호출되므로 그 위에 덮어쓴다)
|
||||
public void OnSceneLoaded()
|
||||
{
|
||||
if (_sceneSkybox != null && SceneLoadManager.Instance != null)
|
||||
SceneLoadManager.Instance.SetSceneSkybox(_sceneSkybox);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
using UnityEngine.Serialization;
|
||||
using UnityEngine.XR.Interaction.Toolkit.Locomotion;
|
||||
|
||||
public class SceneLoadManager : MonoBehaviour
|
||||
@@ -11,8 +12,10 @@ public class SceneLoadManager : MonoBehaviour
|
||||
[SerializeField] private Camera _loadingCam;
|
||||
[SerializeField] private Transform _loadingCamTargetTransform;
|
||||
[SerializeField] private LoadingScreen _loadingScreen;
|
||||
|
||||
[SerializeField] private Material _sceneSkybox;
|
||||
// 씬(LocalManager)이 전용 스카이박스를 지정하지 않았을 때 쓰는 기본 스카이박스
|
||||
// (FormerlySerializedAs: 프리팹에 _sceneSkybox로 저장돼 있던 연결을 유지)
|
||||
[FormerlySerializedAs("_sceneSkybox")]
|
||||
[SerializeField] private Material _defaultSceneSkybox;
|
||||
[SerializeField] private Material _loadingSkybox;
|
||||
|
||||
[SerializeField, Min(0f)] private float _skyboxFadeTime = 1f;
|
||||
@@ -25,6 +28,9 @@ public class SceneLoadManager : MonoBehaviour
|
||||
private Material _runtimeSceneSkybox;
|
||||
private Material _runtimeLoadingSkybox;
|
||||
|
||||
// 씬 전환 시퀀스 진행 중 여부 — 이때 적용되는 새 스카이박스는 검은 상태로 시작해야 한다
|
||||
private bool _isChangingScene;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (Instance == null)
|
||||
@@ -36,16 +42,11 @@ private void Awake()
|
||||
Destroy(gameObject); // 이미 인스턴스가 있으면 자신을 파괴
|
||||
}
|
||||
|
||||
if (_sceneSkybox != null)
|
||||
_runtimeSceneSkybox = new Material(_sceneSkybox);
|
||||
if (_loadingSkybox != null)
|
||||
_runtimeLoadingSkybox = new Material(_loadingSkybox);
|
||||
|
||||
if (_runtimeSceneSkybox != null)
|
||||
{
|
||||
RenderSettings.skybox = _runtimeSceneSkybox;
|
||||
DynamicGI.UpdateEnvironment();
|
||||
}
|
||||
// 씬용 스카이박스는 OnSceneLoaded → SetSceneSkybox에서 적용된다
|
||||
// (기본 스카이박스를 깔고, 씬에 LocalManager가 있으면 씬 전용으로 덮어씀)
|
||||
}
|
||||
|
||||
private void Start()
|
||||
@@ -75,6 +76,10 @@ private void Update()
|
||||
// 씬이 로드되었을때 호출
|
||||
private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
|
||||
{
|
||||
// 우선 기본 스카이박스를 적용 — 씬 전용 스카이박스가 있으면
|
||||
// 아래 루프에서 그 씬의 LocalManager가 SetSceneSkybox로 덮어쓴다
|
||||
SetSceneSkybox(null);
|
||||
|
||||
MonoBehaviour[] allObjs = FindObjectsByType<MonoBehaviour>();
|
||||
|
||||
foreach (var obj in allObjs)
|
||||
@@ -87,6 +92,24 @@ private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
|
||||
}
|
||||
}
|
||||
|
||||
// 현재 씬에서 쓸 스카이박스를 지정한다 (null이면 기본 스카이박스로).
|
||||
// 페이드가 머티리얼 에셋 원본의 _Exposure를 오염시키지 않도록 항상 복사본을 만들어 쓴다.
|
||||
public void SetSceneSkybox(Material skybox)
|
||||
{
|
||||
var source = skybox != null ? skybox : _defaultSceneSkybox;
|
||||
if (source == null) return;
|
||||
|
||||
if (_runtimeSceneSkybox != null) Destroy(_runtimeSceneSkybox);
|
||||
_runtimeSceneSkybox = new Material(source);
|
||||
|
||||
// 씬 전환 중이면 아직 어두워야 한다 — 마지막 페이드 인(0 → 기본 노출)이 밝혀준다
|
||||
if (_isChangingScene && _runtimeSceneSkybox.HasFloat("_Exposure"))
|
||||
_runtimeSceneSkybox.SetFloat("_Exposure", 0f);
|
||||
|
||||
RenderSettings.skybox = _runtimeSceneSkybox;
|
||||
DynamicGI.UpdateEnvironment();
|
||||
}
|
||||
|
||||
public async Awaitable FadeLoadingCanvas(bool isOut,float fadeTime)
|
||||
{
|
||||
float startAlpha = isOut ? 1f : 0f;
|
||||
@@ -190,6 +213,8 @@ private async Awaitable SceneChange(string sceneName)
|
||||
{
|
||||
try
|
||||
{
|
||||
_isChangingScene = true;
|
||||
|
||||
//로딩바 수치 0으로 설정
|
||||
SetSceneLoadingProgressValue(0f);
|
||||
|
||||
@@ -276,5 +301,9 @@ private async Awaitable SceneChange(string sceneName)
|
||||
{
|
||||
Debug.Log("씬 전환 작업이 취소됨");
|
||||
}
|
||||
finally
|
||||
{
|
||||
_isChangingScene = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,7 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.Audio;
|
||||
|
||||
public class SoundManager : MonoBehaviour
|
||||
public class SoundManager : MonoBehaviour, ISceneInitializable
|
||||
{
|
||||
public static SoundManager Instance { get; private set; }
|
||||
|
||||
@@ -44,6 +44,10 @@ private void Awake()
|
||||
}
|
||||
}
|
||||
|
||||
// 씬이 바뀌면 이전 씬에서 남은 전용(Override) BGM을 정리한다 (ISceneInitializable).
|
||||
// 새 씬의 SceneBgm.Start가 SetDefaultBGM으로 그 씬의 곡을 넘겨주면 그대로 재생된다.
|
||||
public void OnSceneLoaded() => ClearOverrideBGM();
|
||||
|
||||
private void Initialize()
|
||||
{
|
||||
//BGM 소스 기본 설정
|
||||
|
||||
Reference in New Issue
Block a user