+
+
Descant
+
Enhanced Unity Dialogue System
+
by Owen Hellum
+
+
+
+
+ Please view the Descant README for
+ information regarding installation and usage!
+
+
+
+
+
+
+
+ Descant is a Unity dialogue system plugin. The
+ Unity Asset Store is
+ chock full of many such
+ types of plugins, ranging from feature-rich,
+ to ultra-minimalist,
+ to downright bad.
+ Descant aims to hit the sweet spot between quality UI, powerful features, and easy-to-lean
+ functionality, while also addressing many of the game-specific consequences of the standard dialogue manager
+ setup. Besides acting as a standard tool for creating, saving, and actualizing non-linear game dialogue, it
+ also pushes the envelope by adding optional dialogue-enhancing node components that introduce features to break
+ away from the overused and underwhelming trends seen in many interactive fiction games. These enhancements act
+ similar to Unity's standard GameObject Component system, and can be applied
+ at-will to nodes. This modular approach is so-far not explored in the world of Unity dialogue systems. The
+ project will be free (and collaborative open-source) forever. Feel free to send me a message or submit
+ a pull request if you want to make any changes.
+
+
+
+
+
Component documentation
+
+ A number of Descant Components come bundled with the system by default. They cover a wide range of
+ applications, and can be edited at-will. Please see the next section, Component creation, for
+ a guide on how to write your own Components in C#.
+
+
+
+
+
+
+
Component creation
+
+ - Create a new C# class in Descant/Components/Custom.
+ - Make sure that the Component is in the DescantComponents namespace.
+ - Make sure that the Component inherits from the DescantComponent abstract class.
+ - Add a [Serializable] attribute to the Component.
+ -
+ Add a [MaxQuantity(...)] attribute to the Component (replace the '...' with the maximum number
+ of Components of this type that can be added to a single node) ('...' can be float.PositiveInfinity).
+
+ -
+ Add a [NodeType(...)] attribute to the Component (replace the '...' with the
+ DescantNodeType indicating which types of nodes it can be added to).
+
+ -
+ Add any number of public variables/properties to the Component (these properties will show up in
+ the Descant Graph Editor when you add the Component to a node) (you may also create
+ private/protected properties, but they won't appear in the editor). Properties may only be of type
+ int, float, string, bool, or
+ enum (VariableType, ComparisonType,
+ OperationType, or ListChangeType enums only).
+
+ -
+ For each public variable, add either an [Inline] attribute (indicating that it will be
+ visually nestled beside the Component name in the editor) or a [ParameterGroup(...)]
+ attribute (indicating that it will be visually arranged in a new group beneath the Component name in the
+ editor) (replace the '...' with the string name of the group to order it into).
+
+ -
+ Optional: By default, all Component fields filter any out most special characters on input. You can
+ override this by giving any public variable a [NoFiltering] attribute, disabling filtering
+ for that variable's corresponding field in the Descant Graph Editor. This is useful for
+ long-form fields that may have sentence grammar and punctuation.
+
+ -
+ If this Component performs some action when it is reached during dialogue, give it the following method:
+ public override DescantNodeInvokeResult Invoke(DescantNodeInvokeResult result). The
+ DescantNodeInvokeResult object being passed contains all the choice/response text for the
+ current node, the current actors, and info regarding the actor portraits) (see the
+ DescantNodeInvokeResult
+ class for more info). The Invoke method must return a DescantNodeInvokeResult
+ object (almost always just result itself, with its properties modified).
+
+ -
+ Optional: Many of the default Components require actor names to know which actors' properties to check.
+ If your Component must also access a DescantActor, make sure that it has a public
+ string ActorName variable, then get access to the actor with
+ DescantComponentUtilities.GetActor(this, result.Actors, ActorName).
+
+ -
+ Optional: Many default Descant Components only do their effect if some comparison is made. Should your
+ Component also wish to do so, the CompareVariable method in
+ DescantComponent
+ may be of use.
+
+ -
+ Optional: If you need the Component to do something continuously while it is active during dialogue, give
+ it one of the following methods: public override bool FixedUpdate() or public
+ override bool Update(). They function in exactly the same manner as the classic MonoBehaviour
+ methods of the same names, save for the fact that if they ever return false, the dialogue
+ ends immediately (should the Component want to end the dialogue for some reason).
+
+ -
+ That's it! Your new Component will now show up as an option to add to a node in the Descant Graph
+ Editor.
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Documentation/Website/index.html.meta b/Documentation/Website/index.html.meta
new file mode 100644
index 0000000..75fa60f
--- /dev/null
+++ b/Documentation/Website/index.html.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 100b742dd43d4fc7b8dddf7507b64a2a
+timeCreated: 1703632699
\ No newline at end of file
diff --git a/Documentation/Website/style.css b/Documentation/Website/style.css
new file mode 100644
index 0000000..2eeae61
--- /dev/null
+++ b/Documentation/Website/style.css
@@ -0,0 +1,124 @@
+:root {
+ --descant-color-background: #2b2b2b;
+ --descant-color-default: rgba(51, 51, 51, 0.4);
+ --descant-color-light: rgba(51, 51, 51, 1);
+
+ --descant-color-text: rgb(157, 157, 157);
+
+ --choice-highlight: lightskyblue;
+ --choice-background: rgba(90, 137, 166, 0.7);
+
+ --response-highlight: darkgoldenrod;
+ --response-background: rgba(164, 123, 19, 0.7);
+
+ --start-highlight: mediumseagreen;
+ --start-background: rgba(46, 134, 85, 0.7);
+
+ --end-highlight: firebrick;
+ --end-background: rgba(121, 23, 23, 0.7);
+
+ --unsaved: lightcoral;
+}
+
+
+/* Elements */
+
+body {
+ font-family: 'Open Sans', sans-serif;
+ font-weight: 400;
+
+ color: var(--descant-color-text);
+
+ background: var(--descant-color-background);
+}
+
+h1, h2, h3, p { margin: 0; }
+h2, h3 strong { font-weight: 700; }
+
+h1 {
+ font-weight: 800;
+ font-size: 60px;
+ color: var(--response-highlight);
+}
+
+h2 {
+ margin-bottom: 20px;
+
+ font-size: 30px;
+ color: var(--start-highlight);
+}
+
+h3 {
+ margin-bottom: 15px;
+
+ font-size: 25px;
+ color: var(--start-background);
+}
+
+p, li { font-size: 20px; }
+
+a {
+ color: var(--choice-highlight);
+}
+a:hover {
+ color: var(--choice-background);
+}
+
+li {
+ margin-bottom: 15px;
+
+ line-height: 30px;
+}
+
+
+/* Flex Classes */
+
+.flex { display: flex; }
+
+.column { flex-direction: column; }
+.row { flex-direction: row; flex-wrap: wrap; }
+
+.start, .align_start { align-items: start; }
+.center, .align_center { align-items: center; }
+.end, .align_end { align-items: end; }
+
+.start, .justify_start { justify-content: start; }
+.center, .justify_center { justify-content: center; }
+.end, .justify_end { justify-content: end; }
+
+
+/* Classes */
+
+.section {
+ margin: 20px;
+}
+
+.important {
+ padding: 20px;
+
+ border-radius: 10px;
+
+ color: var(--end-highlight);
+
+ background: black;
+}
+
+.component {
+ width: 100%;
+
+ margin: 10px;
+ padding: 15px;
+
+ border-radius: 10px;
+
+ background: var(--descant-color-light);
+}
+.component p {
+ margin: 8px;
+}
+
+/* IDs */
+
+#content { width: 90%; }
+
+#components { margin-top: 20px; }
\ No newline at end of file
diff --git a/Documentation/Website/style.css.meta b/Documentation/Website/style.css.meta
new file mode 100644
index 0000000..45221ab
--- /dev/null
+++ b/Documentation/Website/style.css.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: bd89a17e11df4534a0f2b219a2d9332d
+timeCreated: 1703632699
\ No newline at end of file
diff --git a/Documentation/planning.meta b/Documentation/planning.meta
deleted file mode 100644
index 2db7f2f..0000000
--- a/Documentation/planning.meta
+++ /dev/null
@@ -1,8 +0,0 @@
-fileFormatVersion: 2
-guid: fe671ce95e650411c94b18fa3d98b8b2
-folderAsset: yes
-DefaultImporter:
- externalObjects: {}
- userData:
- assetBundleName:
- assetBundleVariant:
diff --git a/Documentation/todo.md b/Documentation/todo.md
index da57f06..dc87fbc 100644
--- a/Documentation/todo.md
+++ b/Documentation/todo.md
@@ -1,6 +1,6 @@
## Easy
-- Add comments
+- ~~Add comments~~
- ~~Remove text filtering from certain Component fields~~
- ~~Round floats when saving to file~~
- ~~Update `README`~~
@@ -15,7 +15,6 @@
- ~~Make TMP text styling more intuitive when being typed out~~
- ~~Make it so that new nodes spawn where clicked~~
- ~~Fix bug with TimedChoice~~
-- Save panned position in `Descant Graph Editor`
- ~~Add option to interject variables into the text~~
@@ -27,4 +26,6 @@
- ~~Make script calling easier~~
- Make autosave better (removed temporarily)
- Create log system
-- ~~Create an online Component documentation website~~
\ No newline at end of file
+- ~~Create an online Component documentation website~~
+- Ctrl-S saving functionality for editors
+- Save panned position in `Descant Graph Editor`
\ No newline at end of file
diff --git a/Editor/Data/DescantGraphData.cs b/Editor/Data/DescantGraphData.cs
index 291d2b4..c6f7202 100644
--- a/Editor/Data/DescantGraphData.cs
+++ b/Editor/Data/DescantGraphData.cs
@@ -12,6 +12,9 @@ namespace DescantEditor
[Serializable]
public class DescantGraphData
{
+ ///