0
\$\begingroup\$

As far as I know, I can detect what objects the player is colliding with is by the following code:

private void OnCollisionEnter2D(Collision2D collision)
{
    if(collision.collider.name.Equals(""))
}

But I have heard that I can use enums instead to reduce computations. Could anyone explain to me using examples?

\$\endgroup\$
5
  • \$\begingroup\$ What exactly are you trying to accomplish? Are you trying to optimise your game? Are you sure this piece of code is using the most resources on your game? \$\endgroup\$ Commented Oct 22, 2019 at 14:57
  • \$\begingroup\$ I get what you are asking but no. No in a way that enums can be used for almost anything, and when compared to something they can either be better or worse (which is out of scope for me to explain), especially your example. A better Question should have you post the enum version agains some other version of your problem, then we could help you a lot more :D \$\endgroup\$ Commented Oct 22, 2019 at 14:59
  • \$\begingroup\$ @TomTsagk I'm making my first game project with my friends in University. in our game the player object can be damaged when it collides with an obstacle or an enemy, in which there are different types of obstacles and enemies that would give different amounts of damage. At first I thought I could using string comparison to detect what the playerObject collided with but I wanted to try using enums instead \$\endgroup\$ Commented Oct 22, 2019 at 15:00
  • \$\begingroup\$ @GamesWerfer If this is your first game, use only the tools you are comfortable with. I'd advice against Premature Optimisation. Speaking from experience, trying to optimise something that is not yet working is one of the reasons projects can get easily abandoned before being finished. Try using string comparison for now, and if you see later on that it doesn't work as you needed, then try to find alternatives. \$\endgroup\$ Commented Oct 22, 2019 at 15:07
  • \$\begingroup\$ I posted two answers to this question. One which makes use of the C# enum feature and another which doesn't but which I think is a better solution for your actual problem. Please pick the one you consider more helpful to you. \$\endgroup\$ Commented Oct 22, 2019 at 16:13

2 Answers 2

1
\$\begingroup\$

I expect that the part you want to optimize is collision.collider.name.Equals("") because you used the Unity Profiler and found out that this particular line of code takes up an unacceptable amount of execution time (I would find that unlikely, though). You also might just want to find out if the other object is friend, enemy or neutral and consider the name of the collider an inappropriate method of doing so (Which I would consider a much better reason).

Let's also assume that you have more than two factions in your game. Because if you only have players and enemies, you don't need an enum to store faction membership. A bool would be much simpler.

In order to do that, you could add a component FactionMembership to each object in your game (or at least those where the friend/foe status is relevant). That class is a wrapper around an enum with all the factions an object can belong to:

public FactionMembership: MonoBehaviour {

     public enum Faction {
          CATS,
          DOGS,
          HAMSTERS
     }

     public Faction faction;
}

When you add this component to a GameObject, you will have a dropdown menu in its inspector where you can pick the faction it belongs to between "CATS", "DOGS" and "HAMSTERS".

You don't need to create a separate MonoBehaviour for this, by the way. You could just add this enum and public variable to an existing one if you have one where it makes sense. But I don't know what else you got in your project, so let's go with a dedicated behaviour for this.

Now back to your collision function. I assume you want to find out if the object belongs to a different faction. In that case you would do this:

private void OnCollisionEnter2D(Collision2D collision)
{
    // get the faction membership components of both objects.
    // note: if you call this function a lot, you might want to 
    // store myFactionMembership in a private class-level variable
    // which you read in Start to improve performance
    FactionMembership myFactionMembership = GetComponent<FactionMembership>();
    FactionMembership otherFactionMembership = collision.gameObject.GetComponent<FactionMembership>();

    // do both objects in this collision actually have a faction membership? 
    // If not, then we are not interested in this collision.
    if(myFactionMembership == null || otherFactionMembership == null) {
         return;
    }
    // check if we have encountered an enemy
    if (myFactionMembership.faction != otherFactionMembership.faction) {
          Console.log("Enemy encountered!");
    }

}

This code of course assumes that all 3 factions we have in this game are mortal enemies who will always fight each other. But this might not always be the case. For example, what if the dogs and the hamsters have forged a temporary alliance against the cats? In that case it might make sense to add a helper method bool IsEnemyOf(FactionMembership other) to FactionMembership.

    FactionMembership myFactionMembership = GetComponent<FactionMembership>();
    FactionMembership otherFactionMembership = collision.gameObject.GetComponent<FactionMembership>();
    if(myFactionMembership == null || otherFactionMembership == null) {
         return;
    }

    if (myFactionMembership.IsEnemyOf(otherFactionMembership)) {
          Console.log("Enemy encountered!");
    }

How that method determines which factions are enemies and which are not is outside of the scope of this answer, because the logic for this could get quite complex depending on what exactly your requirements are.

\$\endgroup\$
0
\$\begingroup\$

A common method to find out what kind of game object you are actually colliding with is to use collision.gameObject.GetComponent to find out if it has a certain component attached to it and then act accordingly.

For example, if all enemies and obstacles in your game have a script Hazard and all the collectible goodies have a script Collectible, you can write code like that:

private void OnCollisionEnter2D(Collision2D collision)
{
      Hazard hazard = collision.gameObject.GetComponent<Hazard>();
      if(hazard) {
            Console.Log("We collided with something bad :(");
            life -= hazard.damage;
      }

      Collectible collectible = collision.gameObject.GetComponent<Collectible>();
      if(collectible) {
            Console.Log("We picked up something good :)");
            score += collectible.scoreValue;
      }
}

By the way, you might notice that this code allows for an object to be both a hazard and a collectible at the same time.

\$\endgroup\$

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.