히든제스처

This commit is contained in:
2026-07-23 13:08:43 +09:00
parent e1c43c9b3d
commit de5fe5b85a
109 changed files with 10034 additions and 135 deletions

View File

@@ -10,7 +10,7 @@ namespace DinoLove.Dialog.GraphTool.Editor
// .dlg 그래프 에셋을 기존 런타임 타입(DialogGroup / DialogNode / DialogChoice)으로 변환한다.
// 생성된 DialogNode들은 서브에셋으로, DialogGroup이 메인 에셋으로 등록된다.
// 따라서 DialogPlayer는 수정 없이 임포트된 .dlg 에셋(= DialogGroup)을 그대로 사용한다.
[ScriptedImporter(8, DialogGraph.AssetExtension)] // 버전 올리면 기존 .dlg 에셋이 재임포트됨
[ScriptedImporter(9, DialogGraph.AssetExtension)] // 버전 올리면 기존 .dlg 에셋이 재임포트됨
internal class DialogGraphImporter : ScriptedImporter
{
public override void OnImportAsset(AssetImportContext ctx)
@@ -128,6 +128,23 @@ public override void OnImportAsset(AssetImportContext ctx)
});
}
}
// 히든 분기 (켜져 있으면) — 목적지 노드 + 제스처 키 + 기록 코드
bool hasHidden = false;
line.GetNodeOptionByName(DialogLineNode.OPTION_HIDDEN_BRANCH)?.TryGetValue(out hasHidden);
if (hasHidden)
{
var hiddenDest = GetConnectedNode(gn, DialogLineNode.PORT_HIDDEN_OUT);
dn.HiddenBranch = hiddenDest != null && map.TryGetValue(hiddenDest, out var hiddenDn) ? hiddenDn : null;
string gestureKey = null;
line.GetNodeOptionByName(DialogLineNode.OPTION_HIDDEN_GESTURE)?.TryGetValue(out gestureKey);
dn.HiddenGestureKey = gestureKey;
string hiddenCode = null;
line.GetNodeOptionByName(DialogLineNode.OPTION_HIDDEN_CODE)?.TryGetValue(out hiddenCode);
dn.HiddenCode = hiddenCode;
}
}
group.StartNode = map.TryGetValue(firstGraphNode, out var startDn) ? startDn : null;
@@ -178,6 +195,12 @@ static IEnumerable<INode> GetSuccessors(INode node)
for (int i = 0; i < choiceCount; i++)
yield return GetConnectedNode(node, DialogLineNode.ChoiceOutPort(i));
}
// 히든 분기 후속도 도달 가능해야 DialogNode로 생성된다
bool hasHidden = false;
line.GetNodeOptionByName(DialogLineNode.OPTION_HIDDEN_BRANCH)?.TryGetValue(out hasHidden);
if (hasHidden)
yield return GetConnectedNode(node, DialogLineNode.PORT_HIDDEN_OUT);
}
// 출력 실행 포트에 연결된 노드 (없으면 null)

View File

@@ -30,9 +30,13 @@ internal class DialogLineNode : DialogGraphNode
public const string PORT_AFFECTION = "Affection";
public const string PORT_PROGRESS = "Progress";
public const string PORT_QUESTION = "ChoiceQuestion";
public const string PORT_HIDDEN_OUT = "HiddenOut";
public const string OPTION_CHOICE_COUNT = "ChoiceCount";
public const string OPTION_EVENT_KEY = "EventKey";
public const string OPTION_CHOICE_COUNT = "ChoiceCount";
public const string OPTION_EVENT_KEY = "EventKey";
public const string OPTION_HIDDEN_BRANCH = "HasHiddenBranch";
public const string OPTION_HIDDEN_GESTURE = "HiddenGestureKey";
public const string OPTION_HIDDEN_CODE = "HiddenCode";
// 선택지별 포트 이름 규칙 (임포터와 공유)
public static string ChoiceTextPort(int i) => $"Choice{i}Text";
@@ -51,6 +55,22 @@ protected override void OnDefineOptions(IOptionDefinitionContext context)
.WithDisplayName("Event Key")
.WithTooltip("비우면 없음. 이 노드 재생 시 DialogPlayer의 같은 Key 이벤트 호출 (영문 키 권장)")
.Delayed();
context.AddOption<bool>(OPTION_HIDDEN_BRANCH)
.WithDisplayName("Hidden Branch")
.WithTooltip("켜면 맨 아래에 'Hidden →' 출력 포트가 생긴다. 이 대사 재생 중 특정 제스처(싸대기/터치)를 하면 " +
"Next/선택지 대신 그 포트로 연결된 노드로 몰래 분기한다")
.WithDefaultValue(false);
context.AddOption<string>(OPTION_HIDDEN_GESTURE)
.WithDisplayName("Hidden Gesture Key")
.WithTooltip("히든 분기를 여는 제스처 키 (DialogGestureZone의 Gesture Key와 일치). 비우면 아무 제스처 존이나 발동")
.Delayed();
context.AddOption<string>(OPTION_HIDDEN_CODE)
.WithDisplayName("Hidden Code")
.WithTooltip("히든 분기를 탔을 때 기록할 선택지 Code (이후 대화 조건 RequiredChoiceCodes에서 검사). 비우면 기록 안 함")
.Delayed();
}
protected override void OnDefinePorts(IPortDefinitionContext context)
@@ -88,23 +108,31 @@ protected override void OnDefinePorts(IPortDefinitionContext context)
{
// 선형 진행
AddExecOutput(context, EXEC_OUT, string.Empty);
return;
}
// 가변 N지선다
// (string 포트는 GraphToolkit 기본 에디터의 IME 중복입력 버그가 있어 DialogText로 통일)
context.AddInputPort<DialogText>(PORT_QUESTION).WithDisplayName("Choice Question").Build();
for (int i = 0; i < choiceCount; i++)
else
{
context.AddInputPort<DialogText>(ChoiceTextPort(i))
.WithDisplayName($"Choice {i + 1} Text")
.Build();
context.AddInputPort<string>(ChoiceCodePort(i))
.WithDisplayName($"Choice {i + 1} Code")
.Build();
AddExecOutput(context, ChoiceOutPort(i), $"Choice {i + 1} →");
// 가변 N지선다
// (string 포트는 GraphToolkit 기본 에디터의 IME 중복입력 버그가 있어 DialogText로 통일)
context.AddInputPort<DialogText>(PORT_QUESTION).WithDisplayName("Choice Question").Build();
for (int i = 0; i < choiceCount; i++)
{
context.AddInputPort<DialogText>(ChoiceTextPort(i))
.WithDisplayName($"Choice {i + 1} Text")
.Build();
context.AddInputPort<string>(ChoiceCodePort(i))
.WithDisplayName($"Choice {i + 1} Code")
.Build();
AddExecOutput(context, ChoiceOutPort(i), $"Choice {i + 1} →");
}
}
// 히든 분기 출력 — 켜져 있으면 선형/선택지 관계없이 맨 아래에 붙는다.
// 이 포트에 연결된 노드가 DialogNode.HiddenBranch가 된다.
bool hasHidden = false;
GetNodeOptionByName(OPTION_HIDDEN_BRANCH)?.TryGetValue(out hasHidden);
if (hasHidden)
AddExecOutput(context, PORT_HIDDEN_OUT, "Hidden →");
}
}
}