#Efficient way to get Player position for targeting

1 messages · Page 1 of 1 (latest)

clear pivot
#

Hi, fiddling around in a 2D test project to get a hang of DOTS/ECS. I have a component MoveLinear which has a float2 target and float speed. In my MoveLinearSystem I'm moving the entities towards the target. Problem is, I want the entities to move towards the player, which currently is a normal GameObject.

My first thought is to make the Player class update a static Vector2 variable every frame and then use that in the System, however that upsets the BurstCompiler, since I'm "Loading from a non-readonly static field". I feel like the player position should be stored in ECS and accessed from there, but I'm not exactly sure how to do that efficiently. Any input is appreciated.

violet valve
#

Just have a system that stores player position into component before your MoveLinearSystem

#

and then get it from component when you need it

clear pivot
#

What component should it store the position in though? Is there a singleton equivalent in Components?

violet valve
#

yes, just call EntityManager.CreateSingleton<T>() in OnCreate and then you can use SystemAPI.SetSingleton(new T()) afterwards

clear pivot
#

Ok yeah that seems good, I'll try it out in a sec.

Can you suggest how I should read the player position though? Do I have to make the Player class a singleton to access the transform?

violet valve
#

well, up to you.
Considering you wanted to use static field - can just store transform in it

worldly thicket
#

Or use SharedStatic to have less code without a system and a component

clear pivot
#

Went over the docs and SharedStatic seems something like a static pointer to a variable, is that correct?

worldly thicket
#

It is a static that can be accesed by bursted code

violet valve
clear pivot
#

Yeah in my mind it makes more sense to have a System manage that. However I have run into a problem, don't think the Singleton is created properly. I'm getting an error.

InvalidOperationException: GetSingleton<PlayerPosition>() requires that exactly one entity exists that match this query, but there are none. Are you missing a call to RequireForUpdate<T>()? You could also use TryGetSingleton<T>()

#

Here's the system class.

[CreateBefore(typeof(MoveLinearSystem))]
public partial class PlayerPositionSystem : SystemBase
{
    public void OnCreate(ref SystemState state) {
        EntityManager.CreateSingleton<PlayerPosition>(new PlayerPosition { positionPlayer = float2.zero}, "PlayerPosition"); 
    }

    public void OnDestroy(ref SystemState state) { 
    }

    protected override void OnUpdate() {
        SystemAPI.SetSingleton(new PlayerPosition { positionPlayer = PlayerMovement.Position });
    }

}```
violet valve
#

I feel like it's thrown from different system

clear pivot
#

TLDR I'm calling SystemAPI.GetSingleton<PlayerPosition>().positionPlayer in another system's OnUpdate

violet valve
clear pivot
#

It's there I believe

violet valve
#

Then maybe you somehow destroyed it?

clear pivot
#

It looks like it's just not calling the OnCreate method for PlayerPositioningSystem. Did I format it wrong?

violet valve
#

SystemBase has virtual methods

#

ISystem has interface methods