Can Parameters be passed through to C# Actions?

I took “ApplyJumpForce()” out of “OnJump” because I wasn’t sure how to pass through a parameter to the “OnJump” action. I wanted to set different jump strengths for the first and second jumps. I figure it’s okay to in this situation because ApplyJumpForce() is in the same script as HandleJump(), but otherwise it would be good to know how to pass through parameters to Actions. :thinking:

I apologise that my code is a little bit different from the course, but I’ve tested it, and it seems to be working.

    private void Update()
    {
        GatherInput();
        Movement();
        CoyoteTime();
        HandleJump();
        HandleSpriteFlip();
    }


    private void FixedUpdate()
    {
        HandleGravity();
        Land();
    }
    private void CoyoteTime()
    {
        if (CheckGrounded()) _coyoteTimer = _coyoteTime;
        else _coyoteTimer -= Time.deltaTime;
    }
    private bool CheckGrounded()
    {
        Collider2D isGrounded = Physics2D.OverlapBox(_feetTransform.position,_groundCheck,0f,_groundLayer);
        return isGrounded;
    }
    private void HandleJump()
    {
        if (_doubleJumpAvailable && _frameInput.Jump)
        {
            _doubleJumpAvailable = false;
            ApplyJumpForce(_doubleJumpStrength);
            OnJump.Invoke();
            return;
        }
        if (!_isJumping && _coyoteTimer>=0 && _frameInput.Jump) {
            _doubleJumpAvailable = true;
            _isJumping = true;
            ApplyJumpForce(_jumpStrength);
            OnJump.Invoke();
            return;
        }
        if (!_isJumping && _coyoteTimer < 0)
        {
            _doubleJumpAvailable = true;
            _isJumping = true;
            return;
        }
    }
    private void ApplyJumpForce(float jumpStrength)
    {
        if(_rb.velocity.y<0) _rb.velocity = new Vector2(_rb.velocity.x, 0f);
        _rb.AddForce(Vector2.up * jumpStrength, ForceMode2D.Impulse);
        _rb.gravityScale = _risingGravityScale;
    }
    private void HandleGravity()
    {
        if (!_isJumping) _rb.gravityScale = _normalGravityScale;

        else if (_rb.velocity.y > _hangVelovityThreshold && _frameInput.Rise)
            _rb.gravityScale = _risingGravityScale;

        else if (_rb.velocity.y > -_hangVelovityThreshold && _frameInput.Rise)
            _rb.gravityScale = _hangGravityScale;

        else _rb.gravityScale = _normalGravityScale;
    }
    private void Land()
    {
        if (_isJumping && _rb.velocity.y < 0.01 && CheckGrounded()) {
            _rb.gravityScale = _normalGravityScale;
            _isJumping = false;
            _doubleJumpAvailable = false;
        }
    }

I don’t have a “_timeInAir” variable, but instead I set the player’s gravity based on their velocity. I wanted to give the jump a unique mechanic and feel, so it’s very snappy before and after the peak and very floaty during the peak. The player can choose to accumulate their momentum to jump higher by double jumping in quick succession, or space the jumps out to float for more time and travel further.

You need to define the Action with the parameters you want to pass through so, let’s assume we want to pass different jump strengths and they are floats you will define it like this

Action<float> OnJump;

Now, when you call it you can do it in one of two ways

OnJump(12f);
// or
OnJump.Invoke(12f);

You can also have multiple

Action<float, float> OnJump;
...
OnJump.Invoke(12f, 1f);

Note that Microsoft only defined action delegates up to a certain number of parameters (I think 6), but usually they are enough. If they’re not you could rather pass a custom struct holding the values, or define more Action delegates

You can also get results back by using Func instead of Action. A Func must always define a parameter (it’s the output type) and the last parameter in the delegate is always the output type

Func<int> GetANumber; // will return an int
int number = GetANumber.Invoke();

Func<float, float, int> AddAsInt; // will take two floats and return an int
int answer = AddAsInt.Invoke(12.8f, 13.5f);
1 Like

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms