I’m currently thinking of my next game and I thought it could have a very clean architecture if I could do a kind of MVVM(Model, View, Viewmodel) approach involving entities.
I’d like to have entities and systems always running in the background, and just represent some of these entities in the foreground (ie on screen) with game objects.
For example, there may be a health component.
And I have a health bar game object acting as the “view” of the health.
Can I access the data on the component from a monobehaviour on a gameobject?
Hey, I think you’re right.
It’s probably best if I design in such a way that game objects never actually need to “know” about components or systems.
Ty Alexandre
Here’s a script that would give you an idea of how to do that. This is a script I put on my game camera, because it can’t be converted to DOTS yet, but I wanted the camera controls to all be coded in DOTS
This script allows you to either copy pos/rot from the DOTS world to the GameObject world, or vice-versa. But it is very inefficient
using System.Collections;
using System.Collections.Generic;
using Unity.Entities;
using Unity.Transforms;
using UnityEngine;
public class TransformEntityBridge : MonoBehaviour
{
public bool Write = false;
public Entity BridgedEntity;
public EntityManager EntityManager;
private Transform _transform;
private void Start()
{
_transform = this.transform;
}
void Update()
{
if (Write)
{
EntityManager.SetComponentData<Translation>(BridgedEntity, new Translation() { Value = _transform.position });
EntityManager.SetComponentData<Rotation>(BridgedEntity, new Rotation() { Value = _transform.rotation });
}
else
{
_transform.position = EntityManager.GetComponentData<Translation>(BridgedEntity).Value;
_transform.rotation = EntityManager.GetComponentData<Rotation>(BridgedEntity).Value;
}
}
}
Hey there Phil, thank you so much. This does indeed answer my question about interaction between the two worlds. I just wasn’t sure if it’s feasible, but seems like it definitely is!
And even if it’s inefficient I should be ok.
The game I plan to work on won’t be anything impossible to achieve with normal game objects.
I just really like the strict and straightforward way of coding in ECS.
Again I’d strongly advise not adding any more logic to monobehaviours.
What you need here is something like:
Hero Entity (or Player or whatever)
Hero IComponentData
Health IComponentData
HealthBar Entity
HealthBar ComponentData
Image ComponentObject
Then have a HealthBarUpdateSystem use GetSingletonEntity to get the entity, then EntityManager.GetComponentData(entity) to get the health, then set Image size.x according to the health value.
In this scenario, no monobehaviour is responsible for updating anything, which is what you want in DOTS. Once a DOTS UI arrives, the only thing you need to do is change the authoring part and nothing else. So your code becomes reusable and much more maintainable
As for the authoring, your HealthBar GameObject could just have an Entity child, on which you would have a HealthBarAutoring IConvertGameObjectToEntity that adds both the image and HealthBar components to the entity.