Skip to content

List Variables

Define matching list wrapper types when you want to store collections of your custom type:

using System;
using HutongGames.PlayMaker;

namespace MyNamespace
{
    [Serializable]
    [DataType(typeof(MyCustomType))]
    public class MyCustomListVariable : ListVariable<MyCustomType>
    {
        public MyCustomListVariable()
        {
        }

        public MyCustomListVariable(string name) :
            base(name)
        {
        }
    }

    [Serializable]
    [DataType(typeof(MyCustomType))]
    public class MyCustomListRef : ListVariableRef<MyCustomType>
    {
    }

    [Serializable]
    [DataType(typeof(MyCustomType))]
    public class MyCustomListVar : ListVariableVar<MyCustomType>
    {
    }
}

Accessing Values

List variables wrap List<T>, but the access patterns are a little different from single-value variables.

ListVariable<T>

ListVariable<T>.Value is the actual List<T>.

List<MyCustomType> list = MyListVariable.Value;
int count = MyListVariable.Value.Count;
MyCustomType first = MyListVariable.Value[0];

Unlike scalar variables, the getter makes sure the list is initialized, so Value returns an empty list instead of null.

ListVariable<T> also exposes a Values array helper:

MyCustomType[] items = MyListVariable.Values;
MyListVariable.Values = items;

This is useful when you want to copy values in or out as an array instead of working with List<T> directly.

ListVariableRef<T>

ListVariableRef<T> also wraps a List<T>, but it additionally exposes ListVariable through the non-generic list variable interface:

List<MyCustomType> list = MyListRef.Value;
IListVariable listVariable = MyListRef.ListVariable;

This is useful when you need to work with APIs that operate on list variables generically rather than on a specific List<T>.

ListVariableRef<T> also has a Values array property:

MyCustomType[] items = MyListRef.Values;
MyListRef.Values = items;

ListVariableVar<T>

ListVariableVar<T> behaves like VariableVar<List<T>>, so it can either use a constant list value or reference an existing list variable.

List<MyCustomType> list = MyListVar.Value;
MyCustomType[] items = MyListVar.Values;

It also provides a typed indexer:

MyCustomType first = MyListVar[0];
MyListVar[2] = someValue;

When assigning through the indexer, the list expands automatically if needed.

Practical Differences

The main differences from single-value wrappers are:

  • list wrappers work with List<T>, not just T
  • Values gives you an array copy/helper surface
  • ListVariableRef<T> and ListVariableVar<T> expose ListVariable for generic list APIs
  • ListVariableVar<T> includes an indexer for editing constant list values

Mutation Notes

Because Value returns the underlying list, editing it in place is not the same as assigning a new value through the property setter.

For example:

MyListVar.Value.Add(item);

This modifies the current list instance directly.

If you want to replace the whole list, assign Value or Values instead:

MyListVar.Value = new List<MyCustomType>(source);
MyListVar.Values = sourceArray;

That pattern is often clearer when you are rebuilding the list from scratch.