#Is there a better way any way to set up
1 messages · Page 1 of 1 (latest)
You can have the counter be a component like 'CoinPurse'. Then whenever a player is in range you increment the value of that component data.
Here's some pseudo code as inspiration:
public struct CoinPurse : IComponentData
{
public int AmountCoins;
}
public class CoinSystem : SystemBase
{
private Entity _coinPurseEntity;
private ComponentLookup<CoinPurse> _coinPurseLookup;
private const float CoinPickupDistance = 1.5f;
private const float CoinPickupDistanceSq = CoinPickupDistance * CoinPickupDistance;
public CoinPurse GetCoinPurse()
{
return EntityManager.GetComponentData<CoinPurse>(_coinPurseEntity);
}
protected override void OnCreate()
{
_coinPurseEntity = EntityManager.CreateEntity(typeof(CoinPurse));
_coinPurseLookup = GetComponentLookup<CoinPurse>(false);
}
protected override void OnUpdate()
{
_coinPurseLookup.Update(this);
new CoinJob()
{
PlayerPosition = GetPlayerPosition(),
CoinPurseLookup = _coinPurseLookup,
CoinPurseEntity = _coinPurseEntity
}.Schedule();
}
protected override void OnDestroy()
{
EntityManager.DestroyEntity(_coinPurseEntity);
}
public partial struct CoinJob : IJobEntity
{
public float3 PlayerPosition;
public ComponentLookup<CoinPurse> CoinPurseLookup;
public Entity CoinPurseEntity;
public void Execute(in WorldTransform coinTransform, in Coin coin)
{
if (math.distancesq(PlayerPosition, coinTransform.Position) < CoinPickupDistanceSq)
{
// Do whatever you do when picking up a coin
// e.g. disable entity via EntityCommandBuffer
// Then increment CoinPurse
CoinPurseLookup.GetRefRW(CoinPurseEntity, false).ValueRW.AmountCoins += 1;
}
}
}
}
My pleasure 🙂
Do you mind if I ask another question, in your opinion is this the best way to handle something like this?
I just don't see any other way to hook up UI / other systems that need this data.
I don't know enough about your use-case to give an answer to that really, mind sharing some more details?
It's pretty standard, a player picks up collectables in a level (think vampire survivor) and then they need to spend that / display it in a UI somewere.
I don't know how much interfacing we have with 1.0 enough to know if I should do this in ECS or Mono.
Is the majority of your game in ECS or in GameObjects?
Doesn't matter actually, I'll explain how I'd do interfacing with UI from ECS.
Currently it's GO.
Okay so you can do it with UI.
Maybe I might just keep this system in ECS then.
Just a simple implementation like this is what I would do if most stuff will be in Gameobjects.
public class CoinPurseBehaviour : MonoBehaviour
{
private CoinSystem _coinSystem;
public void Awake()
{
World.DefaultGameObjectInjectionWorld.GetOrCreateSystem<CoinSystem>();
}
public void Update()
{
// if your UI needs to update every frame then you can update it here
}
public int GetAmountCoins()
{
return _coinSystem.GetCoinPurse().AmountCoins;
}
}
If you have lots of ECS data & you need to work with it in Gameobjects (like UI), then I'd approach it differently.
I'd make a System that grabs all relevant state & put it in NativeContainers, I'd double buffer them so that there'd be no need to complete ECS jobs.
From this system I can then grab any of the containers with data & use it for UI or something else.
Double buffering means we have 1 frame outdated info but that should almost never be an issue.
This is how I did the UI interfacing for a DOTS game I worked on previously, it has since shipped & the UI works great.
Thanks so much, trying it out.