Is it possible to grab *class* IComponentData from an entity?

I have a class IComponentData

 public class ServerDataComponent : IComponentData
{
    public string GameName;
    public string StartServerIp;
    public int GamePort;
}

I am using a class instead of a struct because the string may vary in length.

In my System OnCreate:

        //load up data to be used OnUpdate
        var serverDataEntity = GetSingletonEntity<ServerDataComponent>();
        var serverData = this.GetComponent<ServerDataComponent>(serverDataEntity

And I get this error:
The type 'ServerDataComponent' must be a non-nullable value type in order to use it as parameter 'T' in the generic type or method 'SystemBase.GetComponent<T>(Entity)

How do I get IComponent class data out of an Entity or is that not possible?

You have to use struct for IComponentData. You can use NativeString64 instead of your string fields.
Edit: See post below.

1 Like

No you dont: General purpose components | Entities | 0.16.0-preview.21

@adammpolak You have to use EntityManager.GetComponentData for managed components.

With that being said - you should avoid using managed components unless you have to. Like velen pointed out - you can use FixedStrings instead.

2 Likes

Appreciate it homies! This is for game names and player names in a Unity DOTS NetCode setup.

I went with:

public class ClientDataComponent : IComponentData
{
    public string PlayerName;
    public string ConnectToServerIp;
    public ushort GamePort;
}

And I grab it from a system like this:

        var clientDataEntity = GetSingletonEntity<ClientDataComponent>();
        var clientData = EntityManager.GetComponentData<ClientDataComponent>(clientDataEntity);

It seems like NativeString64 isn’t cutting it:

using AOT;
using Unity.Burst;
using Unity.Networking.Transport;
using Unity.NetCode;
using Unity.Entities;
using Unity.Collections;

public struct SendClientLevelRpc : IRpcCommand
{
    public int levelWidth;
    public int levelHeight;
    public int levelDepth;
    public float playerForce;
    public float bulletVelocity;
    public NativeString64 gameName;
}

gets me:
The type or namespace name 'NativeString64' could not be found (are you missing a using directive or an assembly reference?)

NativeString is from an older version. It’s FixedString now.

using AOT;
using Unity.Burst;
using Unity.Networking.Transport;
using Unity.NetCode;
using Unity.Entities;
using Unity.Collections;
using System.Collections;
using System;

public struct SendClientLevelRpc : IRpcCommand
{
public int levelWidth;
public int levelHeight;
public int levelDepth;
public float playerForce;
public float bulletVelocity;
public FixedString gameName;
}

Gets me:
error CS0723: Cannot declare a variable of static type 'FixedString'

EDIT: Needs to be ** **public FixedString128 gameName;** **

Thank yoU!

You need to specify the length. So FixedString32/FixedString64…etc up to FixedString4096. Just keep in mind these work by using a fixed amount of memory regardless of the actual content of the string.

It seems like using FixedString128 still doesn’t do it:

using Unity.Entities;
using Unity.Collections;


public struct ServerDataComponent : IComponentData
{
    public FixedString128 GameName;
    public string StartServerIp;
    public ushort GamePort;
}

Get:
ServerDataComponent contains a field of System.String, which is neither primitive nor blittable.

public struct ServerDataComponent : IComponentData
{
public FixedString128 GameName;
public string StartServerIp; ← String
public ushort GamePort;
}

Wow… clearly I’m losing it

Thank you :slight_smile: