1
\$\begingroup\$

It may sound like an opinion-based question, but I feel like I am not alone with such problem and this may help others too. I spent a lot of time trying to understand how to make things Unity-way, use the best of the component approach. I read almost everything I can get access to and watched every presentation that I found. But at the end I found myself very confused when it comes to implementation of all this abstract ideas that people were talking about. The last thing that I did not try is asking a question here.

Also I want to mention that I have an experience in programming (mostly OOP) and I am aware of different design pattern, difference between component approach and inheritance, Unity EC vs ECS and all that things. But when it comes to practice with Unity it seems like I am missing something. I will show you an example:

Component approach encourage us to make components small and independent. So we can composite objects from this components easily. I like this idea very much. I decided to make a 2d roguelike to try this approach.

Firstly, I was thinking of what components do I need and there are some from my list:

  • Solid

  • Move

  • Health

  • Activate

So besides Transform and SpriteRenderer: Wall has Solid and Health component. Actor has Solid, Move and Health component. Door has Solid and Activate component. Floor will be empty.

I decided that all objects in my game would be just containers of components, no specific names or tags. Objects interaction logic will be based just on components that object has. In other words, when object with Move components will try to move on specific tile I should somehow get all the components on that tile and then do some logic like (some crazy pseudocode):

Move(x, y) {
    components = getAllComponentsAtCoordinate(x, y);

    if (there is health component in components)
        component.TakeDamage(); //attack 
        return;

    if (there is activate component in components) 
        component.Activate();
        return;

    if (there is no solid components)
        startMoving();
}

And I got stuck at this point. I thought about using raycast to get all objects at the specific coordinate and then get all components from them in some array. But there gonna be too many GetComponent(); methods and this just feels like a wrong way to do it (because getComponent is an expensive operation in Unity).

Or I can use a data structure, that will represent a cell like:

Cell {
    bool passable;
    Actor currentActorStandingHere;
}

(+ inheritance for destructible walls) and then access this cell directly and wrap my logic around this (that how I usually do it in OOP) -- but I will lost all that component prettiness. All objects are now hardcoded (also I dont think that this approach will make use of Unity inspector and all that stuff, because this will be plain c# classes representing the model).

So my question is: how can I use Unity component approach to handle this situation? May some sort of event system help here? Or am I solving this problem a wrong way? I just want to understand how components works in real life. But almost all Unity tutorials that I found were using strong dependencies between components and it seems like it violating the main principle of how unity was made.

Thank you for your attention

\$\endgroup\$
  • \$\begingroup\$ Welcome to GD.SE! At the moment, your question is probably too broad to get a good answer. It'd be great if you could try and make the question more succinct. \$\endgroup\$ – Polar Oct 23 '16 at 22:10
  • \$\begingroup\$ @Polar thanks for a reply, I tried to summarize my question. I hope now it sounds more specific. \$\endgroup\$ – takstakstaks Oct 23 '16 at 22:27
  • \$\begingroup\$ Just because components are a good way to organize an object's behaviours in Unity does not mean they need to be the way you organize your level itself. The 2nd solution sounds like it would do just fine for basic pathing behaviours, and when you need something more specialized, you can look for specific components on the Actor standing there, if any. The Actor class could even cache references to the components you use most, so you save most GetComponent calls. I love components, but we should use them where they make sense, not just spread them on everything for the sake of being component-y \$\endgroup\$ – DMGregory Oct 24 '16 at 3:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.