How to properly delegate to another scripts function?

Hello good people!
I know I can’t use the proper trems in my title for what I’m trying to figure out. It’s why it’s been a nightmare trying to find help through google. So I’m asking here if I can get an explanation.

I’ve got two scripts. A player movement script and an ability script. (Trying to make a dash ability)
I’m following a tutorial, kind of… It’s using rigidbodies while I’m not, so I have to try to translate it through different code.

In the player script I’ve got this:

    public void Movement(Vector3 velocity)
    { 
        cc.Move(velocity * Time.deltaTime);
    }

This approach was kind of new to me. Before, I would have just done a public void Movement, with nothing in the brackets, and then referenced inside the function. But since I can… I think it’s called delegate in programming lingo… It seems to be a bit smarter… But I don’t fully understand it…

Now this is the second script:

    public Update()
    {
        if(setVelocity)
        {
            player.Movement(vector.forward * velocityToSet);
        }
    }

Here is the thing… Yes, it’s not working. And I know it’s because I’ve done something wrong, and haven’t figured it out yet. But to be honest, I got stuck even before that.
The velocity vector I’m giving the movement function is just my input*player speed.
Here is where I’m stuck.
In the second script, I want the player to dash forward (towards where he’s aiming) by a set amount. (velocityToSet is a float supposed to state that amount)

But I don’t know how to delegate into the movement function while still retaining the velocity vector that’s already being put into it?. (I’m imagining some kind of player.Movement(player.velocity * velocity, but htat didn’t work either. The player literally just disappears and the game turns unresponsive…)

Also, the tutorial I’m following uses rigidbody and 2d, while I’m trying to implement stuff without a rigidbody in 3d… And so many tutorials out there insists on using rb.velocity for movement… And I just can’t wrap my head around translating that into an ordinary charactercontroller. XD

You can add the two vectors together. Or you can also just call player.Movement twice with two different velocity vectors for the same effect. If you take the latter approach then the dash ability could be it’s own modular component that doesn’t even need to know anything about the other movement providers.

public class Dash : MonoBehaviour
{
    [SerializeField]
    private KeyCode dashKey = KeyCode.Space;
    [SerializeField]
    private float dashDuration = 1f;
    [SerializeField]
    private float dashSpeed = 3f;
    [SerializeField]
    private Player player = null;

    private bool isDashing;
    private float dashTimeRemaining;

    private void Update()
    {
        if(Input.GetKeyDown(dashKey))
        {
            StartDashing();
        }

        if(isDashing)
        {
            UpdateDash();
        }
    }

    private void StartDashing()
    {
        isDashing = true;
        dashTimeRemaining = dashDuration;
    }

    private void StopDashing()
    {
        isDashing = false;
        dashTimeRemaining = 0f;
    }

    private void UpdateDash()
    {
        float time = Time.deltaTime;
        dashTimeRemaining -= time;

        if(dashTimeRemaining < 0f)
        {
            StopDashing();
            return;
        }

        Vector3 direction = Vector3.up;
        Vector3 velocity = direction * dashSpeed;
        player.Move(velocity);
    }
}
2 Likes

A little bit on the vocabulary:

public void Movement(Vector3 velocity)

velocity is a parameter of the Movement method.
When you call the Movement method you pass a velocity to is as an argument.
So a parameter is a variable in a method definition and an argument is a value given to such a variable.

Making use of parameters can be useful in some cases. It can lead to more reusable methods, and it can also be used to minimize the amount of state that objects have, which can help make things easier to manage and help reduce the number of bugs. It can also help make classes testable.

However using parameters is not inherently any better than not using them, it’s just another tool in the toolbox :slight_smile:
Just try to make your code as easy to understand and use as you can, I think that’s much more important (especially in the beginning) than trying to make your code super reusable.

2 Likes

Thanks a whole bunch! I managed to figure it out thanks to your input!
And thanks for the help with the vocabulary. It’s actually one of the harder things to wrap my head around when trying to go from tutorials to the reference documents. This helps a lot! :slight_smile:

I managed to get the dash working!
I mean, I didn’t show the whole code, cause there is a lot of different things happening beneath the hood here. But you managed to help me deal with the part that wasn’t working as intended!
If I were to compare to your code, my equivalent of startDash and stopDash functions are actually called inside animation events! So I didn’t care about the timer in the code at all. :slight_smile:

    public Update()
    {
        if(setVelocity)
        {
            //this moves the character forward by the direction.
            player.Movement(animDirection * velocityToSet);
        }
    public void SetPlayerVelocity(float velocity)
    {
        //this is called in animation event triggers, setting velocity to a referenced float or zero.
       //this is what I was missing. A reference to the current player direction.
        animDirection = player.transform.forward;
       
        //this stops the dash, since at the end of the animation this velocity is set to 0.
         player.Movement(animDirection * velocity);

        velocityToSet = velocity;
        //this bool is set to false elsewhere in the script.
        setVelocity = true;
    }

Well done, great to hear you got everything working! :slight_smile: