-1

I've been trying to implement shapeshifting mechanic to my game. And there are three current modes that you can switch between. But there seems to be a problem with the if checks im using or the way im using it. I asked some people but they told me to use state machines which i found really complicated for my simple code. But i would also like to hear your opinion.

Here's the code:

if (Input.GetKeyDown(KeyCode.Space))
{
    if (normalMode == true || normalMode == false && speedMode == true && (heavyMode == false))
    {
        normalMode = false;
        heavyMode = true;
        sr.sprite = heavyForm;
        speed = 7f;
        rb.mass = 2f;
    }
    else if (normalMode == true || normalMode == false && (heavyMode == true && (speedForm == false)))
    {
        normalMode = false;
        speedMode = true;
        sr.sprite = speedForm;
        speed = 15f;
        rb.mass = 0.5f;
    }
    else 
    {
        normalMode = true;
        sr.sprite = normalForm;
        speed = 10f;
        rb.mass = 1f;
    }
}

only the if and else statements work and the else if one doesn't. Would be glad if someone helped me out.

7
  • 3
    what does "doen't work" mean? Any exception? Unexpected behaviour? Commented Aug 9, 2024 at 6:25
  • 4
    just look at your second case : normalMode == true && normalMode == false Commented Aug 9, 2024 at 6:26
  • 2
    The first one works because && has higher priority than ||. Commented Aug 9, 2024 at 6:28
  • You really need to figure out how your conditions should look like, then just revise and rewrite them carefully. Commented Aug 9, 2024 at 6:31
  • 1
    Do note that a list of conditions like this is a form of state machine. But for most simple state machines you would at least use an enum and a switch to make the code clearer and safer. The more advanced, object based state machines, tend to be helpful for larger and more complex cases. Commented Aug 9, 2024 at 7:00

2 Answers 2

3

Okay, much to unpack here.

You have three seperate states. Normal. Speed. Heavy. And it seems it can be exactly one of those. But you have a mess of a variables that you need to be extra careful with, to not accidentially set them to a state where it's all broken. Because right now, you could set them to a state, where they are all of the above. Or two. Or none. Broken. Don't build a program where "broken state" is possible. That makes finding mistakes much easier, because a big part can be caught be your compiler.

Then, don't mix two concerns. One concern is setting values for each mode. One concern is changing modes. Seperate them out. This way it is easier to see what happens.

So we write a function for setting values, to make code more readable, and we use an Enum to create our own datatype, which can be only one of the states, either Normal, or Speed, or Heavy. There is no way to accidentially screw up the multiple state variables, if there is only exactly one:

enum CharacterMode { Normal, Speed, Heavy }

// somewhere where you keep your variables:
var currentMode = CharacterMode.Normal;

if (Input.GetKeyDown(KeyCode.Space))
{
    if (currentMode == CharacterMode.Normal)
    {
        SwitchToMode(CharacterMode.Heavy);
    }
    else if (currentMode == CharacterMode.Heavy)
    {
        SwitchToMode(CharacterMode.Speed);
    }
    else if (currentMode == CharacterMode.Speed)
    {
        SwitchToMode(CharacterMode.Normal);
    }
}

// somewhere where you keep your functional logic:
public void SwitchToMode(CharacterMode mode)
{
    this.currentMode = mode;
    
    switch(mode)
    {
        case CharacterMode.Heavy:
            sr.sprite = heavyForm;
            speed = 7f;
            rb.mass = 2f;
            break;
        case CharacterMode.Speed: 
            sr.sprite = speedForm;
            speed = 15f;
            rb.mass = 0.5f;
            break;
        case CharacterMode.Normal:
            sr.sprite = normalForm;
            speed = 10f;
            rb.mass = 1f;
            break;
    }
}

(I don't have a compiler at hand, sorry if I missed a semicolon or bracket somewhere)

Sign up to request clarification or add additional context in comments.

9 Comments

I'd make the if/ else chain also a switch/ case, so the compiler will notify me to fix that place whenever there will be another case added.
first off thank you so much for your time and effort writing this. Second there is two errors and i dont know what to do can you help me out with those too? CS0051 for public void SwitchToMode line and CS0825 for var currentmode line would be glad if helped
@Cramon believe it or not but we actually haven't 100s of error codes memorized :D Consider updating the question with your current attempt code and we can go from there.
@Cramon The errors are likely because I don't know how your full code file looks like. The lines I posted aren't one piece of code, they have to be copied into the appropriate positions in your file.
the code is pretty much the same except the enum name. The error i get is for putting the var currentMode next to my variables it needs to be in a method but one is in update and the other one is in SwitchToMode. The other one is: Inconsistent accessibility: parameter type 'type' is less accessible than method 'method' for SwitchToMode for having the enum in it i guess.
|
0

The else if will never be satisfied due to this part of condition

normalMode == true && normalMode == false

which never be true and whole expression will evaluate to false.

You have to correct that in some way.

2 Comments

My bad changed it to || again I was trying to adjust and see if it worked. But that "or" check doesnt work either
A || !A is always true ... so it is irrelevant for that case.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.