멸망엔딩
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
using System;
|
||||
using Unity.GraphToolkit.Editor;
|
||||
|
||||
namespace DinoLove.Dialog.GraphTool.Editor
|
||||
{
|
||||
// 호감도 분기 노드. 대사 없이 호감도 조건식만 검사해 두 경로 중 하나로 즉시 라우팅한다.
|
||||
// DialogNode(AffectionCheck=true) 하나로 변환된다.
|
||||
//
|
||||
// Condition Count로 조건 줄을 늘린다. 조건 하나는 [Target / 연산자 / 값] 세 줄이고,
|
||||
// 조건 사이마다 [and · or] 연결자 줄이 하나씩 생긴다:
|
||||
//
|
||||
// Target 1 윤지후
|
||||
// Compare 1 ≥
|
||||
// Affection 1 30
|
||||
// Join 1 AND
|
||||
// Target 2 잔디
|
||||
// Compare 2 <
|
||||
// Affection 2 20
|
||||
// ├─ True →
|
||||
// └─ False →
|
||||
//
|
||||
// AND가 OR보다 우선순위가 높다 (A and B or C → (A and B) or C).
|
||||
[Serializable]
|
||||
internal class DialogAffectionNode : DialogGraphNode
|
||||
{
|
||||
public const string PORT_PASS_OUT = "PassOut";
|
||||
public const string PORT_FAIL_OUT = "FailOut";
|
||||
|
||||
public const string OPTION_CONDITION_COUNT = "ConditionCount";
|
||||
|
||||
// 조건별 포트 이름 규칙 (임포터와 공유)
|
||||
public static string TargetPort(int i) => $"Target{i}";
|
||||
public static string ComparePort(int i) => $"Compare{i}";
|
||||
public static string ValuePort(int i) => $"Value{i}";
|
||||
public static string JoinPort(int i) => $"Join{i}";
|
||||
|
||||
protected override void OnDefineOptions(IOptionDefinitionContext context)
|
||||
{
|
||||
context.AddOption<int>(OPTION_CONDITION_COUNT)
|
||||
.WithDisplayName("Condition Count")
|
||||
.WithTooltip("검사할 호감도 조건 개수 (캐릭터마다 하나씩)")
|
||||
.WithDefaultValue(1)
|
||||
.Delayed();
|
||||
}
|
||||
|
||||
protected override void OnDefinePorts(IPortDefinitionContext context)
|
||||
{
|
||||
AddExecInput(context);
|
||||
|
||||
int conditionCount = 1;
|
||||
GetNodeOptionByName(OPTION_CONDITION_COUNT)?.TryGetValue(out conditionCount);
|
||||
if (conditionCount < 1) conditionCount = 1;
|
||||
|
||||
for (int i = 0; i < conditionCount; i++)
|
||||
{
|
||||
context.AddInputPort<CharacterData>(TargetPort(i))
|
||||
.WithDisplayName($"Target {i + 1}")
|
||||
.WithTooltip("누구의 호감도를 검사할지. 비우면 대화 주인 NPC")
|
||||
.Build();
|
||||
context.AddInputPort<AffectionCompare>(ComparePort(i))
|
||||
.WithDisplayName($"Compare {i + 1}")
|
||||
.WithTooltip("호감도를 아래 값과 어떻게 비교할지")
|
||||
.Build();
|
||||
context.AddInputPort<int>(ValuePort(i))
|
||||
.WithDisplayName($"Affection {i + 1}")
|
||||
.WithTooltip("비교 기준값")
|
||||
.Build();
|
||||
|
||||
// 조건 사이에만 연결자를 둔다 (마지막 조건 뒤에는 이어질 게 없으므로 생략)
|
||||
if (i < conditionCount - 1)
|
||||
{
|
||||
context.AddInputPort<AffectionJoin>(JoinPort(i))
|
||||
.WithDisplayName($"Join {i + 1}")
|
||||
.WithTooltip("다음 조건과 묶는 방식. AND가 OR보다 우선")
|
||||
.Build();
|
||||
}
|
||||
}
|
||||
|
||||
AddExecOutput(context, PORT_PASS_OUT, "True →");
|
||||
AddExecOutput(context, PORT_FAIL_OUT, "False →");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 25bc0691603f93e4196ae428c028e855
|
||||
@@ -10,7 +10,7 @@ namespace DinoLove.Dialog.GraphTool.Editor
|
||||
// .dlg 그래프 에셋을 기존 런타임 타입(DialogGroup / DialogNode / DialogChoice)으로 변환한다.
|
||||
// 생성된 DialogNode들은 서브에셋으로, DialogGroup이 메인 에셋으로 등록된다.
|
||||
// 따라서 DialogPlayer는 수정 없이 임포트된 .dlg 에셋(= DialogGroup)을 그대로 사용한다.
|
||||
[ScriptedImporter(10, DialogGraph.AssetExtension)] // 버전 올리면 기존 .dlg 에셋이 재임포트됨
|
||||
[ScriptedImporter(13, DialogGraph.AssetExtension)] // 버전 올리면 기존 .dlg 에셋이 재임포트됨
|
||||
internal class DialogGraphImporter : ScriptedImporter
|
||||
{
|
||||
public override void OnImportAsset(AssetImportContext ctx)
|
||||
@@ -47,7 +47,8 @@ public override void OnImportAsset(AssetImportContext ctx)
|
||||
while (queue.Count > 0)
|
||||
{
|
||||
var gn = queue.Dequeue();
|
||||
if (gn == null || map.ContainsKey(gn) || (gn is not DialogLineNode && gn is not DialogStagingNode))
|
||||
if (gn == null || map.ContainsKey(gn)
|
||||
|| (gn is not DialogLineNode && gn is not DialogStagingNode && gn is not DialogAffectionNode))
|
||||
continue;
|
||||
|
||||
var dn = ScriptableObject.CreateInstance<DialogNode>();
|
||||
@@ -82,6 +83,39 @@ public override void OnImportAsset(AssetImportContext ctx)
|
||||
continue;
|
||||
}
|
||||
|
||||
// 호감도 분기 노드 — 대사 없이 라우팅만: 조건 통과 → AffectionPassBranch, 실패 → Next
|
||||
if (gn is DialogAffectionNode affectionNode)
|
||||
{
|
||||
dn.AffectionCheck = true;
|
||||
|
||||
int conditionCount = 1;
|
||||
var countOption = affectionNode.GetNodeOptionByName(DialogAffectionNode.OPTION_CONDITION_COUNT);
|
||||
if (countOption != null && countOption.TryGetValue(out int storedCount) && storedCount > 0)
|
||||
conditionCount = storedCount;
|
||||
|
||||
dn.AffectionRequirements = new List<AffectionRequirement>(conditionCount);
|
||||
for (int i = 0; i < conditionCount; i++)
|
||||
{
|
||||
dn.AffectionRequirements.Add(new AffectionRequirement
|
||||
{
|
||||
Character = GetInputPortValue<CharacterData>(gn.GetInputPortByName(DialogAffectionNode.TargetPort(i))),
|
||||
Compare = GetInputPortValue<AffectionCompare>(gn.GetInputPortByName(DialogAffectionNode.ComparePort(i))),
|
||||
Value = GetInputPortValue<int>(gn.GetInputPortByName(DialogAffectionNode.ValuePort(i))),
|
||||
// 마지막 조건에는 Join 포트가 없다 → 기본 And (평가 시 무시됨)
|
||||
JoinWithNext = i < conditionCount - 1
|
||||
? GetInputPortValue<AffectionJoin>(gn.GetInputPortByName(DialogAffectionNode.JoinPort(i)))
|
||||
: AffectionJoin.And
|
||||
});
|
||||
}
|
||||
|
||||
var passDest = GetConnectedNode(gn, DialogAffectionNode.PORT_PASS_OUT);
|
||||
dn.AffectionPassBranch = passDest != null && map.TryGetValue(passDest, out var passDn) ? passDn : null;
|
||||
|
||||
var failDest = GetConnectedNode(gn, DialogAffectionNode.PORT_FAIL_OUT);
|
||||
dn.Next = failDest != null && map.TryGetValue(failDest, out var failDn) ? failDn : null;
|
||||
continue;
|
||||
}
|
||||
|
||||
var line = (DialogLineNode)gn;
|
||||
|
||||
dn.Speaker = GetInputPortValue<CharacterData>(gn.GetInputPortByName(DialogLineNode.PORT_SPEAKER));
|
||||
@@ -184,6 +218,14 @@ static IEnumerable<INode> GetSuccessors(INode node)
|
||||
yield break;
|
||||
}
|
||||
|
||||
// 호감도 분기 노드는 두 출력 모두 후속
|
||||
if (node is DialogAffectionNode)
|
||||
{
|
||||
yield return GetConnectedNode(node, DialogAffectionNode.PORT_PASS_OUT);
|
||||
yield return GetConnectedNode(node, DialogAffectionNode.PORT_FAIL_OUT);
|
||||
yield break;
|
||||
}
|
||||
|
||||
if (node is not DialogLineNode line)
|
||||
yield break;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user