Add support for images in dialogue windows (#19)
- Extend editor nodes with custom DialogueContent data type that holds either image or text - Extend the dialogue importer to correctly process the new content into updated RuntimeDialogue content - Update SpeechBubble to be able to display either text or image - Add a custom property drawer for the DialogueContent to allow easy switching in graph authoring Co-authored-by: Michal Pikulski <michal@foolhardyhorizons.com> Reviewed-on: #19
This commit is contained in:
130
Assets/Editor/Dialogue/DialogueContentDrawer.cs
Normal file
130
Assets/Editor/Dialogue/DialogueContentDrawer.cs
Normal file
@@ -0,0 +1,130 @@
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Dialogue.Editor
|
||||
{
|
||||
/// <summary>
|
||||
/// Custom property drawer for DialogueContent that displays either text or image fields based on content type
|
||||
/// </summary>
|
||||
[CustomPropertyDrawer(typeof(DialogueContent))]
|
||||
public class DialogueContentDrawer : PropertyDrawer
|
||||
{
|
||||
// Height constants
|
||||
private const float TypeSelectorHeight = 20f;
|
||||
private const float PropertySpacing = 2f;
|
||||
private const float TextFieldHeight = 40f; // Taller for multi-line text
|
||||
private const float ImageFieldHeight = 18f;
|
||||
private const float PreviewHeight = 64f;
|
||||
|
||||
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
|
||||
{
|
||||
var contentTypeProperty = property.FindPropertyRelative("_contentType");
|
||||
var height = TypeSelectorHeight + PropertySpacing;
|
||||
|
||||
// Add height based on content type
|
||||
if (contentTypeProperty.enumValueIndex == (int)DialogueContentType.Text)
|
||||
{
|
||||
height += TextFieldHeight;
|
||||
}
|
||||
else // Image
|
||||
{
|
||||
height += ImageFieldHeight;
|
||||
|
||||
// Add preview height if an image is assigned
|
||||
var imageProperty = property.FindPropertyRelative("_image");
|
||||
if (imageProperty.objectReferenceValue != null)
|
||||
{
|
||||
height += PropertySpacing + PreviewHeight;
|
||||
}
|
||||
}
|
||||
|
||||
return height;
|
||||
}
|
||||
|
||||
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
|
||||
{
|
||||
EditorGUI.BeginProperty(position, label, property);
|
||||
|
||||
// Create a property field and indent it
|
||||
var contentRect = EditorGUI.PrefixLabel(position, GUIUtility.GetControlID(FocusType.Passive), label);
|
||||
var indent = EditorGUI.indentLevel;
|
||||
EditorGUI.indentLevel = 0;
|
||||
|
||||
// Get properties
|
||||
var contentTypeProperty = property.FindPropertyRelative("_contentType");
|
||||
var textProperty = property.FindPropertyRelative("_text");
|
||||
var imageProperty = property.FindPropertyRelative("_image");
|
||||
|
||||
// Calculate rects
|
||||
var typeRect = new Rect(contentRect.x, contentRect.y, contentRect.width, TypeSelectorHeight);
|
||||
var contentFieldRect = new Rect(
|
||||
contentRect.x,
|
||||
contentRect.y + TypeSelectorHeight + PropertySpacing,
|
||||
contentRect.width,
|
||||
contentTypeProperty.enumValueIndex == (int)DialogueContentType.Text ? TextFieldHeight : ImageFieldHeight);
|
||||
|
||||
// Draw the content type dropdown
|
||||
EditorGUI.PropertyField(typeRect, contentTypeProperty, GUIContent.none);
|
||||
|
||||
// Draw the appropriate field based on content type
|
||||
if (contentTypeProperty.enumValueIndex == (int)DialogueContentType.Text)
|
||||
{
|
||||
// Create a custom style with word wrap enabled
|
||||
GUIStyle wordWrapStyle = new GUIStyle(EditorStyles.textArea);
|
||||
wordWrapStyle.wordWrap = true;
|
||||
|
||||
// Text field with word wrap for multi-line input
|
||||
textProperty.stringValue = EditorGUI.TextArea(contentFieldRect, textProperty.stringValue, wordWrapStyle);
|
||||
}
|
||||
else // Image
|
||||
{
|
||||
// Draw the image field
|
||||
EditorGUI.PropertyField(contentFieldRect, imageProperty, GUIContent.none);
|
||||
|
||||
// Draw a preview if an image is assigned
|
||||
if (imageProperty.objectReferenceValue != null)
|
||||
{
|
||||
var sprite = imageProperty.objectReferenceValue as Sprite;
|
||||
if (sprite != null)
|
||||
{
|
||||
var previewRect = new Rect(
|
||||
contentRect.x,
|
||||
contentFieldRect.y + contentFieldRect.height + PropertySpacing,
|
||||
contentRect.width,
|
||||
PreviewHeight);
|
||||
|
||||
// Draw the preview with preserved aspect ratio
|
||||
DrawSpritePreview(previewRect, sprite);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EditorGUI.indentLevel = indent;
|
||||
EditorGUI.EndProperty();
|
||||
}
|
||||
|
||||
private void DrawSpritePreview(Rect position, Sprite sprite)
|
||||
{
|
||||
if (sprite == null || sprite.texture == null) return;
|
||||
|
||||
// Calculate aspect-preserved rect
|
||||
float aspectRatio = sprite.rect.width / sprite.rect.height;
|
||||
float targetWidth = Mathf.Min(position.width, position.height * aspectRatio);
|
||||
float targetHeight = targetWidth / aspectRatio;
|
||||
|
||||
// Center the preview
|
||||
Rect previewRect = new Rect(
|
||||
position.x + (position.width - targetWidth) * 0.5f,
|
||||
position.y + (position.height - targetHeight) * 0.5f,
|
||||
targetWidth,
|
||||
targetHeight
|
||||
);
|
||||
|
||||
// Draw the sprite preview
|
||||
EditorGUI.DrawPreviewTexture(previewRect, sprite.texture, null, ScaleMode.ScaleToFit);
|
||||
|
||||
// Draw a border around the preview
|
||||
GUI.Box(previewRect, GUIContent.none);
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Assets/Editor/Dialogue/DialogueContentDrawer.cs.meta
Normal file
3
Assets/Editor/Dialogue/DialogueContentDrawer.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f77e7b681b7f464f96242172ea625ed4
|
||||
timeCreated: 1759912655
|
||||
@@ -111,24 +111,42 @@ namespace Editor.Dialogue
|
||||
var lineCountOption = node.GetNodeOptionByName("NoLines");
|
||||
lineCountOption.TryGetValue<int>(out var lineCount);
|
||||
|
||||
// Process dialogue lines based on line type
|
||||
// Process dialogue content
|
||||
if (lineType == DialogueType.SayMultipleLines)
|
||||
{
|
||||
for (var i = 0; i < lineCount; i++)
|
||||
{
|
||||
var lineValue = GetPortValue<string>(node.GetInputPortByName($"DefaultDialogueLine{i + 1}"));
|
||||
if (!string.IsNullOrEmpty(lineValue))
|
||||
var contentPort = node.GetInputPortByName($"DefaultDialogueContent{i + 1}");
|
||||
var contentValue = GetPortValue<DialogueContent>(contentPort);
|
||||
|
||||
if (contentValue != null)
|
||||
{
|
||||
runtimeNode.dialogueLines.Add(lineValue);
|
||||
// Add to dialogueContent list
|
||||
runtimeNode.dialogueContent.Add(contentValue);
|
||||
|
||||
// Also add to legacy dialogueLines list for backward compatibility
|
||||
if (contentValue.ContentType == DialogueContentType.Text && !string.IsNullOrEmpty(contentValue.Text))
|
||||
{
|
||||
runtimeNode.dialogueLines.Add(contentValue.Text);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var lineValue = GetPortValue<string>(node.GetInputPortByName("DefaultDialogueLine"));
|
||||
if (!string.IsNullOrEmpty(lineValue))
|
||||
var contentPort = node.GetInputPortByName("DefaultDialogueContent");
|
||||
var contentValue = GetPortValue<DialogueContent>(contentPort);
|
||||
|
||||
if (contentValue != null)
|
||||
{
|
||||
runtimeNode.dialogueLines.Add(lineValue);
|
||||
// Add to dialogueContent list
|
||||
runtimeNode.dialogueContent.Add(contentValue);
|
||||
|
||||
// Also add to legacy dialogueLines list for backward compatibility
|
||||
if (contentValue.ContentType == DialogueContentType.Text && !string.IsNullOrEmpty(contentValue.Text))
|
||||
{
|
||||
runtimeNode.dialogueLines.Add(contentValue.Text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -169,60 +187,98 @@ namespace Editor.Dialogue
|
||||
runtimeNode.slotItemID = slot.itemId;
|
||||
}
|
||||
|
||||
// Process incorrect item lines
|
||||
// Get line type and count options for incorrect items
|
||||
var incorrectItemLineTypeOption = node.GetNodeOptionByName("IncorrectItemDialogueLineType");
|
||||
incorrectItemLineTypeOption.TryGetValue<DialogueType>(out var incorrectItemLineType);
|
||||
|
||||
var incorrectItemLineCountOption = node.GetNodeOptionByName("IncorrectItemNoLines");
|
||||
incorrectItemLineCountOption.TryGetValue<int>(out var incorrectItemLineCount);
|
||||
|
||||
// Process incorrect item content
|
||||
if (incorrectItemLineType == DialogueType.SayMultipleLines)
|
||||
{
|
||||
for (var i = 0; i < incorrectItemLineCount; i++)
|
||||
{
|
||||
var lineValue = GetPortValue<string>(node.GetInputPortByName($"IncorrectItemDialogueLine{i + 1}"));
|
||||
if (!string.IsNullOrEmpty(lineValue))
|
||||
var contentPort = node.GetInputPortByName($"IncorrectItemDialogueContent{i + 1}");
|
||||
var contentValue = GetPortValue<DialogueContent>(contentPort);
|
||||
|
||||
if (contentValue != null)
|
||||
{
|
||||
runtimeNode.incorrectItemLines.Add(lineValue);
|
||||
// Add to incorrectItemContent list
|
||||
runtimeNode.incorrectItemContent.Add(contentValue);
|
||||
|
||||
// Also add to legacy incorrectItemLines list for backward compatibility
|
||||
if (contentValue.ContentType == DialogueContentType.Text && !string.IsNullOrEmpty(contentValue.Text))
|
||||
{
|
||||
runtimeNode.incorrectItemLines.Add(contentValue.Text);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var lineValue = GetPortValue<string>(node.GetInputPortByName("IncorrectItemDialogueLine"));
|
||||
if (!string.IsNullOrEmpty(lineValue))
|
||||
var contentPort = node.GetInputPortByName("IncorrectItemDialogueContent");
|
||||
var contentValue = GetPortValue<DialogueContent>(contentPort);
|
||||
|
||||
if (contentValue != null)
|
||||
{
|
||||
runtimeNode.incorrectItemLines.Add(lineValue);
|
||||
// Add to incorrectItemContent list
|
||||
runtimeNode.incorrectItemContent.Add(contentValue);
|
||||
|
||||
// Also add to legacy incorrectItemLines list for backward compatibility
|
||||
if (contentValue.ContentType == DialogueContentType.Text && !string.IsNullOrEmpty(contentValue.Text))
|
||||
{
|
||||
runtimeNode.incorrectItemLines.Add(contentValue.Text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
runtimeNode.loopThroughIncorrectLines =
|
||||
GetPortValue<bool>(node.GetInputPortByName("LoopThroughIncorrectItemLines"));
|
||||
|
||||
// Process forbidden item lines
|
||||
// Get line type and count options for forbidden items
|
||||
var forbiddenItemLineTypeOption = node.GetNodeOptionByName("ForbiddenItemDialogueLineType");
|
||||
forbiddenItemLineTypeOption.TryGetValue<DialogueType>(out var forbiddenItemLineType);
|
||||
|
||||
var forbiddenItemLineCountOption = node.GetNodeOptionByName("ForbiddenItemNoLines");
|
||||
forbiddenItemLineCountOption.TryGetValue<int>(out var forbiddenItemLineCount);
|
||||
|
||||
// Process forbidden item content
|
||||
if (forbiddenItemLineType == DialogueType.SayMultipleLines)
|
||||
{
|
||||
for (var i = 0; i < forbiddenItemLineCount; i++)
|
||||
{
|
||||
var lineValue = GetPortValue<string>(node.GetInputPortByName($"ForbiddenItemDialogueLine{i + 1}"));
|
||||
if (!string.IsNullOrEmpty(lineValue))
|
||||
var contentPort = node.GetInputPortByName($"ForbiddenItemDialogueContent{i + 1}");
|
||||
var contentValue = GetPortValue<DialogueContent>(contentPort);
|
||||
|
||||
if (contentValue != null)
|
||||
{
|
||||
runtimeNode.forbiddenItemLines.Add(lineValue);
|
||||
// Add to forbiddenItemContent list
|
||||
runtimeNode.forbiddenItemContent.Add(contentValue);
|
||||
|
||||
// Also add to legacy forbiddenItemLines list for backward compatibility
|
||||
if (contentValue.ContentType == DialogueContentType.Text && !string.IsNullOrEmpty(contentValue.Text))
|
||||
{
|
||||
runtimeNode.forbiddenItemLines.Add(contentValue.Text);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var lineValue = GetPortValue<string>(node.GetInputPortByName("ForbiddenItemDialogueLine"));
|
||||
if (!string.IsNullOrEmpty(lineValue))
|
||||
var contentPort = node.GetInputPortByName("ForbiddenItemDialogueContent");
|
||||
var contentValue = GetPortValue<DialogueContent>(contentPort);
|
||||
|
||||
if (contentValue != null)
|
||||
{
|
||||
runtimeNode.forbiddenItemLines.Add(lineValue);
|
||||
// Add to forbiddenItemContent list
|
||||
runtimeNode.forbiddenItemContent.Add(contentValue);
|
||||
|
||||
// Also add to legacy forbiddenItemLines list for backward compatibility
|
||||
if (contentValue.ContentType == DialogueContentType.Text && !string.IsNullOrEmpty(contentValue.Text))
|
||||
{
|
||||
runtimeNode.forbiddenItemLines.Add(contentValue.Text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -259,4 +315,4 @@ namespace Editor.Dialogue
|
||||
return fallbackValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using UnityEngine;
|
||||
using Unity.GraphToolkit.Editor;
|
||||
using System;
|
||||
using Dialogue;
|
||||
|
||||
namespace Editor.Dialogue
|
||||
{
|
||||
@@ -37,8 +38,7 @@ namespace Editor.Dialogue
|
||||
const string LineTypeOptionName = "DialogueLineType";
|
||||
const string NoLinesOptionName = "NoLines";
|
||||
const string LoopThroughDefaultLinesOptionName = "LoopThroughDefaultLines";
|
||||
const string DefaultDialogueLineOptionName = "DefaultDialogueLine";
|
||||
|
||||
const string DefaultDialogueContentOptionName = "DefaultDialogueContent";
|
||||
|
||||
protected override void OnDefineOptions(IOptionDefinitionContext context)
|
||||
{
|
||||
@@ -47,7 +47,6 @@ namespace Editor.Dialogue
|
||||
.WithDefaultValue(DialogueType.SayOneLine)
|
||||
.Delayed();
|
||||
|
||||
|
||||
context.AddOption<int>(NoLinesOptionName)
|
||||
.WithDisplayName("Number of Default Lines")
|
||||
.WithDefaultValue(1)
|
||||
@@ -59,6 +58,7 @@ namespace Editor.Dialogue
|
||||
context.AddInputPort("in").Build();
|
||||
context.AddOutputPort("out").Build();
|
||||
|
||||
// Get line type and count options
|
||||
var lineTypeOption = GetNodeOptionByName(LineTypeOptionName);
|
||||
lineTypeOption.TryGetValue<DialogueType>(out var lineType);
|
||||
var lineCountOption = GetNodeOptionByName(NoLinesOptionName);
|
||||
@@ -68,15 +68,21 @@ namespace Editor.Dialogue
|
||||
{
|
||||
for (var i = 0; i < lineCount; i++)
|
||||
{
|
||||
context.AddInputPort<string>($"{DefaultDialogueLineOptionName}{i + 1}").WithDisplayName($"Default Dialogue Line {i + 1}").Build();
|
||||
context.AddInputPort<DialogueContent>($"{DefaultDialogueContentOptionName}{i + 1}")
|
||||
.WithDisplayName($"Dialogue Content {i + 1}")
|
||||
.Build();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
context.AddInputPort<string>($"{DefaultDialogueLineOptionName}").WithDisplayName("Default Dialogue Line").Build();
|
||||
context.AddInputPort<DialogueContent>($"{DefaultDialogueContentOptionName}")
|
||||
.WithDisplayName("Dialogue Content")
|
||||
.Build();
|
||||
}
|
||||
|
||||
context.AddInputPort<bool>($"{LoopThroughDefaultLinesOptionName}").WithDisplayName("Loop Through Default Lines?").Build();
|
||||
context.AddInputPort<bool>($"{LoopThroughDefaultLinesOptionName}")
|
||||
.WithDisplayName("Loop Through Content?")
|
||||
.Build();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,38 +116,39 @@ namespace Editor.Dialogue
|
||||
public class WaitOnSlot : DialogueNode
|
||||
{
|
||||
const string RequiredSlotOptionName = "RequiredSlot";
|
||||
// Incorrect item - i.e. not the correct one but also not forbidden
|
||||
const string IncorrectItemLineTypeOptionName = "IncorrectItemDialogueLineType";
|
||||
const string IncorrectItemNoLinesOptionName = "IncorrectItemNoLines";
|
||||
const string LoopThroughIncorrectItemLinesOptionName = "LoopThroughIncorrectItemLines";
|
||||
const string IncorrectIteDialogueLineOptionName = "IncorrectItemDialogueLine";
|
||||
// Explicitely forbidden item
|
||||
const string IncorrectItemDialogueContentOptionName = "IncorrectItemDialogueContent";
|
||||
|
||||
const string ForbiddenItemLineTypeOptionName = "ForbiddenItemDialogueLineType";
|
||||
const string ForbiddenItemNoLinesOptionName = "ForbiddenItemNoLines";
|
||||
const string LoopThroughForbiddenItemLinesOptionName = "LoopThroughForbiddenItemLines";
|
||||
const string ForbiddenIteDialogueLineOptionName = "ForbiddenItemDialogueLine";
|
||||
const string ForbiddenItemDialogueContentOptionName = "ForbiddenItemDialogueContent";
|
||||
|
||||
protected override void OnDefineOptions(IOptionDefinitionContext context)
|
||||
{
|
||||
base.OnDefineOptions(context);
|
||||
|
||||
// Incorrect
|
||||
// Incorrect item options
|
||||
context.AddOption<DialogueType>(IncorrectItemLineTypeOptionName)
|
||||
.WithDisplayName("Incorrect Item Line Type")
|
||||
.WithDefaultValue(DialogueType.SayOneLine)
|
||||
.Delayed();
|
||||
|
||||
context.AddOption<int>(IncorrectItemNoLinesOptionName)
|
||||
.WithDisplayName("Number of Incorrect Item Lines")
|
||||
.WithDefaultValue(1)
|
||||
.Delayed();
|
||||
|
||||
// Forbidden
|
||||
|
||||
// Forbidden item options
|
||||
context.AddOption<DialogueType>(ForbiddenItemLineTypeOptionName)
|
||||
.WithDisplayName("Forbidden Item Line Type")
|
||||
.WithDefaultValue(DialogueType.SayOneLine)
|
||||
.Delayed();
|
||||
|
||||
context.AddOption<int>(ForbiddenItemNoLinesOptionName)
|
||||
.WithDisplayName("Forbidden of Incorrect Item Lines")
|
||||
.WithDisplayName("Number of Forbidden Item Lines")
|
||||
.WithDefaultValue(1)
|
||||
.Delayed();
|
||||
}
|
||||
@@ -152,45 +159,59 @@ namespace Editor.Dialogue
|
||||
|
||||
base.OnDefinePorts(context);
|
||||
|
||||
// Incorrect
|
||||
// Process Incorrect Item content
|
||||
var incorrectItemLineTypeOption = GetNodeOptionByName(IncorrectItemLineTypeOptionName);
|
||||
incorrectItemLineTypeOption.TryGetValue<DialogueType>(out var incorrectItemLineType);
|
||||
var incorrectItemLineCountOption = GetNodeOptionByName(IncorrectItemNoLinesOptionName);
|
||||
incorrectItemLineCountOption.TryGetValue<int>(out var incorrectItemLineCount);
|
||||
|
||||
// Add DialogueContent ports for incorrect item content
|
||||
if (incorrectItemLineType == DialogueType.SayMultipleLines)
|
||||
{
|
||||
for (var i = 0; i < incorrectItemLineCount; i++)
|
||||
{
|
||||
context.AddInputPort<string>($"{IncorrectIteDialogueLineOptionName}{i + 1}").WithDisplayName($"Incorrect Item Dialogue Line {i + 1}").Build();
|
||||
context.AddInputPort<DialogueContent>($"{IncorrectItemDialogueContentOptionName}{i + 1}")
|
||||
.WithDisplayName($"Incorrect Item Content {i + 1}")
|
||||
.Build();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
context.AddInputPort<string>($"{IncorrectIteDialogueLineOptionName}").WithDisplayName("Incorrect Item Dialogue Line").Build();
|
||||
context.AddInputPort<DialogueContent>($"{IncorrectItemDialogueContentOptionName}")
|
||||
.WithDisplayName("Incorrect Item Content")
|
||||
.Build();
|
||||
}
|
||||
|
||||
context.AddInputPort<bool>($"{LoopThroughIncorrectItemLinesOptionName}").WithDisplayName("Loop Through Incorrect Item Lines?").Build();
|
||||
context.AddInputPort<bool>($"{LoopThroughIncorrectItemLinesOptionName}")
|
||||
.WithDisplayName("Loop Through Incorrect Content?")
|
||||
.Build();
|
||||
|
||||
// Forbidden
|
||||
// Process Forbidden Item content
|
||||
var forbiddenItemLineTypeOption = GetNodeOptionByName(ForbiddenItemLineTypeOptionName);
|
||||
forbiddenItemLineTypeOption.TryGetValue<DialogueType>(out var forbiddenItemLineType);
|
||||
var forbiddenItemLineCountOption = GetNodeOptionByName(ForbiddenItemNoLinesOptionName);
|
||||
forbiddenItemLineCountOption.TryGetValue<int>(out var forbiddenItemLineCount);
|
||||
|
||||
// Add DialogueContent ports for forbidden item content
|
||||
if (forbiddenItemLineType == DialogueType.SayMultipleLines)
|
||||
{
|
||||
for (var i = 0; i < forbiddenItemLineCount; i++)
|
||||
{
|
||||
context.AddInputPort<string>($"{ForbiddenIteDialogueLineOptionName}{i + 1}").WithDisplayName($"Forbidden Item Dialogue Line {i + 1}").Build();
|
||||
context.AddInputPort<DialogueContent>($"{ForbiddenItemDialogueContentOptionName}{i + 1}")
|
||||
.WithDisplayName($"Forbidden Item Content {i + 1}")
|
||||
.Build();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
context.AddInputPort<string>($"{ForbiddenIteDialogueLineOptionName}").WithDisplayName("Forbidden Item Dialogue Line").Build();
|
||||
context.AddInputPort<DialogueContent>($"{ForbiddenItemDialogueContentOptionName}")
|
||||
.WithDisplayName("Forbidden Item Content")
|
||||
.Build();
|
||||
}
|
||||
|
||||
context.AddInputPort<bool>($"{LoopThroughForbiddenItemLinesOptionName}").WithDisplayName("Loop Through Forbidden Item Lines?").Build();
|
||||
context.AddInputPort<bool>($"{LoopThroughForbiddenItemLinesOptionName}")
|
||||
.WithDisplayName("Loop Through Forbidden Content?")
|
||||
.Build();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user