Pick-up script on Player or Coin game object


Pick-up script on Player or Coin game object



I watched Basic Platformer Game tutorial for Unity where presenter created coin pick-up script that he attached to Coin prefab.



Let's say we have a game with pick-upable objects. They do nothing more than incrementing the score (or affecting the player in another way) and destroy themselves on collision.



I was wondering that what is the preferred approach to this problem.



I've come up with two approaches:



Approach A



Have one ObjectPickup script on the player game object. This script would do whatever is required depending on the type of collided object.


private void OnTriggerEnter2D(Collider2D other)
{
if (other.gameObject.CompareTag("Coin"))
{
IncrementScore();
Destroy(other.gameObject);
}
else if (other.gameObject.CompareTag("SuperSpeed"))
{
IncreasePlayerSpeed();
Destroy(other.gameObject);
}
}



Approach B



Have CoinPickup script on every coin and SuperSpeedPickup script on every super speed powerup.


private void OnTriggerEnter2D(Collider2D other)
{
if (other.gameObject.CompareTag("Player"))
{
other.gameObject.IncrementScore();
Destroy(gameObject);
}
}



And other script:


private void OnTriggerEnter2D(Collider2D other)
{
if (other.gameObject.CompareTag("Player"))
{
other.gameObject.IncreasePlayerSpeed();
Destroy(gameObject);
}
}



Is Approach A more efficient then Approach B? If so what is the rough number of GameObjects when Approach A becomes preferable?



Or is it always better to work with Approach B as it seems to be cleaner (when we have a number of different pick-upable objects)?





Player object should probably have ability to pickup things. It should detect if it collided with a pickable object (e.g. by having "Pickable" tag).
– FCin
Jun 29 at 9:32





I think (but I am absolutely not sure about that, so I'm posting as a comment), that performances are not an issue, here. Unity should "arrange" the OnTriggerEnter logic from all the objects in a specific loop, dedicated to collision detection and managed by the engine. Personally, I've always implemented approach A, for letting the programming logic "player-centric" (the player is the one that should do things when it collides with other objects, in my perspective).
– Andrea ジーティーオー
Jun 29 at 10:29




4 Answers
4



In your example, "approach a" would be more efficient than the other because the OnTriggerEnter2D is called once. With "approach b", OnTriggerEnter2D is called twice on two different scripts. It's slower for Unity to make callback calls let alone on two different scripts + the player. Also, OnTriggerEnter2D is sent to disabled MonoBehaviours which makes "approach a" more efficient choice. The main reason for the slow event call is because the call is made from native C++ side of the code to the Unity's C# API side and this is costly.


OnTriggerEnter2D


OnTriggerEnter2D


OnTriggerEnter2D


MonoBehaviours



Note that it really doesn't matter that much. This is just an attempt to answer your question for which one is more efficient but what you're doing is a micro-optimization.



The thing that should play big role in this decision is the behavior of the coin after the trigger.



If the coins behave the-same then use "approach a" and do the detection on the player's side.



If the coins have different behavior like coins with different score values, color and action(animation) when they are collected then do the detection on the coins side and handle each coin. This is the reason why scripts are attached to GameObjects in the first place. You don't need different tags for each different coin. Use enum to distinguish their action in the OnTriggerEnter2D function. It would be awful to use "approach a" to handle this in this case.


enum


OnTriggerEnter2D



Approach A sounds a bit more performant, also it would work with multiplayer. If you have n players, local or online, you'd need to check the player id on the coin. Otherwise you'd need a lot of tags. No need to do that if the players detect item collisions themselves.





Why would you have to tag them? Collision picks the correct player already.
– Zizy Archer
Jun 29 at 11:27





valid argument.
– KYL3R
Jun 29 at 11:45



Considering you can create a prefab for every coin and for every super speed power up with the second approach script already attached to it AND considering you can spawn them very easily from anywhere in the code I'd really stick to the second approach, making it more sensible, clean and clearly understandable from everyone.



I don't like (and I wouldn't absolutely use) the first approach for this specific purpouse mainly because the OnTriggerEnter2D is very likely to be fired a very large number of times since it's put on the player and the player is moving around colliding with stuff everywhere.


OnTriggerEnter2D





Player most probably already has a colider assigned to it, so it is going to collide with everything anyway.
– FCin
Jun 29 at 9:54





Yeah it's just to spare some useless checks in the collider code to make everything cleaner and more well organized (and, of top all, separated from a logic point of view, at least in my experience/opinion)
– greyhame
Jun 29 at 9:58



I should use the B, cause it's more like how object-programming works (at least on my head!) even if it's more expensive.



But Method A do not split interactions, so imagine that you can collide with 2 different pickable objects, and you collide with bouth at the same time. If you use Method A, it will use allways the same collision-order, which can be desired or not!



But clearly with Method B you don't really know which object will be picked first (in this concrete case!)






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Comments

Popular posts from this blog

paramiko-expect timeout is happening after executing the command

Export result set on Dbeaver to CSV

Opening a url is failing in Swift