Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

26.01.2015, 11:23

Entity-component-system (ECS)

Hallo zusammen

Ich arbeite zur Zeit an einem Entity-component-system (ECS) in C++, welches ich für meine Spiele verwenden möchte.
Zu diesem Thema finden sich im Internet sehr viele Informationen, teils auch sehr detailliert. Leider komme ich an einem Punkt nicht mehr weiter.
Ich muss jedoch kurz ausholen.

Ich baue mein ECS wie folgt auf:

- World-Class enthält (aktuell noch in einer Map) sowohl die Entities als auch die Systeme. Wenn eine neue Entitiy als auch ein neues System
erstellt werden, läuft dies über die World-Class. Dabei erhält jede neue Entitiy bzw. jedes neue System eine eigene ID. Die beiden int Variablen sind auf
static gesetzt
- Entity-Class enthält (aktuell noch in einer Map) die entsprechenden Components (z.B. SpriteComponent, TransformComponent etc.) -> Nur Daten.
- System-Class enthält entsprechend die Systeme wie z.B. SpriteRenderingSystem -> Nur Logic

Aufbau sieht grob wie folgt aus:

System/Untersysteme:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class System {

public:

virtual void Update() = 0;

}

class SpriteRenderingSystem : public System {

public:

void Update();

}


Component/Spezifische Components:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class Component {

....

}

class SpriteComponent : public Component
{
    public:
    
    SpriteComponent(string sFilename, string id, int width, int height);
    
    int getWidth() { return m_width; }
    int getHeight() { return m_height; }
    string getID() { return m_id; }
    
    private:
    
    int m_width;
    int m_height;
    string m_id;
    
};

}


Das Problem liegt nun bei der Erstellung der Components in der Entity-Class.
Ich füge aktuell ein neues Component wie folgt an:

C-/C++-Quelltext

1
m_player->CreateComponent(new SpriteComponent("/.../player.png", "player", 20, 20), SPRITE_COMPONENT);


In der Entity-Class passiert dann folgendes:

*.hpp:

C-/C++-Quelltext

1
Component *CreateComponent(Component *component, int componentType);


*.cpp:

C-/C++-Quelltext

1
2
3
4
5
6
7
Component* Entity::CreateComponent(Component *component, int componentType)
{
    Component *newComp = component;
    m_mComponents[componentType] = newComp;

    return newComp;
}


*.hpp:

C-/C++-Quelltext

1
map<int, Component*> m_mComponents;


Mit diesem Konstrukt ist es mir jedoch NICHT möglich auf die Subkategorien der Component wie z.B. SpriteComponent zu zugreifen.
Dies heisst also, dass ich whs. mit Templates arbeiten muss. Genau hier ist mein Problem. Ich habe schon alles mir möglich versucht, in eine map
(geht es überhaupt) eine Variable einzufügen welche halt je nach Component an der zweiten Stelle SpriteComponent* bzw. TransformComponent* heisst.
Aber dies klappt nicht. Habe auch gelesen man sollte mit unique_ptr arbeiten, aber ich muss ganz ehrlich sagen da stosse ich echt an meine Grenzen.

Mein Versuch ging in folgende Richtung:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
template <typename T>;
T& CreateComponent(T *component, int componentType);

...

template <typename T>;
T& Entity::CreateComponent(T *component, int componentType)
{
    T *newComp = component;
    m_mComponents[componentType] = newComp;

    return newComp;
}

...


Ich hoffe jmd. kann mir helfen!

Danke!

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

2

26.01.2015, 12:52

Die Möglichkeiten und Probleme dieses Ansatzes wurden hier schon diskutiert:
ECS | Organisation der Entitys / Actors

Dir fehlt die Möglichkeit des Double-Dispatches und Du musst Dir überlegen Entities und Components eben anders so zu registrieren, dass Du keine Laufzeit-Typ-Information benötigst. Diese Typ-Information macht Dir nämlich in Kombination mit Heap-Daten sämtliche Vorteile eines ECS komplett kaputt.


Kommt es mir nur so vor oder sind durch Unity alle Anfänger im Moment total auf einem ECS-Hype, unabhängig davon, ob das überhaupt sinnvoll ist?
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

3

26.01.2015, 13:53

Besteht im Moment ein "ECS-Hype"? Vielleicht, ich weiss es nicht.
Ich für meinen Teil habe Spass neue Wege kennen zu lernen und die Dinge auch vom grundlegenden Ansatz zu verstehen.
Unity habe ich bis dato noch nicht verwendet, mir ist aber bekannt dass Unity auf dem ECS basiert.

Danke für deine Antwort BlueCobold. Ich hoffte eine konkrete Antwort (Code-Lösung bzw. Code-Ansatz) zu meinem Ansatz zu erhalten.
Anscheinend muss ich aber zwei Schritte zurück, da der grundsätzliche Weg nicht richtig ist.

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

4

26.01.2015, 15:18

Nun, ich kann mich nur wiederholen. Typen zur Laufzeit zu checken, kann nicht Sinn der Sache sein. Du willst sie anders organisieren. Vorschläge zur Umsetzung so einer Organisation findet sich eben im anderen Topic.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Werbeanzeige