Click or drag to resize

Working with objects

In this article you will see how you can work with objects when developing your articy:draft plugins using the MDK.

Basic object handling

All articy objects are wrapped in an ObjectProxy and provide ways to access the objects data. Dealing with ObjectProxies can be difficult at first, as you are not working with explicit instances of the respective type, instead the ObjectProxy provides a single interface to deal with all articy objects.

For some properties you will find a Get method (like GetDisplayName), other properties are accessed in a different way. To access all properties you need to use the indexer on the ObjectProxy.

C#
ObjectProxy prj = Session.GetProjectRoot();

string projectDisplayName = (string)prj["DisplayName"];

Because we are dealing with different types via the ObjectProxy, we can't access the properties directly, instead we use the indexer and pass in the name of the property which then returns an object or null if the property was not found. But working with literal strings can be difficult to maintain and it can be hard to remember the exact name of a property. Therefore the MDK provides a static helper object called ObjectPropertyNames that contains constants for almost all property names.

C#
string projectDisplayName = (string)prj[ObjectPropertyNames.DisplayName];

Setting properties works in the same way using the indexer.

C#
myObject[ObjectPropertyNames.Text] = "Some Text";

Sometimes it is necessary to get the represented type for a given ObjectProxy, you can check that using ObjectType

C#
if(myObject.ObjectType == ObjectType.DialogueFragment)
{

}

Most properties represent regular primitive types, but some can reference another object, most notably Parent and Speaker. If the property represents another articy object the indexer will return another ObjectProxy

C#
ObjectProxy speaker = myObject[ObjectPropertyNames.Speaker] as ObjectProxy;

if(speaker != null)
{
    string speakerName = (string)speaker[ObjectPropertyNames.DisplayName];
}

When you have a query to find a specific type, it is possible that you get more objects than intended. For example, if you make a query over the whole project looking for DialogueFragments you will get Fragments found in the Flow and in any Documents. If that is not desired you need to adjust your query or you need to check the objects context.

C#
if(myObject.IsInContext(ObjectContext.Flow))
{

}

Working with Templates and Features
Note Note

It is currently not possible to create or modify a template/feature. You can only access and modify the values on objects with templates.

If you want to know if an ObjectProxy represents an object with a template, you can get the name of the used template

C#
ObjectProxy obj = ...

if (obj.GetTemplateTechnicalName().IsNullOrEmpty())
{

}

Accessing a particular property on an object is also done via the indexer, but you need to qualify the feature and the property both by technical name. Because you could have two different features both with equal named properties.

C#
ObjectProxy obj = ...

int age = (int)obj["DefaultBasicCharacterFeature.Age"];
Caution note Caution

Only the TechnicalName is used, not the DisplayName when accessing features and properties.

You can set/clear the template of an object using SetTemplate

C#
obj.SetTemplate("DefaultMainCharacterTemplate");
Note Note

You can't create entirely new features or templates or add/remove properties from existing ones at this time using the MDK.

Working with Assets

While Assets work in the same way as any other articy object, you can do some special things with them that might be necessary to understand to properly work with them.

Assets in articy are imported from a source and included as part of your project. For that the ApiSession object found on your MacroPlugin derived class contains a couple of necessary methods.

Importing a new asset is done via ImportAsset

C#
ObjectProxy targetFolder = Session.GetSystemFolder(SystemFolderNames.Assets);
string newAssetName = "MyFlowAsset";
string filePath = @"C:\Flower.png";

var obj = Session.ImportAsset(targetFolder, newAssetName, filePath);

Modifying an existing asset with a new source works in a similar way. For example you want to overwrite the underlying image.

C#
ObjectProxy targetAsset = ...

string filePath = @"C:\Flower.png";

Session.ChangeAsset(targetAsset, filePath);

Important

When you are dealing with importing or changing assets, the Asset system of articy:draft will import/modify this content asynchronously. This can be a potential pitfall if you want to work with the new asset content directly. To make sure that your asset operation is fully finished and the underlying content is available to work with you need to call

C#
Session.WaitForAssetProcessing(new WaitForAssetProcessingArgs());
This will stall the current thread until the asset system is finished.

To reiterate: This is only necessary when you need to work with the external asset file of an articy asset, if you want to work with the articy object, you can do that directly after the import operation. To put it differently: A newly articy asset object is immediately created in your project, but the asset file is potentially still copied to the project folder.

Accessing the underlying asset file is rather trivial

C#
var assetPath = myAsset[ObjectPropertyNames.AbsoluteFilePath] as string;
if (!string.IsNullOrEmpty(assetPath))
{
    byte[] fileBytes = File.ReadAllBytes(assetPath);
    ...
}

Multiuser and Claiming

When you are writing a plugin that should work with multiuser, partitions and claiming, you need to make some additional checks before trying to create/modify objects.

The most important check is to see if an object is currently available for modification, in other words if it is available for modifications. To do that you can easily ask an object if it IsReadOnly

C#
ObjectProxy obj = ...

if(obj.IsReadOnly)
{
    // not mine, need to claim it before modifying
}

When you want to claim an object, you need to claim its partition. To do that you find the necessary methods on the ApiSession for example

C#
ObjectProxy obj = ...

if (obj.IsReadOnly)
{
    Session.ClaimPartition(obj.GetPartitionId());
}

This only works if the partition was not claimed by somebody else, after a claim you can check if you have that partition by either checking IsReadOnly again or more extensively by using GetPartitionInfo(Guid)

C#
ObjectProxy obj = ...

PartitionInfo partInfo = Session.GetPartitionInfo(obj.GetPartitionId());
if (!partInfo.IsClaimedByMe)
{
    // not my partition
}

If you are done with a partition, you might need to publish the changes, so other users in the project can get them, for that you can use

C#
Session.PublishProjectPartitions(false); // publish and unclaim
You can keep the claims by supplying true if necessary, to continue working with those partitions.