Hi just want to ask which one is better and why ? (or maybe there's even better solution please I need advice)
public class Player
{
GameController _gameController;
public Player
{
_gameController.OnPlayerGetHit += GetHit;
}
private void GetHit(float damage){}
}
public class GameController
{
public delegate void PlayerHitCallback();
public event PlayerHitCallback OnPlayerGetHit;
public OnCollisionHit()
{
OnPlayerGetHit?.Invoke();
}
}
or
public class Player
{
public void GetHit(float damage){}
}
public class GameController
{
Player _player;
public OnCollisionHit()
{
_player.GetHit(damage);
}
}
I want to ask wether Top solution is better or worse than the later (or maybe both of them is no good) please help I need some advice. Thanks in advance !
Actually, there are far more alternatives available in Unity for the same goal: passing over information and triggering actions between objects.
As me and others said in the comments, the "best" choice depends on a lot of things, like: the size and expected timelife of your app, design choices, experience of the coders, specific problem to solve, personal preference...
By no means I intend to give an ultimate answer to this, but I can share a founded point of view, taking those factors into consideration.
After all, I'd just state the same I said In the comment: If you are doing a big application with lots of classes and component, possibly being developed by different people, having the classes need to know much about each other can be a bad, and a change in one component may result in breaks in all sort of places along the application. But, if your application is small and the relationship between the classes is pretty obvious, you shouldn't bother making your stuff that fancy and you should bother on more important things, like shipping your game.
Although, there are some differences in the intended use of those tools that I'd like to point.
Calling a method directly on the other object demands from your caller 2 things: 1) to know who is the calee (have a reference to it) and what will happen in there (to know the method name and objective). There are many situations where it stands. Suppose your game controller is responsible to make the player move around the world. You probably already have a reference to a player, and you want to make it, and just it, to know when to move. You'd better call player.move()
.
Calling a method in an object is like calling your friend to say you are available tonight to hang out.
Calling an event is other stuff. Your player can die in the world. Many components could be interested in knowing when the player just died. An audio manager may want to play a SE. A net controller may want to communicate to a web server. An achievement system may want to give a prize, the enemies may want to celebrate... All those components shall have had subscribed to player.OnAboutToDie
and all this will happen in appropriate occasion. With events, you are communicating everyone interested in your message (maybe nobody), without control on what are they doing with this information. It's like posting on your Twitter that you are available tonight...
C# events and Unity events play the same role, the difference is that c# events are universal among all c# packages and programs, are more flexible and fast. Unity events can be manipulated in inspector by non programmers and have other unity related benefits.
There's also the Unity's Message System. This is what makes things like Update and Start to work on all monobehaviours and stuff. This is an exaggeration of the message passing metaphor that I described before. All objects that implements a message named alike will be triggered by SendMessage
and even it's children with BroadcastMessage
. It is like paying the local radio station to announce you are available tonight...
Edit: I just realized OP never mentioned Unity in the question [:facepalm]. The answer still applies, though.