- Home /
Component architecture problem
I have read countless articles on component model, but I am still having some problems. Lets try with example im trying to make. I have an inventory with only one item inside,It can be picked up, dropped and used. I want to make different behaviours for using a different item. This is my InventoryItem GameObject composition.
I have exposed attributes that need to be shared between objects as a class attached to gameObject so everyone can read or modify it if needed.
//VelocityAttribute.cs
public class VelocityAttribute : MonoBehaviour
{
public Vector3 Velocity;
}
After that i have a movement component that is using velocity only to apply gravity and call raycast based collision detection component whitch is controller2d. This is because my items can sometimes be thrown, and if they are dropped in the air to fall to the ground.
//DefaultMovement.cs
[RequireComponent (typeof (VelocityAttribute))]
[RequireComponent (typeof (Controller2D))]
public class DefaultMovement : MonoBehaviour
{
VelocityAttribute velocityAttribute;
float gravity = -9.81f;
Controller2D controller;
void Awake ()
{
velocityAttribute = GetComponent<VelocityAttribute> ();
controller = GetComponent<Controller2D> ();
}
void Update ()
{
velocityAttribute.Velocity.y += gravity * Time.deltaTime;
controller.Move ();
}
}
Then i have an interface for all usable items.
//IUsable.cs
public interface IUsableItem
{
void Use();
}
My concrete UsageScript.
//ThrowUsage.cs
public class ThrowUsage: MonoBehaviour,IUsableItem
{
VelocityAttribute velocityAttribute;
void Awake()
{
velocityAttribute= GetComponent<VelocityAttribute> ();
}
public void Use()
{
velocityAttribute.Velocity = Vector3.right;
}
}
And finally my inventoryItem.
//InventoryItem.cs
public class InventoryItem : MonoBehaviour,IInventoryItem
{
IUsableItem usableItem;
void Awake()
{
usableItem=GetComponent<IUsableItem>();
}
public void Use()
{
usableItem.Use ();
}
}
Is this the right way to do it in unity or is there some other better approach ? What bothers me, if I call Use() on my item, in current frame movement component could already be executed and it could skip frame.
Should I have one script that will fetch all others on GameObject and sync them to be executed in determined order, or they can safely be separated?
Imagine if i had 2 or 3 scripts with Update().There is no way to determine in what order they will fire, and usually its important. I know i can add them to execution order in unity but doing that for alot of scripts is a major headache.
I know, this is alot of questions buy as you can see, I am completely lost. So the question is: What is standard practice in unity solving these problems with component based programming?
Am I completely off road? :)
Hi, it's always difficult to answer as the architecture depends on your project's needs and those needs are not known at project's start... So, what I usually do is keep it simple at first because I know this architecture will need to be modified during the project's life. $$anonymous$$eep it simple and refactor often, that would be my advice :-)
Going with simple focused components/monobehaviours worked well for me, but as always, there is a balance to find, too many small components can be difficult to maintain. I would not go with interfaces at first as component can play this role quite well.
Thanks on advice, and yes, I am having a feeling that i am overengineering things very often. Need to work harder on that aspect i think.