글로벌 오브젝트 추가

This commit is contained in:
2026-07-30 12:46:37 +09:00
parent 073567c652
commit 2413483853
23 changed files with 425 additions and 51 deletions

Binary file not shown.

View File

@@ -1,9 +1,20 @@
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;
// 노드의 역할. 서로 배타적이므로 플래그 여러 개가 아니라 하나의 종류로 둔다.
public enum DialogNodeKind
{
[InspectorName("대사")] Line, // 평범한 대사 노드
[InspectorName("호감도 분기")] AffectionCheck, // 대사 없이 조건만 검사해 즉시 라우팅
[InspectorName("종료")] End, // 대화를 끝낸다 (BGM 처리만 정함)
}
[CreateAssetMenu(menuName = "Communication/Dialog Node")] [CreateAssetMenu(menuName = "Communication/Dialog Node")]
public class DialogNode : ScriptableObject public class DialogNode : ScriptableObject
{ {
[Tooltip("이 노드의 역할. 그래프에서 어떤 노드를 썼는지에 따라 임포터가 정한다")]
public DialogNodeKind Kind = DialogNodeKind.Line;
[Header("Speaker")] [Header("Speaker")]
public CharacterData Speaker; public CharacterData Speaker;
@@ -18,7 +29,13 @@ public class DialogNode : ScriptableObject
// 진행은 항상 플레이어 입력(OnDialogNext)으로 넘어간다. // 진행은 항상 플레이어 입력(OnDialogNext)으로 넘어간다.
[Header("Presentation")] [Header("Presentation")]
public AudioClip Bgm; // 있으면 이 대사부터 전용 BGM 재생, 비어있으면 기본 BGM으로 복귀 [Tooltip("있으면 이 대사부터 BGM으로 갈아탄다. 비우면 변경 없음 — " +
"다시 바꾸기 전까지 계속 이어진다")]
public AudioClip Bgm;
[Tooltip("이 대사가 시작될 때 한 번 재생할 효과음 (문 여는 소리, 쿵 소리 등). " +
"BGM과 달리 이어지지 않고 1회성이다")]
public AudioClip Sfx;
[Tooltip("이 대사만의 타이핑 연출(속도·글자색·타이핑 사운드). " + [Tooltip("이 대사만의 타이핑 연출(속도·글자색·타이핑 사운드). " +
"비우면 DialogHud의 기본 스타일을 쓴다")] "비우면 DialogHud의 기본 스타일을 쓴다")]
@@ -36,17 +53,18 @@ public class DialogNode : ScriptableObject
public List<HiddenBranch> HiddenBranches = new(); public List<HiddenBranch> HiddenBranches = new();
[Header("Affection Branch")] [Header("Affection Branch")]
[Tooltip("켜면 이 노드는 대사 없이 호감도 조건만 검사해 즉시 라우팅한다: " + [Tooltip("(Kind = 호감도 분기 전용) 검사할 호감도 조건들 (캐릭터·연산자·값 + 다음 조건과의 and/or). " +
"조건을 만족하면 AffectionPassBranch로, 아니면 Next로")]
public bool AffectionCheck;
[Tooltip("검사할 호감도 조건들 (캐릭터·연산자·값 + 다음 조건과의 and/or). " +
"캐릭터를 비우면 대화 주인 NPC. AND가 OR보다 우선. 비어 있으면 무조건 통과")] "캐릭터를 비우면 대화 주인 NPC. AND가 OR보다 우선. 비어 있으면 무조건 통과")]
public List<AffectionRequirement> AffectionRequirements = new(); public List<AffectionRequirement> AffectionRequirements = new();
[Tooltip("조건을 만족했을 때 갈 노드 (실패하면 Next로)")] [Tooltip("조건을 만족했을 때 갈 노드 (실패하면 Next로)")]
public DialogNode AffectionPassBranch; public DialogNode AffectionPassBranch;
[Header("End")]
[Tooltip("(Kind = 종료 전용) 켜면 대화가 끝나도 마지막에 재생 중이던 BGM을 유지한다. " +
"끄면 장소 BGM으로 복귀. 종료 노드마다 따로 정할 수 있어서 분기별로 다르게 끝낼 수 있다")]
public bool KeepBgmOnEnd;
[Header("ChoiceQuestion")] [Header("ChoiceQuestion")]
[TextArea(2,5)] public string ChoiceQuestion; [TextArea(2,5)] public string ChoiceQuestion;

View File

@@ -185,14 +185,25 @@ private async Awaitable<StoryBeat> SelectBeat(List<StoryBeat> playable)
private async Awaitable PlayBeat(StoryBeat beat) private async Awaitable PlayBeat(StoryBeat beat)
{ {
// 도달한 종료 노드가 정한다. 중간에 끊기면(씬 전환 등) false로 남아 장소 BGM으로 복귀한다.
bool keepBgmOnEnd = false;
try try
{ {
var node = beat.Group.StartNode; var node = beat.Group.StartNode;
int routingHops = 0; // 연속 라우팅 횟수 — 라우팅 노드끼리 순환하면 대기 없는 무한 루프가 되므로 차단 int routingHops = 0; // 연속 라우팅 횟수 — 라우팅 노드끼리 순환하면 대기 없는 무한 루프가 되므로 차단
while (node != null) while (node != null)
{ {
// 종료 노드 — 대화를 끝낸다. 분기마다 다른 종료 노드를 둘 수 있어서
// "이 루트는 BGM 유지, 저 루트는 복귀"가 각각 정해진다.
if (node.Kind == DialogNodeKind.End)
{
keepBgmOnEnd = node.KeepBgmOnEnd;
break;
}
// 호감도 라우팅 노드 — 대사 없이 즉시 분기 (플레이어에겐 분기 자체가 보이지 않는다) // 호감도 라우팅 노드 — 대사 없이 즉시 분기 (플레이어에겐 분기 자체가 보이지 않는다)
if (node.AffectionCheck) if (node.Kind == DialogNodeKind.AffectionCheck)
{ {
if (++routingHops > 100) if (++routingHops > 100)
{ {
@@ -254,8 +265,12 @@ private async Awaitable PlayBeat(StoryBeat beat)
{ {
if (DialogHud.Instance != null) if (DialogHud.Instance != null)
DialogHud.Instance.Hide(); DialogHud.Instance.Hide();
if (SoundManager.Instance != null)
SoundManager.Instance.ClearOverrideBGM(); // 대화가 끝나면 기본 BGM으로 복귀 // 대화 BGM 처리 — 도달한 종료 노드가 Keep BGM이면 마지막 곡을 그대로 유지하고,
// 아니면 장소 BGM으로 복귀한다.
if (SoundManager.Instance != null && !keepBgmOnEnd)
SoundManager.Instance.ClearOverrideBGM();
RestoreDefaultAnimations(); RestoreDefaultAnimations();
} }
} }
@@ -303,14 +318,14 @@ private async Awaitable<bool> PlayNode(DialogNode node)
if (node.Progress != 0) if (node.Progress != 0)
StoryManager.Instance.MainProgress += node.Progress; StoryManager.Instance.MainProgress += node.Progress;
// 전용 BGM: 설정돼 있으면 교체, 비어 있으면 기본 BGM으로 복귀 // BGM: 지정된 노드에서만 갈아타고, 다시 바꾸기 전까지 계속 이어진다.
if (SoundManager.Instance != null) // 비어 있으면 "변경 없음" — 모든 노드에 같은 곡을 넣어줄 필요가 없다.
{ if (node.Bgm != null && SoundManager.Instance != null)
if (node.Bgm != null) SoundManager.Instance.PlayOverrideBGM(node.Bgm);
SoundManager.Instance.PlayOverrideBGM(node.Bgm);
else // 1회성 효과음 — 이 대사가 뜨는 순간 한 번 재생된다
SoundManager.Instance.ClearOverrideBGM(); if (node.Sfx != null && SoundManager.Instance != null)
} SoundManager.Instance.PlaySFX(node.Sfx);
// 보이스 재생 // 보이스 재생
if (node.Voice != null && node.Speaker != null) if (node.Voice != null && node.Speaker != null)

View File

@@ -4,7 +4,7 @@
namespace DinoLove.Dialog.GraphTool.Editor namespace DinoLove.Dialog.GraphTool.Editor
{ {
// 호감도 분기 노드. 대사 없이 호감도 조건식만 검사해 두 경로 중 하나로 즉시 라우팅한다. // 호감도 분기 노드. 대사 없이 호감도 조건식만 검사해 두 경로 중 하나로 즉시 라우팅한다.
// DialogNode(AffectionCheck=true) 하나로 변환된다. // DialogNode(Kind = AffectionCheck) 하나로 변환된다.
// //
// Condition Count로 조건 줄을 늘린다. 조건 하나는 [Target / 연산자 / 값] 세 줄이고, // Condition Count로 조건 줄을 늘린다. 조건 하나는 [Target / 연산자 / 값] 세 줄이고,
// 조건 사이마다 [and · or] 연결자 줄이 하나씩 생긴다: // 조건 사이마다 [and · or] 연결자 줄이 하나씩 생긴다:

View File

@@ -0,0 +1,32 @@
using System;
using Unity.GraphToolkit.Editor;
namespace DinoLove.Dialog.GraphTool.Editor
{
// 대화의 종료점. 진행 경로의 끝을 이 노드에 연결하면 "여기서 대화가 끝난다"가 그래프에 드러난다.
// Start와 달리 **여러 개 둘 수 있다** — 분기로 갈린 루트마다 종료 노드를 따로 두고
// BGM 처리를 다르게 정할 수 있다.
//
// 대화가 끝날 때의 BGM 처리를 여기서 정한다:
// Keep BGM 꺼짐(기본) → 장소 BGM(LocationData.Bgm)으로 복귀
// Keep BGM 켜짐 → 마지막에 재생 중이던 BGM을 그대로 유지
//
// 임포터는 이 노드를 DialogNode(Kind = End)로 변환한다. 대사가 없으므로 재생 시
// 아무것도 표시하지 않고 BGM 처리만 정한 뒤 대화를 끝낸다.
[Serializable]
internal class DialogEndNode : DialogGraphNode
{
public const string PORT_KEEP_BGM = "KeepBgm";
protected override void OnDefinePorts(IPortDefinitionContext context)
{
AddExecInput(context);
// 옵션(AddOption)이 아니라 입력 포트를 쓴다 — 이 프로젝트에서 값 렌더링이
// 여러 타입으로 검증된 경로이고, 임포터의 GetInputPortValue로 그대로 읽힌다.
context.AddInputPort<bool>(PORT_KEEP_BGM).WithDisplayName("Keep BGM")
.WithTooltip("켜면 대화가 끝나도 마지막 BGM을 그대로 유지한다. " +
"끄면(기본) 장소 BGM으로 돌아간다").Build();
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 96e836626b396b144a706f8e4e8e611e

View File

@@ -42,6 +42,11 @@ public override void OnGraphChanged(GraphLogger infos)
infos.LogWarning("Start 노드는 하나만 사용됩니다. 가장 먼저 생성된 노드만 적용됩니다.", extra); infos.LogWarning("Start 노드는 하나만 사용됩니다. 가장 먼저 생성된 노드만 적용됩니다.", extra);
break; break;
} }
// End 노드도 필수. 단 Start와 달리 여러 개 둘 수 있다 —
// 분기로 갈린 루트마다 종료 노드를 따로 두고 BGM 처리를 다르게 정할 수 있다.
if (!GetNodes().OfType<DialogEndNode>().Any())
infos.LogError("End 노드가 필요합니다. (Dialog End Node를 추가해 마지막 대사에 연결하세요)", this);
} }
} }
} }

View File

@@ -10,7 +10,7 @@ namespace DinoLove.Dialog.GraphTool.Editor
// .dlg 그래프 에셋을 기존 런타임 타입(DialogGroup / DialogNode / DialogChoice)으로 변환한다. // .dlg 그래프 에셋을 기존 런타임 타입(DialogGroup / DialogNode / DialogChoice)으로 변환한다.
// 생성된 DialogNode들은 서브에셋으로, DialogGroup이 메인 에셋으로 등록된다. // 생성된 DialogNode들은 서브에셋으로, DialogGroup이 메인 에셋으로 등록된다.
// 따라서 DialogPlayer는 수정 없이 임포트된 .dlg 에셋(= DialogGroup)을 그대로 사용한다. // 따라서 DialogPlayer는 수정 없이 임포트된 .dlg 에셋(= DialogGroup)을 그대로 사용한다.
[ScriptedImporter(17, DialogGraph.AssetExtension)] // 버전 올리면 기존 .dlg 에셋이 재임포트됨 [ScriptedImporter(20, DialogGraph.AssetExtension)] // 버전 올리면 기존 .dlg 에셋이 재임포트됨
internal class DialogGraphImporter : ScriptedImporter internal class DialogGraphImporter : ScriptedImporter
{ {
public override void OnImportAsset(AssetImportContext ctx) public override void OnImportAsset(AssetImportContext ctx)
@@ -38,7 +38,9 @@ public override void OnImportAsset(AssetImportContext ctx)
if (firstGraphNode == null) if (firstGraphNode == null)
return; // Start만 있고 연결 없음 return; // Start만 있고 연결 없음
// 1패스: 도달 가능한 모든 라인 노드 → DialogNode 인스턴스 생성 (중복 제거) // 1패스: 도달 가능한 모든 노드 → DialogNode 인스턴스 생성 (중복 제거).
// End 노드도 DialogNode가 된다 — 그래야 분기마다 다른 종료 노드를 두고
// 각자 다른 BGM 처리를 갖게 할 수 있다 (Next로 자연히 연결되므로 별도 배선이 없다).
var map = new Dictionary<INode, DialogNode>(); var map = new Dictionary<INode, DialogNode>();
var order = new List<INode>(); var order = new List<INode>();
var queue = new Queue<INode>(); var queue = new Queue<INode>();
@@ -48,7 +50,8 @@ public override void OnImportAsset(AssetImportContext ctx)
{ {
var gn = queue.Dequeue(); var gn = queue.Dequeue();
if (gn == null || map.ContainsKey(gn) if (gn == null || map.ContainsKey(gn)
|| (gn is not DialogLineNode && gn is not DialogAffectionNode)) || (gn is not DialogLineNode && gn is not DialogAffectionNode
&& gn is not DialogEndNode))
continue; continue;
var dn = ScriptableObject.CreateInstance<DialogNode>(); var dn = ScriptableObject.CreateInstance<DialogNode>();
@@ -75,10 +78,19 @@ public override void OnImportAsset(AssetImportContext ctx)
{ {
var dn = map[gn]; var dn = map[gn];
// 종료 노드 — 대사 없이 대화를 끝내며, BGM 처리만 담는다
if (gn is DialogEndNode)
{
dn.Kind = DialogNodeKind.End;
dn.KeepBgmOnEnd = GetInputPortValue<bool>(
gn.GetInputPortByName(DialogEndNode.PORT_KEEP_BGM));
continue;
}
// 호감도 분기 노드 — 대사 없이 라우팅만: 조건 통과 → AffectionPassBranch, 실패 → Next // 호감도 분기 노드 — 대사 없이 라우팅만: 조건 통과 → AffectionPassBranch, 실패 → Next
if (gn is DialogAffectionNode affectionNode) if (gn is DialogAffectionNode affectionNode)
{ {
dn.AffectionCheck = true; dn.Kind = DialogNodeKind.AffectionCheck;
int conditionCount = 1; int conditionCount = 1;
var countOption = affectionNode.GetNodeOptionByName(DialogAffectionNode.OPTION_CONDITION_COUNT); var countOption = affectionNode.GetNodeOptionByName(DialogAffectionNode.OPTION_CONDITION_COUNT);
@@ -117,6 +129,7 @@ public override void OnImportAsset(AssetImportContext ctx)
dn.Expression = GetInputPortValue<ExpressionData>(gn.GetInputPortByName(DialogLineNode.PORT_EXPRESSION)); dn.Expression = GetInputPortValue<ExpressionData>(gn.GetInputPortByName(DialogLineNode.PORT_EXPRESSION));
dn.Voice = GetInputPortValue<VoiceClip>(gn.GetInputPortByName(DialogLineNode.PORT_VOICE)); dn.Voice = GetInputPortValue<VoiceClip>(gn.GetInputPortByName(DialogLineNode.PORT_VOICE));
dn.Bgm = GetInputPortValue<AudioClip>(gn.GetInputPortByName(DialogLineNode.PORT_BGM)); dn.Bgm = GetInputPortValue<AudioClip>(gn.GetInputPortByName(DialogLineNode.PORT_BGM));
dn.Sfx = GetInputPortValue<AudioClip>(gn.GetInputPortByName(DialogLineNode.PORT_SFX));
dn.Typewriter = GetInputPortValue<TypewriterStyle>(gn.GetInputPortByName(DialogLineNode.PORT_TYPEWRITER)); dn.Typewriter = GetInputPortValue<TypewriterStyle>(gn.GetInputPortByName(DialogLineNode.PORT_TYPEWRITER));
dn.Affection = GetInputPortValue<int>(gn.GetInputPortByName(DialogLineNode.PORT_AFFECTION)); dn.Affection = GetInputPortValue<int>(gn.GetInputPortByName(DialogLineNode.PORT_AFFECTION));
dn.Progress = GetInputPortValue<int>(gn.GetInputPortByName(DialogLineNode.PORT_PROGRESS)); dn.Progress = GetInputPortValue<int>(gn.GetInputPortByName(DialogLineNode.PORT_PROGRESS));

View File

@@ -21,6 +21,7 @@ internal class DialogLineNode : DialogGraphNode
public const string PORT_EXPRESSION = "Expression"; public const string PORT_EXPRESSION = "Expression";
public const string PORT_VOICE = "Voice"; public const string PORT_VOICE = "Voice";
public const string PORT_BGM = "Bgm"; public const string PORT_BGM = "Bgm";
public const string PORT_SFX = "Sfx";
public const string PORT_TYPEWRITER = "Typewriter"; public const string PORT_TYPEWRITER = "Typewriter";
public const string PORT_AFFECTION = "Affection"; public const string PORT_AFFECTION = "Affection";
public const string PORT_PROGRESS = "Progress"; public const string PORT_PROGRESS = "Progress";
@@ -69,7 +70,11 @@ protected override void OnDefinePorts(IPortDefinitionContext context)
context.AddInputPort<ExpressionData>(PORT_EXPRESSION).WithDisplayName("Expression").Build(); context.AddInputPort<ExpressionData>(PORT_EXPRESSION).WithDisplayName("Expression").Build();
context.AddInputPort<VoiceClip>(PORT_VOICE).WithDisplayName("Voice").Build(); context.AddInputPort<VoiceClip>(PORT_VOICE).WithDisplayName("Voice").Build();
context.AddInputPort<AudioClip>(PORT_BGM).WithDisplayName("BGM") context.AddInputPort<AudioClip>(PORT_BGM).WithDisplayName("BGM")
.WithTooltip("있으면 이 대사부터 전용 BGM 재생, 비우면 기본 BGM으로 복귀").Build(); .WithTooltip("있으면 이 대사부터 이 BGM으로 갈아탄다. " +
"비우면 변경 없음 — 다시 바꾸기 전까지 계속 이어진다").Build();
context.AddInputPort<AudioClip>(PORT_SFX).WithDisplayName("SFX")
.WithTooltip("이 대사가 시작될 때 한 번 재생할 효과음 (문 여는 소리, 쿵 소리 등). " +
"BGM과 달리 이어지지 않고 1회성이다").Build();
context.AddInputPort<TypewriterStyle>(PORT_TYPEWRITER).WithDisplayName("Typewriter") context.AddInputPort<TypewriterStyle>(PORT_TYPEWRITER).WithDisplayName("Typewriter")
.WithTooltip("이 대사만의 타이핑 연출(속도·글자색·타이핑 사운드). " + .WithTooltip("이 대사만의 타이핑 연출(속도·글자색·타이핑 사운드). " +
"비우면 DialogHud의 기본 스타일").Build(); "비우면 DialogHud의 기본 스타일").Build();

View File

@@ -0,0 +1,18 @@
using UnityEngine;
public class GlobalObject : MonoBehaviour
{
private static GlobalObject _instance;
void Awake()
{
if (_instance == null)
{
_instance = this;
DontDestroyOnLoad(gameObject);
}
else
{
Destroy(gameObject);
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 945cc6d1ec9db6446b7c06f420117c84

View File

@@ -55,6 +55,12 @@ public void MoveTo(LocationData location)
if (location == null || DialogPlayer.IsAnyActive) return; if (location == null || DialogPlayer.IsAnyActive) return;
Current = location; Current = location;
// 장소 BGM = SoundManager의 기본 BGM 층. 대화용 BGM(Override)이 걷히면 이 곡으로 돌아온다.
// 비어 있으면 변경하지 않는다 — 노드 BGM과 같은 규칙(비면 변경 없음)이다.
if (location.Bgm != null && SoundManager.Instance != null)
SoundManager.Instance.SetDefaultBGM(location.Bgm);
if (_currentInstance != null) Destroy(_currentInstance); if (_currentInstance != null) Destroy(_currentInstance);
_currentInstance = location.Prefab != null _currentInstance = location.Prefab != null
? Instantiate(location.Prefab, _locationRoot) ? Instantiate(location.Prefab, _locationRoot)

View File

@@ -45,7 +45,7 @@ private void Awake()
} }
// 씬이 바뀌면 이전 씬에서 남은 전용(Override) BGM을 정리한다 (ISceneInitializable). // 씬이 바뀌면 이전 씬에서 남은 전용(Override) BGM을 정리한다 (ISceneInitializable).
// 새 씬의 SceneBgm.Start가 SetDefaultBGM으로 그 씬의 곡을 넘겨주면 그대로 재생된다. // 기본 BGM 층은 LocationManager.MoveTo가 장소 입장 시 SetDefaultBGM으로 넘겨준다.
public void OnSceneLoaded() => ClearOverrideBGM(); public void OnSceneLoaded() => ClearOverrideBGM();
private void Initialize() private void Initialize()

View File

@@ -11,4 +11,8 @@ public class LocationData : ScriptableObject
[Tooltip("이 장소의 프리팹 — 배경 + 캐릭터 슬롯(CharacterSlot)들 + 이동 버튼 등")] [Tooltip("이 장소의 프리팹 — 배경 + 캐릭터 슬롯(CharacterSlot)들 + 이동 버튼 등")]
public GameObject Prefab; public GameObject Prefab;
[Tooltip("이 장소의 기본 BGM. 대화용 BGM이 걷히면 이 곡으로 돌아온다. " +
"비우면 변경하지 않는다(이전 곡 유지) — 같은 곡을 쓰는 장소마다 넣지 않아도 된다")]
public AudioClip Bgm;
} }

View File

@@ -1,4 +1,5 @@
using System; using System;
using System.Text;
using System.Threading; using System.Threading;
using UnityEngine; using UnityEngine;
@@ -36,10 +37,38 @@ public sealed class Typewriter
// 지금 적용할 스타일 (글자 색 오버라이드 판단용). 연출 없이 표시했으면 null // 지금 적용할 스타일 (글자 색 오버라이드 판단용). 연출 없이 표시했으면 null
public TypewriterStyle Style => _style; public TypewriterStyle Style => _style;
// Label.text에 그대로 넣을 문자열. 아직 안 드러난 뒷부분은 투명 처리돼 있다 // Label.text에 그대로 넣을 문자열. 아직 안 드러난 뒷부분은 투명 처리돼 있다.
public string Composed => _cursor >= _full.Length //
? _full // 뒷부분의 태그마다 <alpha=#00>을 다시 선언하는 게 핵심이다:
: _full.Substring(0, _cursor) + HIDE_TAG + _full.Substring(_cursor); // <color=...>나 </color>는 색을 (재)지정하면서 알파까지 같이 덮으므로, 앞에 한 번만 걸어둔
// <alpha=#00>이 풀려 아직 안 나온 글자가 보여 버린다. 뒷부분은 전부 숨겨야 하는 구간이니
// 태그가 끝날 때마다 투명도를 다시 못박는 게 항상 옳다.
public string Composed
{
get
{
if (_cursor >= _full.Length) return _full;
var sb = new StringBuilder(_full.Length + 32);
sb.Append(_full, 0, _cursor);
sb.Append(HIDE_TAG);
for (int i = _cursor; i < _full.Length; i++)
{
char c = _full[i];
sb.Append(c);
if (c != '<') continue;
int close = _full.IndexOf('>', i + 1);
if (close < 0) continue; // 닫히지 않은 '<' — 평범한 글자로 취급
sb.Append(_full, i + 1, close - i); // 태그 나머지 + '>'
sb.Append(HIDE_TAG); // 색이 되돌아갔을 수 있으니 다시 숨긴다
i = close;
}
return sb.ToString();
}
}
// 새 텍스트로 타이핑을 시작한다. style이 null이면 연출 없이 즉시 전체 표시. // 새 텍스트로 타이핑을 시작한다. style이 null이면 연출 없이 즉시 전체 표시.
// token은 소유자(MonoBehaviour)의 destroyCancellationToken을 넘길 것. // token은 소유자(MonoBehaviour)의 destroyCancellationToken을 넘길 것.

8
Assets/03_Shaders.meta Normal file
View File

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

8
Assets/04_Models.meta Normal file
View File

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

Binary file not shown.

View File

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

View File

@@ -19,6 +19,164 @@ MonoBehaviour:
RefIds: RefIds:
- rid: -2 - rid: -2
type: {class: , ns: , asm: } type: {class: , ns: , asm: }
- rid: 4848514907161231424
type: {class: 'Constant`1[[System.Int32, mscorlib]]', ns: Unity.GraphToolkit.Editor, asm: UnityEditor.GraphToolkitModule}
data:
m_Value: 0
- rid: 4848514907161231425
type: {class: 'Constant`1[[TypewriterStyle, Assembly-CSharp]]', ns: Unity.GraphToolkit.Editor, asm: UnityEditor.GraphToolkitModule}
data:
m_Value: {fileID: 0}
- rid: 4848514907161231434
type: {class: UserNodeModelImp, ns: Unity.GraphToolkit.Editor.Implementation, asm: UnityEditor.GraphToolkitModule}
data:
m_Guid:
m_Value0: 16453215471102353767
m_Value1: 11894338102006161391
m_HashGuid:
serializedVersion: 2
Hash: 676104504c9055e4ef9f78207c2d11a5
m_Version: 2
m_Position: {x: 1022.2925, y: -108.445}
m_Title:
m_Tooltip:
m_NodePreviewModel:
rid: -2
m_State: 0
m_InputConstantsById:
m_KeyList:
- KeepBgm
m_ValueList:
- rid: 4848514907161231435
m_InputPortInfos:
expandedPortsById:
m_KeyList: []
m_ValueList:
m_OutputPortInfos:
expandedPortsById:
m_KeyList: []
m_ValueList:
m_Collapsed: 0
m_CurrentModeIndex: 0
m_ElementColor:
m_Color: {r: 0, g: 0, b: 0, a: 0}
m_HasUserColor: 0
m_Node:
rid: 4848514907161231436
- rid: 4848514907161231435
type: {class: 'Constant`1[[System.Boolean, mscorlib]]', ns: Unity.GraphToolkit.Editor, asm: UnityEditor.GraphToolkitModule}
data:
m_Value: 0
- rid: 4848514907161231436
type: {class: DialogEndNode, ns: DinoLove.Dialog.GraphTool.Editor, asm: Assembly-CSharp-Editor}
data:
- rid: 4848514907161231437
type: {class: WireModel, ns: Unity.GraphToolkit.Editor, asm: UnityEditor.GraphToolkitModule}
data:
m_Guid:
m_Value0: 5143976002492878297
m_Value1: 15423880824646763031
m_HashGuid:
serializedVersion: 2
Hash: d9cdb899eb1263471782070be4a10cd6
m_Version: 2
m_FromPortReference:
m_NodeModelGuid:
m_Value0: 4814898993618757843
m_Value1: 13954766896149483658
m_NodeModelHashGuid:
serializedVersion: 2
Hash: d32808d01ff5d1428ad05e788e4aa9c1
m_UniqueId: PassOut
m_PortDirection: 2
m_PortOrientation: 0
m_Title: "True \u2192"
m_ToPortReference:
m_NodeModelGuid:
m_Value0: 16453215471102353767
m_Value1: 11894338102006161391
m_NodeModelHashGuid:
serializedVersion: 2
Hash: 676104504c9055e4ef9f78207c2d11a5
m_UniqueId: In
m_PortDirection: 1
m_PortOrientation: 0
m_Title:
- rid: 4848514907161231438
type: {class: UserNodeModelImp, ns: Unity.GraphToolkit.Editor.Implementation, asm: UnityEditor.GraphToolkitModule}
data:
m_Guid:
m_Value0: 1938688397874075465
m_Value1: 2789158294045304892
m_HashGuid:
serializedVersion: 2
Hash: 49977485d39ae71a3ca8e7dab014b526
m_Version: 2
m_Position: {x: 1015.285, y: 82.087524}
m_Title:
m_Tooltip:
m_NodePreviewModel:
rid: -2
m_State: 0
m_InputConstantsById:
m_KeyList:
- KeepBgm
m_ValueList:
- rid: 4848514907161231440
m_InputPortInfos:
expandedPortsById:
m_KeyList: []
m_ValueList:
m_OutputPortInfos:
expandedPortsById:
m_KeyList: []
m_ValueList:
m_Collapsed: 0
m_CurrentModeIndex: 0
m_ElementColor:
m_Color: {r: 0, g: 0, b: 0, a: 0}
m_HasUserColor: 0
m_Node:
rid: 4848514907161231441
- rid: 4848514907161231439
type: {class: WireModel, ns: Unity.GraphToolkit.Editor, asm: UnityEditor.GraphToolkitModule}
data:
m_Guid:
m_Value0: 641791417328842023
m_Value1: 16432348670849463703
m_HashGuid:
serializedVersion: 2
Hash: 27b5c7c9e419e808973558c70d6e0be4
m_Version: 2
m_FromPortReference:
m_NodeModelGuid:
m_Value0: 4814898993618757843
m_Value1: 13954766896149483658
m_NodeModelHashGuid:
serializedVersion: 2
Hash: d32808d01ff5d1428ad05e788e4aa9c1
m_UniqueId: FailOut
m_PortDirection: 2
m_PortOrientation: 0
m_Title: "False \u2192"
m_ToPortReference:
m_NodeModelGuid:
m_Value0: 1938688397874075465
m_Value1: 2789158294045304892
m_NodeModelHashGuid:
serializedVersion: 2
Hash: 49977485d39ae71a3ca8e7dab014b526
m_UniqueId: In
m_PortDirection: 1
m_PortOrientation: 0
m_Title:
- rid: 4848514907161231440
type: {class: 'Constant`1[[System.Boolean, mscorlib]]', ns: Unity.GraphToolkit.Editor, asm: UnityEditor.GraphToolkitModule}
data:
m_Value: 0
- rid: 4848514907161231441
type: {class: DialogEndNode, ns: DinoLove.Dialog.GraphTool.Editor, asm: Assembly-CSharp-Editor}
data:
- rid: 6600512887158735084 - rid: 6600512887158735084
type: {class: GraphModelImp, ns: Unity.GraphToolkit.Editor.Implementation, asm: UnityEditor.GraphToolkitModule} type: {class: GraphModelImp, ns: Unity.GraphToolkit.Editor.Implementation, asm: UnityEditor.GraphToolkitModule}
data: data:
@@ -33,9 +191,13 @@ MonoBehaviour:
- rid: 6600512887158735087 - rid: 6600512887158735087
- rid: 6600512887158735111 - rid: 6600512887158735111
- rid: 6600512887158735114 - rid: 6600512887158735114
- rid: 4848514907161231434
- rid: 4848514907161231438
m_GraphWireModels: m_GraphWireModels:
- rid: 6600512887158735113 - rid: 6600512887158735113
- rid: 6600512887158735115 - rid: 6600512887158735115
- rid: 4848514907161231437
- rid: 4848514907161231439
m_GraphStickyNoteModels: [] m_GraphStickyNoteModels: []
m_GraphPlacematModels: [] m_GraphPlacematModels: []
m_GraphVariableModels: [] m_GraphVariableModels: []
@@ -46,9 +208,9 @@ MonoBehaviour:
m_LastKnownBounds: m_LastKnownBounds:
serializedVersion: 2 serializedVersion: 2
x: -404 x: -404
y: -43 y: -108
width: 1186 width: 1581
height: 450 height: 497
m_GraphElementMetaData: m_GraphElementMetaData:
- m_Guid: - m_Guid:
m_Value0: 8557079674992562767 m_Value0: 8557079674992562767
@@ -90,6 +252,38 @@ MonoBehaviour:
Hash: 3baeafb1da23486527c4bf3c23696024 Hash: 3baeafb1da23486527c4bf3c23696024
m_Category: 2 m_Category: 2
m_Index: 1 m_Index: 1
- m_Guid:
m_Value0: 16453215471102353767
m_Value1: 11894338102006161391
m_HashGuid:
serializedVersion: 2
Hash: 676104504c9055e4ef9f78207c2d11a5
m_Category: 0
m_Index: 3
- m_Guid:
m_Value0: 5143976002492878297
m_Value1: 15423880824646763031
m_HashGuid:
serializedVersion: 2
Hash: d9cdb899eb1263471782070be4a10cd6
m_Category: 2
m_Index: 2
- m_Guid:
m_Value0: 1938688397874075465
m_Value1: 2789158294045304892
m_HashGuid:
serializedVersion: 2
Hash: 49977485d39ae71a3ca8e7dab014b526
m_Category: 0
m_Index: 4
- m_Guid:
m_Value0: 641791417328842023
m_Value1: 16432348670849463703
m_HashGuid:
serializedVersion: 2
Hash: 27b5c7c9e419e808973558c70d6e0be4
m_Category: 2
m_Index: 3
m_EntryPoint: m_EntryPoint:
rid: 6600512887158735087 rid: 6600512887158735087
m_Graph: m_Graph:
@@ -128,9 +322,6 @@ MonoBehaviour:
m_InputConstantsById: m_InputConstantsById:
m_KeyList: m_KeyList:
- __option_ChoiceCount - __option_ChoiceCount
- __option_HasHiddenBranch
- __option_HiddenGestureKey
- __option_HiddenCode
- Speaker - Speaker
- SpeakerNameOverride - SpeakerNameOverride
- TalkText - TalkText
@@ -140,11 +331,10 @@ MonoBehaviour:
- Bgm - Bgm
- Affection - Affection
- Progress - Progress
- __option_HiddenBranchCount
- Typewriter
m_ValueList: m_ValueList:
- rid: 6600512887158735088 - rid: 6600512887158735088
- rid: 6600512887158735090
- rid: 6600512887158735091
- rid: 6600512887158735092
- rid: 6600512887158735093 - rid: 6600512887158735093
- rid: 6600512887158735094 - rid: 6600512887158735094
- rid: 6600512887158735096 - rid: 6600512887158735096
@@ -154,6 +344,8 @@ MonoBehaviour:
- rid: 6600512887158735100 - rid: 6600512887158735100
- rid: 6600512887158735108 - rid: 6600512887158735108
- rid: 6600512887158735109 - rid: 6600512887158735109
- rid: 4848514907161231424
- rid: 4848514907161231425
m_InputPortInfos: m_InputPortInfos:
expandedPortsById: expandedPortsById:
m_KeyList: [] m_KeyList: []
@@ -173,18 +365,6 @@ MonoBehaviour:
type: {class: 'Constant`1[[System.Int32, mscorlib]]', ns: Unity.GraphToolkit.Editor, asm: UnityEditor.GraphToolkitModule} type: {class: 'Constant`1[[System.Int32, mscorlib]]', ns: Unity.GraphToolkit.Editor, asm: UnityEditor.GraphToolkitModule}
data: data:
m_Value: 0 m_Value: 0
- rid: 6600512887158735090
type: {class: 'Constant`1[[System.Boolean, mscorlib]]', ns: Unity.GraphToolkit.Editor, asm: UnityEditor.GraphToolkitModule}
data:
m_Value: 0
- rid: 6600512887158735091
type: {class: 'Constant`1[[System.String, mscorlib]]', ns: Unity.GraphToolkit.Editor, asm: UnityEditor.GraphToolkitModule}
data:
m_Value:
- rid: 6600512887158735092
type: {class: 'Constant`1[[System.String, mscorlib]]', ns: Unity.GraphToolkit.Editor, asm: UnityEditor.GraphToolkitModule}
data:
m_Value:
- rid: 6600512887158735093 - rid: 6600512887158735093
type: {class: 'Constant`1[[CharacterData, Assembly-CSharp]]', ns: Unity.GraphToolkit.Editor, asm: UnityEditor.GraphToolkitModule} type: {class: 'Constant`1[[CharacterData, Assembly-CSharp]]', ns: Unity.GraphToolkit.Editor, asm: UnityEditor.GraphToolkitModule}
data: data:

View File

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

Binary file not shown.

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: ddd31e95563e379458d4e8f53904b484
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant: