private void Update()
    {
        if (_characterController.isGrounded && _velocity.y < 0.1f)
        {
            _velocity.y = -2.5f;
        }

        playerIsGrounded = _characterController.isGrounded;

        // Wall-running raycast and hit info checks
        DoWallRunCheck(_stateParams, _velocity, _characterController.isGrounded);

        // Tick our current state to handle our movement
        _stateParams.Velocity = _velocity;
        _stateParams          = _stateMachine.Tick(_stateParams);
        _velocity             = _stateParams.Velocity;

        // Update our horizontal velocity variable
        _horizontalVelocity.x = _velocity.x;
        _horizontalVelocity.z = _velocity.z;

        // Handle our horizontal movement
        _characterController.Move(_velocity * Time.deltaTime);

        // Apply gravity (call move twice because t-squared)
        HandleGravity();

        //DebugPrintVelocity();
    }
示例#2
0
    public IStateParams Tick(IStateParams stateParams)
    {
        var stateParamsVelocity = stateParams.Velocity;

        // Gather input and create an input vector from the values
        float forwardSpeed  = PlayerInput.Instance.VerticalRaw;
        float sideSpeed     = PlayerInput.Instance.HorizontalRaw;
        var   inputVelocity = (_player.transform.forward * forwardSpeed) + (_player.transform.right * sideSpeed);

        // If we hit Crouch while Jumping, we want to land in a slide
        if (PlayerInput.Instance.CrouchDown)
        {
            ToSlide = true;
        }

        // Handle aerial movement and wall jumping
        if (stateParams.WallJumped)
        {
            _doJump = false;
            stateParams.WallJumped = false;
            stateParamsVelocity    = HandleWallJumping(stateParamsVelocity, forwardSpeed, sideSpeed);
        }
        else
        {
            stateParamsVelocity = HandleJumping(stateParamsVelocity, inputVelocity);
            stateParamsVelocity = HandleMovement(stateParamsVelocity, inputVelocity);
        }

        stateParams.Velocity = stateParamsVelocity;
        return(stateParams);
    }
示例#3
0
 public IStateParams OnEnter(IStateParams stateParams)
 {
     if (PlayerInput.Instance.SpaceDown || stateParams.WallJumped)
     {
         _doJump = true;
     }
     return(stateParams);
 }
示例#4
0
    public IStateParams Tick(IStateParams stateParams)
    {
        var stateParamsVelocity = stateParams.Velocity;

        stateParamsVelocity.x = 0;
        stateParamsVelocity.z = 0;
        stateParams.Velocity  = stateParamsVelocity;
        return(stateParams);
    }
示例#5
0
    public IStateParams Tick(IStateParams stateParams)
    {
        StateTransition stateTransition = CheckForTransition();

        if (stateTransition != null)
        {
            stateParams = SetState(stateTransition.To, stateParams);
        }
        return(_currentState.Tick(stateParams));
    }
示例#6
0
    public IStateParams OnEnter(IStateParams stateParams)
    {
        var stateParamsVelocity = stateParams.Velocity;

        if (stateParamsVelocity.y < 0)
        {
            stateParamsVelocity.y = 0;
            stateParams.Velocity  = stateParamsVelocity;
        }
        return(stateParams);
    }
示例#7
0
 private IStateParams SetGravity(IStateParams stateParams)
 {
     if (stateParams.Velocity.y < 0f)
     {
         stateParams.GravityOverride = _gravity / 4f;
     }
     else
     {
         stateParams.GravityOverride = _gravity / 1.5f;
     }
     return(stateParams);
 }
示例#8
0
    private void TiltCamera(IStateParams stateParams)
    {
        var lerpSpeed = Time.deltaTime * 4f;

        // This value will be retrieved by the PlayerLook script via PlayerLookVars
        if (_wallRunningRight)
        {
            stateParams.WallRunZRotation = Mathf.Lerp(_playerCamera.localRotation.z, _wallRunCameraTilt, lerpSpeed);
        }
        else if (_wallRunningLeft)
        {
            stateParams.WallRunZRotation = Mathf.Lerp(_playerCamera.localRotation.z, -_wallRunCameraTilt, lerpSpeed);
        }
    }
    private void DoWallRunCheck(IStateParams stateParams, Vector3 velocity, bool isGrounded)
    {
        float rayDistance = 1f;

        if (!isGrounded)
        {
            var lastHitInfo = stateParams.WallRunHitInfo;
            // Check initialization of wall-running rules.
            // Right now this just mean checking if our velocity vector touches any walls.
            if (!_isWallRunning)
            {
                RaycastHit velocityHitInfo;
                RaycastHit inputHitInfo;
                Vector3    vDir = new Vector3(velocity.x, 0, velocity.z);
                Vector3    iDir = CreateInputVector();
                Physics.Raycast(transform.position, vDir, out velocityHitInfo, rayDistance);
                Physics.Raycast(transform.position, iDir, out inputHitInfo, rayDistance);
                Debug.DrawRay(transform.position, Vector3.ClampMagnitude(vDir, rayDistance), Color.yellow);
                Debug.DrawRay(transform.position, Vector3.ClampMagnitude(iDir, rayDistance), Color.black);
                if (velocityHitInfo.collider != null || inputHitInfo.collider != null)
                {
                    _isWallRunning             = true;
                    stateParams.WallRunHitInfo = velocityHitInfo.collider != null ? velocityHitInfo : inputHitInfo;
                    return;
                }
            }
            // Check continuous wall-running rules.
            // Raycast along the last hit info's normal, in the reverse direction, to see if we're still on a wall.
            else if (lastHitInfo.collider != null)
            {
                RaycastHit wallNormalHitInfo;
                Vector3    rayDir = new Vector3(-lastHitInfo.normal.x, 0, -lastHitInfo.normal.z);
                Physics.Raycast(transform.position, rayDir, out wallNormalHitInfo, rayDistance);
                if (wallNormalHitInfo.collider != null)
                {
                    stateParams.WallRunHitInfo = wallNormalHitInfo;
                    return;
                }
            }
        }
        // If we reached this point we shouldn't be wall-running
        _isWallRunning = false;
        // This is here to make sure we're not creating new RaycastHits every frame
        if (stateParams.WallRunHitInfo.collider != null)
        {
            stateParams.WallRunHitInfo = new RaycastHit();
        }
    }
示例#10
0
    public IStateParams SetState(IState state, IStateParams stateParams)
    {
        if (_currentState == state)
        {
            return(stateParams);
        }
        var fromState = _currentState;
        var toState   = state;

        stateParams = _currentState != null?_currentState.OnExit(stateParams) : stateParams;

        Debug.Log($"Changed from {_currentState} to {state}");
        _currentState = state;
        stateParams   = _currentState != null?_currentState.OnEnter(stateParams) : stateParams;

        OnStateChanged?.Invoke(fromState, toState);

        return(stateParams);
    }
示例#11
0
    public IStateParams Tick(IStateParams stateParams)
    {
        var stateParamsVelocity = stateParams.Velocity;
        var wallRunHitInfo      = stateParams.WallRunHitInfo;

        var  forwardSpeed = PlayerInput.Instance.Vertical;
        bool wallJumped   = PlayerInput.Instance.SpaceDown;

        if (wallJumped)
        {
            stateParams.WallJumped = true;
        }
        else
        {
            // Find the direction parallel to the wall using the wallRunHitInfo.normal
            SetWallRunSide();
            // Tilt the camera in the opposite direction of the wall-run
            TiltCamera(stateParams);
            // Wall running right
            if (_wallRunningRight)
            {
                _wallRunMoveAxis = Vector3.Cross(Vector3.up, wallRunHitInfo.normal);
            }
            // Wall running left
            else
            {
                _wallRunMoveAxis = Vector3.Cross(wallRunHitInfo.normal, Vector3.up);
            }
            // Apply our movement along the wall run axis we found above
            var moveAxis = _wallRunMoveAxis;
            moveAxis  = (moveAxis * forwardSpeed);
            moveAxis *= _wallRunSpeed;
            moveAxis  = Vector3.ClampMagnitude(moveAxis, _wallRunSpeed);
            // Update our stateParams velocity
            stateParamsVelocity.x = moveAxis.x;
            stateParamsVelocity.z = moveAxis.z;
            stateParams.Velocity  = stateParamsVelocity;
        }

        return(SetGravity(stateParams));
    }
示例#12
0
    public IStateParams Tick(IStateParams stateParams)
    {
        var velocity = stateParams.Velocity;

        // Lower into a crouch if we aren't lowered already
        if (_lowering)
        {
            Crouch();
        }
        // Apply drag to our velocity
        velocity.x *= 1 - Time.deltaTime;
        velocity.z *= 1 - Time.deltaTime;
        // Transition to Crouched state when velocity is under a threshold
        var horizontalVelocity = new Vector3(velocity.x, 0, velocity.z);

        if (horizontalVelocity.magnitude < CrouchThreshold)
        {
            IsSliding = false;
        }
        stateParams.Velocity = velocity;
        return(stateParams);
    }
示例#13
0
    public IStateParams Tick(IStateParams stateParams)
    {
        var stateParamsVelocity = stateParams.Velocity;

        // Gather our vertical and horizontal input
        float forwardSpeed = PlayerInput.Instance.Vertical;
        float sideSpeed    = PlayerInput.Instance.Horizontal;

        // Apply these values to our player
        var tempVelocity = (_player.transform.forward * forwardSpeed) + (_player.transform.right * sideSpeed);

        tempVelocity *= _walkingSpeed;

        // Make sure we're never moving faster than our walking speed
        tempVelocity = Vector3.ClampMagnitude(tempVelocity, _walkingSpeed);

        // Update our stateParams velocity
        stateParamsVelocity.x = tempVelocity.x;
        stateParamsVelocity.z = tempVelocity.z;
        stateParams.Velocity  = stateParamsVelocity;

        return(stateParams);
    }
示例#14
0
 internal InsertOperandState(IStateParams stateParams, IStateFactory stateFactory) : base(stateParams, stateFactory)
 {
 }
示例#15
0
 public IStateParams Tick(IStateParams stateParams)
 {
     HandleInput();
     CrouchOrStand();
     return(HandleMovement(stateParams));
 }
示例#16
0
 public IStateParams OnExit(IStateParams stateParams)
 {
     _toSprint = false;
     return(stateParams);
 }
示例#17
0
 public IStateParams OnEnter(IStateParams stateParams)
 {
     _lowering   = true;
     _firstFrame = true;
     return(stateParams);
 }
示例#18
0
 internal State(IStateParams stateParams, IStateFactory stateFactory)
 {
     this.stateParams  = stateParams;
     this.stateFactory = stateFactory;
 }
示例#19
0
 public IStateParams OnExit(IStateParams stateParams)
 {
     _doubleJumpAvailable = true;
     ToSlide = false;
     return(stateParams);
 }
    private void Awake()
    {
        Player player = FindObjectOfType <Player>();

        _characterController = GetComponent <CharacterController>();
        _stateHelper         = new PlayerMovementStateMachineHelper();
        _stateMachine        = new BaseStateMachine();
        _playerLookVars      = new PlayerLookVars();

        // Hook into the BaseStateMachine OnStateChanged event
        _stateMachine.OnStateChanged += HandleStateChanged;

        // Prepare our StateParams for passing to all of our states
        _stateParams                 = new StateParams();
        _stateParams.Velocity        = _velocity;
        _stateParams.GravityOverride = defaultGravity;

        // Create our states
        Idle        idle        = new Idle(player);
        Walking     walking     = new Walking(player);
        Sprinting   sprinting   = new Sprinting(player);
        Jumping     jumping     = new Jumping(player);
        WallRunning wallRunning = new WallRunning(player, defaultGravity);
        Crouching   crouching   = new Crouching(player);
        Sliding     sliding     = new Sliding(player);

        // Create our state transitions
        // Any -> Idle
        _stateMachine.AddAnyTransition(idle, () => _stateHelper.ToIdle(idle, jumping, crouching, sliding));
        // Any -> Jumping
        _stateMachine.AddAnyTransition(jumping, () => _stateHelper.ToJump(jumping, _isWallRunning, _stateParams.WallJumped));

        // Idle -> Walking
        _stateMachine.AddTransition(idle, walking, () => walking.IsWalking());
        // Walking -> Sprinting
        _stateMachine.AddTransition(walking, sprinting, () => PlayerInput.Instance.ShiftDown);
        // Sprinting -> Walking
        _stateMachine.AddTransition(sprinting, walking, () => !sprinting.IsStillSprinting());

        // Idle -> Crouching
        _stateMachine.AddTransition(idle, crouching, () => PlayerInput.Instance.CrouchDown);
        // Walking -> Crouching
        _stateMachine.AddTransition(walking, crouching, () => PlayerInput.Instance.CrouchDown);
        // Crouching -> Walking
        _stateMachine.AddTransition(crouching, walking, () => _stateHelper.CrouchToWalk(crouching, walking));
        // Crouching -> Sprinting
        _stateMachine.AddTransition(crouching, sprinting, () => _stateHelper.CrouchToSprint(crouching));
        // Sprinting -> Sliding (Crouching)
        _stateMachine.AddTransition(sprinting, sliding, () => PlayerInput.Instance.CrouchDown);

        // Jumping -> Sliding
        _stateMachine.AddTransition(jumping, sliding, () => _stateHelper.JumpToSlide(jumping));
        // Jumping -> Sprinting
        _stateMachine.AddTransition(jumping, sprinting, () => _stateHelper.JumpToSprint(jumping, _preserveSprint));
        // Jumping -> Walking
        _stateMachine.AddTransition(jumping, walking, () => _stateHelper.JumpToWalk(jumping, walking, _preserveSprint));
        // Jumping -> Wall Running
        _stateMachine.AddTransition(jumping, wallRunning, () => _isWallRunning);

        // Wall Running -> Sprinting
        _stateMachine.AddTransition(wallRunning, jumping, () => _stateHelper.WallRunToSprint(jumping, _isWallRunning, _preserveSprint));
        // Wall Running -> Walking
        _stateMachine.AddTransition(wallRunning, jumping, () => _stateHelper.WallRunToWalk(jumping, walking, _isWallRunning));

        // Default to Idle
        _stateParams = _stateMachine.SetState(idle, _stateParams);
    }
 internal WaitForSecondOperandState(IStateParams stateParams, IStateFactory stateFactory) : base(stateParams, stateFactory)
 {
 }
示例#22
0
 public IState GetInsertOperandState(IStateParams param) => new InsertOperandState(param, this);
示例#23
0
 public IState GetShowResultState(IStateParams param) => new ShowResultState(param, this);
示例#24
0
 public IStateParams OnEnter(IStateParams stateParams)
 {
     return(stateParams);
 }
示例#25
0
 public IStateParams OnEnter(IStateParams stateParams)
 {
     IsSliding = true;
     _lowering = true;
     return(stateParams);
 }
示例#26
0
 public IStateParams OnExit(IStateParams stateParams)
 {
     return(stateParams);
 }
示例#27
0
 public IStateParams OnExit(IStateParams stateParams)
 {
     IsSliding = false;
     _lowering = false;
     return(stateParams);
 }
示例#28
0
 internal ShowResultState(IStateParams stateParams, IStateFactory stateFactory) : base(stateParams, stateFactory)
 {
 }
示例#29
0
 public IState GetWaitForSecondOperandState(IStateParams param) => new WaitForSecondOperandState(param, this);