Is there a better way for this work other than if else statements?

So I'm working on a bullet change system to a weapon. I'm using tags to check if the object collided with is equal to a certain String and then make the current projectile equal to that specific bullet. I feel like there is a better way to do this but I'm not sure.. Here is the code:

public class BulletChange : MonoBehaviour
{
    BulletManager bm;

    private void Start()
    {
        bm = FindObjectOfType<BulletManager>();

        //Destroying Egg After 4 Seconds
        Destroy(gameObject, 4f);
    }
    private void OnTriggerEnter2D(Collider2D collision)
    {
        //Setting Current Projectile Depending On The Taken Egg

        if(collision.gameObject.GetComponent<PlayerMovement>())
        {
            if(tag.Equals("CannonBall"))
            {
                bm.setCurrentProjectile(bm.getCannonBallPrefab());
            }

            else if(tag.Equals("Laser"))
            {
                bm.setCurrentProjectile(bm.getLaserPrefab());
            }

            bm.showIcon(); //Showing Icon Of New Ammo
            Destroy(gameObject);  //Destroying Egg After Collision With Player
        }
    }
}

Honesty the else if, is quite fine for just a couple items. You could shorten it to this.

if(tag.Equals("CannonBall"))
    bm.setCurrentProjectile(bm.getCannonBallPrefab());
else if(tag.Equals("Laser"))
    bm.setCurrentProjectile(bm.getLaserPrefab());

If you end up with more than two projectiles. Just change it to a Switch statement.

switch(tag){
    case: "Cannon":
        bm.setCurrentProjectile(bm.getCannonBallPrefab());
    break;
    case: "Laser":
        bm.setCurrentProjectile(bm.getLaserPrefab());
    break
}

Maybe overkill, but you can always use a dictionary. I'm pretty sure someone has even made a plugin to show dictionaries in the inspector for easy use.

if(collision.gameObject.GetComponent<PlayerMovement>())
{
    bm.setCurrentProjectile(myDictionary[tag.name]);

    bm.showIcon(); //Showing Icon Of New Ammo
    Destroy(gameObject);  //Destroying Egg After Collision With Player
}

If you don't want a dictionary, create a class list.

using system.linq;

public class BulletItem
{
    public string name;
    public gameobject prefabBullet;  
}

public list<BulletItem> bulletItems;

if(collision.gameObject.GetComponent<PlayerMovement>())
{
       bm.setCurrentProjectile(bulletItems.Single(x => x.name == tag.name).prefabBullet);

    bm.showIcon(); //Showing Icon Of New Ammo
    Destroy(gameObject);  //Destroying Egg After Collision With Player
}

I really respect that you are trying to improve/learn on even the littlest things. Good luck dude!

1 Like


Thanks for the reply :smile: I will try these out

IMHO I always find switch statement horrible:
- because they are actually horribly more verbose than if else, {...} is less (2 symbols) than case ... break; (10 symbols)!
- if you forget a break, the behavior is to fall through, and it can be hard to debug, a missed bracket is instant signaling from the ide
- generally you start with code having simple test, but when you evolve teh code and some case need more complex check, you have to completely destructure the expression, with if it's easier to separate, append and move "node". I found that switch resist much less to game dev than if, because of iterations and evolving design.
- it's generally just compile the same under the hood, so there is no real advantage anyway.

If 'im wrong I would like to have counter argument, because

I mean compile errors are a good argument. You can't miss a break without getting an error. I dont know any real programmer that would rather see if/else if/ else if/ else if/ ielse if/ else etc.

Not to mention for every if/else you have to set the left hand condition. With a switch, you set it once.

As I mentioned, one or two are fine. Passed that its a no no.

My personal rule is :

if (a == 1)
    Foo():
else
    Bar();

Is the maximum. If 'a' can have other predetermined values, switch to switch right away.

1 Like


That's kinda a problem for me, at least in game dev, because sometimes you need the nth condition to be different for specific case, and then the code become more messy. But that's specific case.


[quote]
You can actually, it fall through, it's an intended behavior, if not then break is redundant and could be omitted because the next case statement would be a boundary, in some language (blitz3d) that's how it work, there is no fallthrough.
[/quote]
I'm wrong c# don't allow fallthrough, wich make break useless and awful
https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/switch


I don't get way, styliztically switch are worse to me, also most of the time even in case I should use switch, I already have bool so I just do if (test) or if (!test), most of time most can be true at the same time so if else is basically a priority structure, that is if nth is true and nth +1 is also true, nth take priority in execution and nth+1 is not executed.

I mean I want argument, that stem from experience, that are not it's poo poo
I'm talking from my own experience here.

I want to rephrase the question then, outside of switch, what are the other alternative to if else, that fit the case I outlined above?

So far, I had kind of evolve avoiding switch and if altogether for object assignment, but that's less performant, even though you will have to do million of operation per frame to feel the impact. So there is architecture alternative, my only problem is that the logic structure code become obfuscated because you would have to jump around many declaration to understand what's going on. So I see myself reverting back to if tree but organized with the Decision/Behavior tree logic pattern. (ie if are node, and you append then with nesting). I would like to go further by making the test data driven, but I haven't found a way to do it.

[quote]
My personal rule is :

if (a == 1)
    Foo():
else
    Bar();

Is the maximum. If 'a' can have other predetermined values, switch to switch right away.
[/quote]
In that case you would use a ternary operator, so you would only use that or switch and no if else. :p

The break is just a way to leave the switch case, many other things can be used. Return etc.

But his nth condition is the same...

Do you have anything helpful to add to this guy's question, that nobody already has?


Exactly. Except ternary operator is only if I actually assign the value. No if-else, only if related, but not the same if-statements need to be bundled up. Obviously you don't have many choices there.

I guess you just have to decide one thing, do you want to be a game designer who can program a big long if-else. Or do you want to be a real programmer who makes games with good code... :sunglasses:

LOL. I just wrote this in my code:

            if (dX > dY && dX > dZ)
                iX = -iY - iZ;
            else if (dZ > dY)
                iZ = -iX - iY;

(pixel-calculation, local variables before refactor, don't judge :P )


but is it good code if there is no logic about it, code isn't about beauty contest, imho ifelse can be more readable, flexible and maintainable than switch, a real programmer care about fact and logic. ;)


It is matter of experience (working with others). If you write if-else-if, I expect different statement in the else-if. Because if it is the same (I mean you test the same variable) it is unnecessary mental load parsing the statements again and again, meanwhile reading the switch statement you parse the left hand side once (tag) and just go through the case-s, so you see all the right hand sides. It's easier on the brain than always parsing else if(lopikulaGameObject.CompareTag("izebogyo")).
You know.

2 Likes


This sounds like another response of "don't do this! is no good! I don't like because of x." I really wish people would stop this. You are wrong, not by what you state about switch statements, but that you are giving advice to not use a tool available to a programmer because it doesn't suit your code style.

@xXAl-HarereXx I want to let you know that using tag creates a string every time it is used. This will create garbage, how you have it with the if/else if is perfectly fine, but I would switch to using CompareTag("CannonBall") that is garbage free. If you find it becoming too many if/else if, you may want to refactor your code, but always make sure its a problem before making a significant change. Remember the profiler is your best friend(and the frame debugger too.)

1 Like


Didnt know about the tag thing. Thanks I will use compare tag :)


Ironically that's your answer too, and it wasn't an advice it wakings an observation, which is why i ask other people to weight into it, ie no dogma. Ultimately @ give a sensible reason about scanning the code. And ultimately you are wrong because there is valid reason to discourage some pattern, like using Goto and jump, even though it's available and if else is as much a tool at disposition than switch.

Recently there was a lot of drama about the leak code of yandere simulator, done with unity, because there was huge if else tree, and that was stupid because it was one case where lurking ninja is right, if the condition isn't the same, or potentially not the same, switch won't help. And the dev follows some other pattern like imitating behavior tree organization.

Knowing when to apply and when not is key, that's also why, outlining case where switch case would fail, i asked if there was alternative structures, so we effectively used all tools at disposition.

Ultimately if OP code won't evolve to break the conditional, he should use switch, assuming the verbosity don't bother him. Ie he has a complete overview to decide himself.


How is it irony? Please explain.

I would quit trying to debate with this guy haha, no point. OP has all the advice he needs Anyways. Iā€™m about to unfollow this thread too lol.

1 Like