Click or drag to resize

Object Templates

Part of your exported data are Object Templates and understanding their relationship with your articy objects, how they work and how to use the different types inside unity is part of this guide.

Primer to articy:drafts object templates
template primer folders

If you have never worked with or need a small brush up about the articy:draft template system, read on otherwise you can skip this section

Every object in articy:draft (Entity, FlowFragment, Location etc.) has a predefined set of hardcoded properties like DisplayName, TechnicalName, ID, Text, Attachments etc.. When designing more complex projects using articy:draft you will sooner or later arrive at a point you wish an articy object had a specific property. Lets say your game needs every NPC to contain a property stating how much gold it is worth when killed, now the obvious articy type would be to use an Entity for the NPCs but how do you create a property for the gold? Introducing model templates:

Following is a list of important parts of the template system, if this doesn't make sense at first, continue reading, we will look at each part in more detail:

  • Template Container for features bound to one specific articy object type.
  • Feature Container for properties reusable in different templates.
  • Property Single piece of information with a specific type stored inside a feature.
  • Property definition Allows predefining a property and its settings as a reusable property type.

Every articy:draft object type can have an object template. You create those object templates in articy:draft using the template editor. It is important to understand that an object template is fixed to one type and one type only. When you create an entity template called "Item" you can only attach this template to entities and nothing else.

A template is usually built up of one or many different features. A feature is created via the feature editor in articy:draft. Because features are not bound to an object type they are a good way to share the same kind of properties between different templated articy object types. A feature itself is a container for properties and can have many properties of varying types. Reusing our example above we could create a feature called LootInfo and place it in our entity template NPC. Later on if we create a template for Chests, we could reuse our LootInfo feature.

On the feature we can now start to plan and create our properties. In the feature editor you are presented with a list of different property types and each type can be placed in the feature grid, creating a new property inside the feature. Every property type has different settings depending on the type and allow us to fine tune and guide how the designers can work or modify the property when used. For example when using the Number property type, we can set the amount of decimal places, a unit, min and max value and so forth. Going back to our example above, in our LootInfo feature we would create a new Number property calling it Gold, adjusting its setting, like min and max and maybe set the Unit to "g" for gold.

Sometimes we have a lot of properties in our features that share the same settings. For example we create a feature for an RPG character with many skill attributes and we have to set the min and max value for every property by hand. To simplify this, you can create property definitions that are reusable presets of properties. For the unity plugin and for the remainder of this guide they are not important.

Understanding Objects with Templates

Lets first have a look of how objects with templates differ from objects without templates, for this example we look at the Entity type:

classdiagram simple template
Here we have 3 classes generated by the plugin from the maniac manfred project. In the image above you can see the class Entity with some of its properties like DisplayName, Text, Color etc. If you export Entities this C# class will get generated by the plugin and all your entities will be instances of this class stored inside the database. This is all done for you by the plugin so you can just access your data like
C#
Entity ent = ArticyDatabase.GetObject<Entity>("Chr_Manfred");
Debug.Log( ent.DisplayName );
Now lets look at the arrow pointing into the Entity. The arrow is visualizing an inheritance (Generalization) or a "Is-A" Relationship. This effectively means that the classes Player_Character and Item are derived from Entity. This means that the object templates in articy:draft create specialized objects of the templates class in your unity project. To better understand this concept, lets just look at some code
C#
Character ent = ArticyDatabase.GetObject<Player_Character>("Chr_Manfred");

// access the displayname because a Character is still an Entity.
Debug.Log(ent.DisplayName); 

// access the template
Debug.Log( ent.Template.Character.Motivation );
We ask the database to return the object as the more specialized class Player_Character, it is still an Entity and carries all the properties of one, but now it also has a new property called Template giving us access to the template features and the properties.

Important to remember

  • Object Templates in articy:draft will be C# classes in unity. eg. Player_Character Template -> class Player_Character : Entity {}
  • Each of these template classes will have a property called Template giving access to the template and its features. myObj.Template.MyFeature
  • The features contain the properties layed out in the articy:draft template editor. myObj.Template.MyFeature.MyProperty
  • The TechnicalName is always used for the generated classes or property names.

Note Note

This example assumes that you have inheritance enabled in the ruleset data layout, which is the default and the prefered way to work.

Accessing Features and properties

With a basic understanding of how templates are created by the plugin, lets look how we can work with them

C#
Character ent = ArticyDatabase.GetObject<Player_Character>("Chr_Manfred");
// access to the template -> the feature called "Character" and the template property "Motivation"
Debug.Log( ent.Template.Character.Motivation );

Accessing a template property is very straight forward if you are used to C# properties in general.

<myObject>.Template.<FeatureTechnicalName>.<PropertyTechnicalName>

We can work the same way with template properties as we can with general properties (DisplayName, Color etc.). We just have to remember that the TechnicalName of the property in articy:draft is the property name in C#.
property visualstudio

Working with specific property types

property types

This section contains the following subsections:

Boolean, Number, Text

The basic types are straight forward mapped to their C# types and thus very easy and intuitive to use.

C#
var manfred = ArticyDatabase.GetObject<Player_Character>("Chr_Manfred");
var locationCell = ArticyDatabase.GetObject<LocationSettings>("Loc_Cell");

Debug.Log( manfred.Template.Character.Age );                                 // Number (float)
manfred.Template.Character.Age = 42;

Debug.Log( manfred.Template.Character.Motivation );                         // Text (small, medium, large) (string)
manfred.Template.Character.Motivation = "Converting oxygen to carbon dioxide.";

Debug.Log( locationCell.Template.LocationSettings.IsStartLocation );     // Boolean (bool)
locationCell.Template.LocationSettings.IsStartLocation = false;

Slots

A reference slot is used to provide a link to another articy object.

C#
var locationCell = ArticyDatabase.GetObject<LocationSettings>("Loc_Cell");
var startDialog = locationCell.Template.LocationSettings.InitialDialog as Dialogue;
Here we access a slot property called InitialDialog and use C-Sharps "as" operator to cast the value to a Dialog. This is important because a Slot property is always of type ArticyObject.

It is worth noting that the object is lazy fetched, which means everytime you access the property, the property will internally ask the database to get the object again.

Strip and calculated Strip

When you need multiple objects referenced you should use a Strip in your template. In unity a strip property is of type List<ArticyObject>.

C#
var manfred = ArticyDatabase.GetObject<Player_Character>("Chr_Manfred");
foreach(ArticyObject obj in manfred.Template.Character.Likes)
{
    var entity = obj as Entity;
    if(entity != null)
        Debug.Log(entity.DisplayName);
}

Note Note

Because the plugin has no support for the query language used in articy:draft for calculated strips they are effectively downgraded to regular strips and they contain the calculated data at the time of export.

Drop-down list

Dropdown lists are a good way to visualize limited data. In unity drop down lists are effectively enums, with the drop-down type being the name of the enum. So using a drop-down in unity

C#
var therapistZone = ArticyDatabase.GetObject<Conditional_Zone>("Zon_4B2E23F9");
therapistZone.Template.ZoneCondition.CursorIfConditionMatches = MouseCursor.Take;
here you can see that we assign a new value to the property CursorIfConditionMatches which is a drop-down property in our ZoneCondition feature. The enum type MouseCursor was generated by the plugin and is exactly how we defined it in articy.

Scripts

All the scripts inside the flow on pins and in instructions and conditions are called by the ArticyFlowPlayer and we usually don't have to worry about it. But scripts in templates have to be used manually. When exported these properties can be ArticyScriptCondition, ArticyScriptInstruction or a plain string depending on which mode you selected in the template editor in articy

property type script mode
The difference between ArticyScriptCondition and ArticyScriptInstruction is simply that the former returns a boolean and is used to check if something is allowed, this is the same for input pins, while the later is just used to execute code and is similar to output pins.

You can do 2 things with both script types in unity.

Using scripts inside your code is therefor just a matter of using the CallScript() methods.

C#
var therapistZone = ArticyDatabase.GetObject<Conditional_Zone>("Zon_4B2E23F9");

// call the Condition property first
bool result = therapistZone.Template.ZoneCondition.ClickCondition.CallScript();

// check the returned value, a condition always returns true or false depending on the evaluation of the script
if(result)
{
    // if we were allowed to click it, execute the instruction
    therapistZone.Template.ZoneCondition.OnClickInstruction.CallScript();
}
here you can see how we use a condition property called ClickCondition, execute the script using CallScript() and if that returns true, we call the instruction in that feature called OnClickInstruction.

Just to clarify, if you selected "No error validation" on the script property inside the feature editor.

property type script mode noscript
The property will be imported as a simple string property, not having the RawScript or CallScript() method.

Access object by feature

In articy:draft templates are bound to a specific type, which means you can't assign a FlowFragment template to a DialogueFragment. But because it is often necessary to have the same set of data on multiple types, articy:draft introduced the concept of Features. Features can be reused in templates and are a good way to attach the same set of data to multiple object types. But how can we write code targeting a specific feature, without the need to know the type of the underlying template.

At this point we have only accessed features where knew the type of the template. But its also possible to ask an arbitrary object if it is a templated object and contains a specific feature. To do that, the plugin will generated specialized interfaces for every feature in the form of

IObjectWithFeature<FeatureTechnicalName>

for us. This is the same concept as the property interfaces like IObjectWithLocalizableDisplayName. Now to use it we can type

C#
ArticyObject obj = ArticyDatabase.GetObject("Chr_Manfred"); // some object

var characterFeature = obj as IObjectWithFeatureCharacter;
if(characterFeature != null)
{
    characterFeature.GetFeatureCharacter().Motivation = "Converting oxygen to carbon dioxide.";
}
here we use the as keyword to cast an object to the type IObjectWithFeatureCharacter, if the variable is not null we know that the obj must have the feature. To finally get access to the feature itself we have to call a method in the form

<Object>.GetFeature<FeatureTechnicalName>()

Template property meta data and constraints

property type constraints
When you create templates in articy, the template editor allows you to fine tune how certain properties should behave. While only enforced inside of articy:draft, some of these information can be useful to have even after exporting. The plugin will for every property create static informations providing these meta information. Every articy object type that has a template carries these so called Constraints with it. To access it you just need the name of the template and call the static property Constraints.

<TemplateType>.Constraints.<FeatureTechnicalName>.<PropertyTechnicalName>.<Constraint data>

C#
var manfred = ArticyDatabase.GetObject<Player_Character>("Chr_Manfred");

// use unitys Assert to check if the Motivation properties length is less or equal than what we defined in the constraints for that property
Assert.IsEqual( manfred.Template.Character.Motivation.Length <= Character.Constraints.Character.Motivation.MaxLength );

See Also