P
P
PyChan2020-08-01 15:33:07
C++ / C#
PyChan, 2020-08-01 15:33:07

Why does the class field not change?

A script hangs on the player, each frame executing the Move () function

private void Move()
    {
        if (Input.GetKeyDown(KeyCode.W))
        {
            states.currentState.Go();
            Debug.Log(states.currentState);
        }
        if (Input.GetKeyDown(KeyCode.LeftShift))
        {
            states.currentState.Accelerate();
        }
        if (Input.GetKeyUp(KeyCode.A))
        {
            transform.Rotate(new Vector3(0, rotationSpeed * Time.deltaTime, 0));
        }
        if (Input.GetKeyUp(KeyCode.W))
        {
            Debug.Log(states.currentState);
            states.Reset();
        }
        if (Input.GetKeyDown(KeyCode.Space))
        {
            states.currentState.Jump();
        }
    }

states contains a structure that stores and manages player states
. Here she is:
public struct PlayerStates
{
    public PlayerStates(Rigidbody _rb, Animator _anim)
    {
        initialState = new InitialPlayerState(_anim, _rb);
        currentState = initialState;
        walkingState = new WalkingPlayerState(_anim, _rb);
        runningState = new RunningPlayerState(_anim, _rb);
        jumpingState = new JumpingPlayerState(_anim, _rb);
        doubleJumpingState = new DoubleJumpingPlayerState(_anim, _rb);
        focusedState = new FocusedPlayerState(_anim, _rb);
        states = new IPlayerStates[] { initialState, currentState, walkingState, runningState, jumpingState, doubleJumpingState, focusedState };
        foreach (IPlayerStatesDelegates element in states)
        {
            element.switchToWalk += changeToWalking;
            element.switchToFocuse += changeToFocused;
            element.switchToJump += changeToJump;
            element.switchToRun += changeToRunning;
        }
    }
    public IPlayerStates[] states;
    public IPlayerStates currentState { get; set; }
    public IPlayerStates initialState;
    public IPlayerStates walkingState;
    public IPlayerStates runningState;
    public IPlayerStates jumpingState;
    public IPlayerStates doubleJumpingState;
    public IPlayerStates focusedState;
    private void changeToFocused()
    {
        currentState = focusedState;
    }
    private void changeToWalking()
    {
        currentState = walkingState;
    }
    private void changeToRunning()
    {
        currentState = runningState;
    }
    private void changeToJump()
    {
        if (currentState == jumpingState)
            currentState = doubleJumpingState;
        else if (currentState != doubleJumpingState)
            currentState = jumpingState;
    }
    public void Reset()
    {
        currentState.Reset();
        currentState = initialState;
    }
}

Initially states.currentState = new InitialPlayerState(). This class has a Reset() method that turns off the walking or running animation, which does nothing (logically, because initially the player just stands still). When you press W, the player starts moving forward and states.currentState should already become walkingState = new WalkingPlayerState() (an event is executed in the InitialPlayerState class that triggers the changeToWalking method), and when W is released, the Reset method is executed and the player must stop (because in WalkingPlayerState this method turns off the animation). But he doesn't stop! The function that changes the currentState is executed, but InitialPlayerState is still printed to the console.
Here are the state classes themselves:
public abstract class PlayerState : IPlayerStates, IPlayerStatesDelegates
{
    protected Animator anim;
    protected Rigidbody rb;
    protected float jumpSpeed;
    protected float walkingSpeed;
    protected Transform tr;
    
    public PlayerState(Animator _anim, Rigidbody _rb)
    {
        Init(_anim, _rb);
    }
    protected void Init(Animator _anim, Rigidbody _rb)
    {
        anim = _anim;
        rb = _rb;
        tr = rb.gameObject.transform;
        jumpSpeed = 10;
        walkingSpeed = 10;
    }
    protected void Move(float speed)
    {
        tr.position += tr.forward * speed * Time.deltaTime;
    }
    public event ChangeStateToWalking switchToWalk;
    public virtual void Go()
    {
        Move(walkingSpeed);
        anim.SetBool("Walk", true);
        switchToWalk();
    }

    public event ChangeStateToFocused switchToFocuse;
    public virtual bool Focuse()
    {
        anim.SetBool("Focuse", true);
        switchToFocuse();
        return true;
    }
    
    public event ChangeStateToRunning switchToRun;
    public virtual bool Accelerate()
    {
        Move(walkingSpeed * 2);
        anim.SetBool("Run", true);
        anim.SetBool("Walk", false);
        switchToRun();
        return true;
    }
    public virtual void Shoot()
    {
        anim.SetTrigger("Shoot");
    }
    public virtual void AvoidDefeat()
    {
        anim.SetTrigger("Bend");
    }

    
    public event ChangeStateToJumping switchToJump;
    public virtual bool Jump()
    {
        rb.AddForce(Vector3.up * (jumpSpeed / 2));
        anim.SetTrigger("Jump");
        switchToJump();
        return true;
    }
    
    public event Defeated lose;
    public virtual void Defeat()
    {
        anim.SetTrigger("Lose");
        lose();
    }
    public abstract void Reset();
}
public class InitialPlayerState : PlayerState
{
    public InitialPlayerState(Animator _anim, Rigidbody _rb) : base(_anim, _rb)
    {
        Init(_anim, _rb);
    }
    public override void Reset()
    {

    }
}
public class WalkingPlayerState : PlayerState
{
    public WalkingPlayerState(Animator _anim, Rigidbody _rb) : base(_anim, _rb)
    {
        Init(_anim, _rb);
    }
    public override void Go()
    {

    }
    public override void Reset()
    {
        anim.SetBool("Walk", false);
    }
}

+ There is another problem that the player does not move forward when executing the PlayerState.Move() method. I will be very grateful if you help me to solve these 2 problems.

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question