Search Unity

Resolved How to properly delegate to another scripts function?

Discussion in 'Scripting' started by Snakebearer, Jun 7, 2022.

  1. Snakebearer

    Snakebearer

    Joined:
    Feb 9, 2013
    Posts:
    26
    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:

    Code (csharp):
    1.  
    2.     public void Movement(Vector3 velocity)
    3.     {
    4.         cc.Move(velocity * Time.deltaTime);
    5.     }
    6.  
    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:

    Code (csharp):
    1.  
    2.     public Update()
    3.     {
    4.         if(setVelocity)
    5.         {
    6.             player.Movement(vector.forward * velocityToSet);
    7.         }
    8.     }
    9.  
    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
     
  2. SisusCo

    SisusCo

    Joined:
    Jan 29, 2019
    Posts:
    1,331
    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.

    Code (CSharp):
    1. public class Dash : MonoBehaviour
    2. {
    3.     [SerializeField]
    4.     private KeyCode dashKey = KeyCode.Space;
    5.     [SerializeField]
    6.     private float dashDuration = 1f;
    7.     [SerializeField]
    8.     private float dashSpeed = 3f;
    9.     [SerializeField]
    10.     private Player player = null;
    11.  
    12.     private bool isDashing;
    13.     private float dashTimeRemaining;
    14.  
    15.     private void Update()
    16.     {
    17.         if(Input.GetKeyDown(dashKey))
    18.         {
    19.             StartDashing();
    20.         }
    21.  
    22.         if(isDashing)
    23.         {
    24.             UpdateDash();
    25.         }
    26.     }
    27.  
    28.     private void StartDashing()
    29.     {
    30.         isDashing = true;
    31.         dashTimeRemaining = dashDuration;
    32.     }
    33.  
    34.     private void StopDashing()
    35.     {
    36.         isDashing = false;
    37.         dashTimeRemaining = 0f;
    38.     }
    39.  
    40.     private void UpdateDash()
    41.     {
    42.         float time = Time.deltaTime;
    43.         dashTimeRemaining -= time;
    44.  
    45.         if(dashTimeRemaining < 0f)
    46.         {
    47.             StopDashing();
    48.             return;
    49.         }
    50.  
    51.         Vector3 direction = Vector3.up;
    52.         Vector3 velocity = direction * dashSpeed;
    53.         player.Move(velocity);
    54.     }
    55. }
     
    Snakebearer and Bunny83 like this.
  3. SisusCo

    SisusCo

    Joined:
    Jan 29, 2019
    Posts:
    1,331
    A little bit on the vocabulary:

    Code (CSharp):
    1. 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 :)
    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.
     
    Snakebearer and Bunny83 like this.
  4. Snakebearer

    Snakebearer

    Joined:
    Feb 9, 2013
    Posts:
    26
    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! :)

    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. :)

    Code (csharp):
    1.  
    2.  
    3.     public Update()
    4.     {
    5.         if(setVelocity)
    6.         {
    7.             //this moves the character forward by the direction.
    8.             player.Movement(animDirection * velocityToSet);
    9.         }
    10.  
    11.  
    Code (csharp):
    1.  
    2.     public void SetPlayerVelocity(float velocity)
    3.     {
    4.         //this is called in animation event triggers, setting velocity to a referenced float or zero.
    5.        //this is what I was missing. A reference to the current player direction.
    6.         animDirection = player.transform.forward;
    7.        
    8.         //this stops the dash, since at the end of the animation this velocity is set to 0.
    9.          player.Movement(animDirection * velocity);
    10.  
    11.         velocityToSet = velocity;
    12.         //this bool is set to false elsewhere in the script.
    13.         setVelocity = true;
    14.     }
    15.  
     
  5. SisusCo

    SisusCo

    Joined:
    Jan 29, 2019
    Posts:
    1,331
    Well done, great to hear you got everything working! :)