andoowhy / EgoCS

EgoCS: An Entity (GameObject) Component System framework for Unity3D
MIT License
223 stars 31 forks source link

Setting Public Variables of Components #9

Closed owengalenjones closed 7 years ago

owengalenjones commented 7 years ago

Hello, curious what the best way to do accomplish something would be.

In an RTS style game, I have a Selectable EgoComponent that has a public GameObject SelectionGraphic on it that displays a Projector on the ground when the unit is selected.

Currently I'm passing in the SelectionGraphic in a script that runs when the Scene is instantiated and gets passed to the SelectableComponent:

Ego.AddComponent<SelectableComponent> (g).selectGraphic = this.selectionGraphic;

I would love to be able to set the SelectionGraphic public variable in the editor, but it appears when I do this method it gets overwritten at run time. Is this true? Is doing it via script the only way?

Thanks!

andoowhy commented 7 years ago

By "Selectable EgoComponent", do you mean your SelectableComponent class derives from EgoComponent? If so, it should derive from MonoBehaviour instead.

owengalenjones commented 7 years ago

Sorry I should've been more explicit, the classes look like this:

SelectableComponent.cs

using UnityEngine;

[DisallowMultipleComponent]
public class SelectableComponent : MonoBehaviour
{
    public GameObject selectGraphic; // this is what I would love to set in the Editor
                                         // for all SelectableComponents
    public EgoComponent selectGraphicInstance;
    public bool selected = false;
}

SceneInstantiation.cs


public class Tester : MonoBehaviour {
  public GameObject selectionGraphic;  // this is set from the editor
  void AddComponents(EgoComponent g) {
    // called from scene Start()
    Ego.AddComponent<SelectableComponent> (g).selectGraphic = this.selectionGraphic; 
    // passed to SelectableComponent
  }
}

This approach works but it seems odd to set the public variable of the component from the unrelated class. I could also see the public GameObject selectionGraphic; being moved to the SelectableSystem.cs class but that breaks this rule:

Systems SHOULD NEVER store any data, i.e. no variables or constants. They can only have Start(), Update(), FixedUpdate(), Event Handler methods, and helper methods.

Thanks so much! I really enjoy EgoCS, I really like the decisions that let it play nice with Unity compared to other ECS systems I've seen.

andoowhy commented 7 years ago

I suggest makingSelectableComponent.selectGraphic a prefab reference set from the editor (and renaming it selectGraphicPrefab to make it clearer). Then you instantiate those prefabs with a SelectGraphicInstantiationSystem with the appropriate Start() method.

Have a look at how I instantiate Bricks in BreakoutWithEgoCS, more specifically BrickInstantiation.cs and BrickInstantiationSystem.cs.