"RuntimeSets" in DOTS

Hey folks,

So, I watched this talk: Unite Austin 2017 - Game Architecture with Scriptable Objects

I really like the idea behind Runtime sets (~41:14 in the video), but can’t quite figure out how to make it work with DOTS. I am still busy trying to wrap my head around DOTS, so maybe I am just missing something obvious. Here is what I tried, first me experimenting with DOTS and then me trying to integrate “RuntimeSets” into it.

If this is not possible (now). I would be open to any alternative that accomplishes the following;

  • Allows me to get away from the Singleton pattern for managing lists / data.
  • Allows me to populate the list via both the editor and code
  • The data is accessible from within a DOTS System.
  • (Optional) The data is still in a struct (for DOTS)

DOTS:

using Unity.Entities;

[GenerateAuthoringComponent]
public struct Skill : IComponentData
{
    public int id;
    public int level;
    public float progress;
    public float incrementer;
}


using Unity.Entities;
using Unity.Mathematics;

public class TestSystem : SystemBase
{
    protected override void OnUpdate()
    {
        float delta = Time.DeltaTime;

        // TEMP
        TestManager testManager = TestManager.instance;

        Entities.ForEach((ref Skill skill) =>
        {
            skill.progress = skill.progress + (skill.incrementer * delta);

            if (skill.progress >= 100.0f) {
                skill.level++;
                skill.progress = 0.0f;
            }

            testManager.skills[skill.id].text = "Skill" + skill.id + ": " + skill.level + " | " + math.round(skill.progress * 100.0f) / 100.0f;
        }).Schedule();
    }
}

DOTS with “RuntimeSets”:

// ----------------------------------------------------------------------------
// Unite 2017 - Game Architecture with Scriptable Objects
// 
// Author: Ryan Hipple
// Date:   10/04/17
// ----------------------------------------------------------------------------

using System.Collections.Generic;
using UnityEngine;

public abstract class RuntimeSet<T> : ScriptableObject
{
    public List<T> Items = new List<T>();

    public void Add(T thing)
    {
        if (!Items.Contains(thing))
            Items.Add(thing);
    }

    public void Remove(T thing)
    {
        if (Items.Contains(thing))
            Items.Remove(thing);
    }
}

[CreateAssetMenu]
public class SkillRuntimeSet : RuntimeSet<SkillMono>
{ }


using UnityEngine;

public class SkillMono : MonoBehaviour
{
    public SkillRuntimeSet RuntimeSet;
    public Skill SkillData;

    private void OnEnable()
    {
        RuntimeSet.Add(this);
    }

    private void OnDisable()
    {
        RuntimeSet.Remove(this);
    } 
}


using Unity.Entities;

public class TestSystem : SystemBase
{
    protected override void OnUpdate()
    {
        float delta = Time.DeltaTime;

        // Knew this wouldn't work on Classes, but had to try anyway.
        // Trying to grab the struct (Skill) directly doesn't work, either.
        Entities.ForEach((ref SkillMono skillMono) =>
        {
            var skill = skillMono.SkillData;
            skill.progress = skill.progress + (skill.incrementer * delta);

            if (skill.progress >= 100.0f) {
                skill.level++;
                skill.progress = 0.0f;
            }

        }).WithoutBurst().Run();
    }
}

This post is already pretty long because of the code snippets, but it would be great if anyone knows how to do the Events from that same talk (~33:44) from within a DOTS system and could share.

Also, I realize DOTS isn’t ready yet, but I still want to start understanding it and make some use of it.

I think this pattern may be obsolete for DOTS.

Main reason being that entities and components are stored and easily accessible as arrays already. And to access those arrays you don’t even need any asset references but just components/tags you’re after at the moment.

You can inspect those collections of entities in Entity Debugger window. You cannot edit them there yet, but for that you can write your own custom editor window where entities can be spawned/destroyed manually etc.