So I just finished going through all the ECS videos and I remember Mike Acton telling us to request example projects that would best explain the ECS system to us. It cant be too simple or too obtuse. More over its been a while since we’ve had an official unity demo.
So I am inviting you guys to post your suggestions.
I personally would like to see a demo that shows any of the following systems Mecanim ECS interaction/communication
If you have multiple npc’s they’d most likely be in different states. eg one could be interacting with an object while another idles. Would we just be changing gross state in the update while animation state machine does the main churn?
ECS menu system
Mike actually stated slow UI as a justification for ECS in the talk. I cannot envisage how this would even work (Architecture).
AI system.
This one might be complex but i think it would show off the system the most. AI has a lot of dependencies and does not update every frame. Lots of communication also. I suggest a state machine system but, an “if-else” ai would not be a good way to do this.
A simple state machine like the plug-able one used in the tanks tutorial from.
Ultimately we could re-purpose the old stealth demo or Angry bots
I’d like to see something along the lines of a behavior tree in ECS. Struggling to think of how you would go about that, but it is so much more useful for AI than a basic state machine.
You might have to copy the Service based implementation from UE4. It is probably the only way to maintain performance without redundant tree traversals. Especially since most of the examples did not have branching code.
Sensory updates can be threaded and fed to a blackboard, it will mean tedious code of writing to a blackboard after every ComponentSystem update if note and requests/deferred retrieval of data not currently present. Different ComponentSystems for each sensor as the logic is mostly consistent.
It would probably be the same for event communication between objects. populating lists of messages/commands after ComponentSystem updates and resolving them at the end of frame or beginning of the next.
Reading from blackboards or Animation Parameter might also happen frequently as we prepare our jobs based on the state. I doubt placing the whole blackboard would be good for cache.
The irregularity of AI update would mean we probably have to spread updates for each agent across many frames like the particle system example from gdc
foreach agent in agentList
if timeSinceLastUpdate > n
aiUpdateQueue.(agent)
For utility systems i am at a total loss. 1 system per consideration or per action?
Hello ! I’d love to see some 2D in pure ECS. Should I use MeshInstanceRenderer or a system using DrawTexture onPostRender ?
I’m not sure how to work with Mecanim :
use an Animator to copy Animator Controllers data into an ECS Animator at start
use multiple Animators to modify and store controllers states in every entities
I read somewhere Animator was already working with a jobified pattern. Should I rebuild the wheel or go for hybrid ?
Based on the pure ECS exemple, I’m going with this for now :
SpriteInstanceRenderer.cs
using System;
using Unity.Entities;
using UnityEngine;
namespace Playtest.Rendering
{
[Serializable]
public struct SpriteInstanceRenderer : ISharedComponentData
{
public Texture2D sprite;
public Material material;
}
public class SpriteInstanceRendererComponent : SharedComponentDataWrapper<SpriteInstanceRenderer> { }
}
SpriteInstanceRendererSystem.cs
using System.Collections.Generic;
using Unity.Entities;
using Unity.Mathematics;
using Unity.Transforms2D;
using UnityEngine;
using UnityEngine.Experimental.PlayerLoop;
namespace Playtest.Rendering
{
[ExecuteInEditMode]
public class SpriteInstanceRendererSystem : ComponentSystem
{
List<SpriteInstanceRenderer> m_CacheduniqueRendererTypes = new List<SpriteInstanceRenderer>(10);
ComponentGroup m_InstanceRendererGroup;
protected override void OnCreateManager(int capacity)
{
m_InstanceRendererGroup = GetComponentGroup(ComponentType.Create<SpriteInstanceRenderer>(), ComponentType.Create<Position2D>());
}
protected override void OnUpdate()
{
Camera.onPostRender = null;
EntityManager.GetAllUniqueSharedComponentDatas(m_CacheduniqueRendererTypes);
Camera.onPostRender += (Camera camera) =>
{
GL.PushMatrix();
GL.LoadPixelMatrix(0, Screen.width, 0, Screen.height);
};
for (int i = 0; i != m_CacheduniqueRendererTypes.Count; i++)
{
var renderer = m_CacheduniqueRendererTypes[i];
m_InstanceRendererGroup.SetFilter(renderer);
var positions = m_InstanceRendererGroup.GetComponentDataArray<Position2D>();
for (int j = 0; j != positions.Length; j++)
{
float2 position = positions[j].Value;
Camera.onPostRender += (Camera camera) =>
{
Graphics.DrawTexture(
new Rect(position.x,
position.y + renderer.sprite.height,
renderer.sprite.width,
-renderer.sprite.height),
renderer.sprite,
renderer.material);
};
}
}
Camera.onPostRender += (Camera camera) =>
{
GL.PopMatrix();
};
m_CacheduniqueRendererTypes.Clear();
}
}
}
I’ll try this today :
InstanceAnimatorSystem.cs
using System.Collections.Generic;
using Unity.Entities;
using UnityEngine;
using UnityEngine.Experimental.PlayerLoop;
namespace Playtest.Rendering
{
[ExecuteInEditMode]
public class InstanceAnimatorSystem : ComponentSystem
{
Animator animator = new Animator();
List<InstanceAnimator> m_CacheduniqueAnimatorTypes = new List<InstanceAnimator>(10);
ComponentGroup m_InstanceAnimatorGroup;
protected override void OnCreateManager(int capacity)
{
m_InstanceAnimatorGroup = GetComponentGroup(ComponentType.Create<InstanceAnimator>(), ComponentType.Create<SpriteInstanceRenderer>());
// 1) Copy every Animator Controllers data from m_InstanceAnimatorGroup into Entities using an Animator
}
protected override void OnUpdate()
{
// 2) Get the actual state from every Entities and set the SpriteInstanceRenderer Texture2D value
}
}
}
Please, guys, go very easy on us noobs. I have really tried 3 hours of understanding the ECS architecture. Even though I got the idea (at least that’s what I want to think) when it comes to implementing it I crumble. I mean wtf is bootstrap scripts NewGame method! Who calls it? Is it magical? How the hell PlayerLook is assigned to that script?! (Don’t answer those questions, what I am trying to say it is too complex for my delicate old brain).
So my ideas of examples:
From very empty project →
A project where we create an entity cube. Turning an empty gameobject into Cube with ECS. Meshrenderer component?
A project where we create an entity cube. From thin air. No gameObject.
Now let’s make the cube turns around itself. No input no nothing but ECS style.
Let’s spawn 1000 of the above cubes in a line. Still turning. ECS style.
Delete those 1000 cubes, spawn those cubes in 5 different positions where we assign their positions by using the editor (for example with empty gameobjects) so I will learn how to tie inspector to ECS.
Let’s create a Sphere. From thin air. No gameObject. ECS style.
Let’s get the user input and make the ball roll (with transform first - I mean teleport it around)
Let’s make the ball roll with Physix (Now we learn to connect our Rigidbody to ECS?! is this a thing?)
Let’s turn this into a roll a ball tutorial at the end.
So now I know 2 systems of movement (transportation,physix), 2 systems of spawning (w/ GO and without GO), assigning values from GOs to entities (spawn places), 1 system of user input, 1 system of constant movement (rolling of cubes) and I guess some more.
Edit: After like 4 hours, I could move a cube and turn it with Hybrid ECS (where cube is still a GO). Then I tried to delve back in to pure ECS samples (Get cocky I guess). Simple rotation killed me. I understand I need to add Transform matrix or it won’t instantiate anything. Then I spawned some balls into the middle with the Unity spawn script (mind you I failed lots as I think pure entity has its own laws, some components are must have). I tried to move stuff with my old script. But mo… Now they are an entity so they refused to move. I really suspect it is something about TransformMatrix component… Though why is it that way? I think there are lots of missing but basic stuff that is not yet in documents. (Again I am not writing these for immediate answers but as a struggling coder’s journey so to show required tutorial level)
From what I know, in my simple mind, particle systems are the best for showing an ECS in action.
The Systems influence particle behaviour, randomisation, customisation, and events activating further Systems to perform more logic/processing upon the properties within the components of the particles.
The Components make up various properties of ever more complex particles.
I’ve got the raycast command working and its raycasting normal monobehaviours with colliders but can’t implement a way to detect the raycast on an entity
How to work with big data sets. e.g. Minecraft-like world. Is every block an entity? How many entities are too many? Or should all blocks be in an array on one entity or on chunk entities?
You’d want to make chunks into entities and have a ChunkSystem that “renders” the whole thing with data from Chunk datacomponent or something. I’ve tested 100,000 entities (cubes) with instanced material and I got around 30fps avg on my old Radeon 7670m (frame rates dropped as more cubes entered the view) you can get the project here
We do a lot of real world data simulation & visualisation with Unity rather than write games. So we read in sometimes very large data sets and need to move, rotate items according to ‘scalable real’ time. So i would much welcome examples of ‘lerping’ moves and rotating over several frames. Also event driven job scheduling.
@Ziboo My friends over at Brazil are starting a little roguelike project. I’m suggesting them to use ECS and Unity’s tile map, they are currently only starting to learn both. So would be great if there would be an example like this, I would send it to them. Maybe I can help you out at least with ideas if I won’t be able to dedicate much time. Maybe I can help you figure out how to get around not having the reactive systems (should be easy). I would definitely learn a thing or two in the process.
@illinar Hey thanks for the offer. I’m just playing with it. Not sure I will continue or not, I’m not sure the ECS is mature enough to handle something like that, maybe wait a little bit, I’ll see.
But honestly, just trying, without Events on entities or component changed, it’s kind of a nightmare, you pretty much have to do a system for every little things… which is very time consuming