Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Dashing Like Megaman X Series

Discussion in 'Scripting' started by unity_4six12, Aug 31, 2019.

  1. unity_4six12

    unity_4six12

    Joined:
    Aug 20, 2019
    Posts:
    8
    Hello guys!

    I've been learning Unity and C# for about 2 weeks now, currently I'm laying the basic groundwork for the player movement. I'm trying to implement a dash feature which is somewhat similar to the Megaman series. With the codes I have right now, I can dash normally on the ground, but whenever I dash on air, my character gravity is doing it's job pulling down the character while dashing.

    I tried to set the Rigidbody's gravity scale to 0 but I don't know how to reset it back to it's original value. Can anyone help me? Also, please be kind to proofread my codes if it's actually messy.

    PS: I tried resetting the gravity scale within the ResetAttack() to it's original value which is 6, but the problem is that, my jump power has weakened as if gravity has doubled.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class PlayerMovement : MonoBehaviour
    6. {
    7.     [SerializeField] CharacterController2D controller;
    8.     public Animator animator;
    9.  
    10.     [SerializeField] private float dashDistance;
    11.  
    12.     [SerializeField] private float runSpeed = 30f;
    13.     private float horizontalMove = 0f;
    14.  
    15.     private bool jump = false;
    16.     private bool isAttacking = false;
    17.  
    18.     private Rigidbody2D rb2d;
    19.  
    20.     private void Start()
    21.     {
    22.         rb2d = GetComponent<Rigidbody2D>();
    23.     }
    24.  
    25.  
    26.     // Update is called once per frame
    27.     void Update()
    28.     {
    29.         #region Basic Movement
    30.  
    31.         if (!this.animator.GetCurrentAnimatorStateInfo(0).IsName("Attack1"))
    32.         {
    33.             horizontalMove = Input.GetAxisRaw("Horizontal") * runSpeed;
    34.         }
    35.  
    36.        
    37.         animator.SetFloat("Speed", Mathf.Abs(horizontalMove));
    38.  
    39.         if (Input.GetButtonDown("Jump"))
    40.         {
    41.             jump = true;
    42.             animator.SetBool("Jumping", true);
    43.         }
    44.  
    45.         if (Input.GetButtonDown("Fire1") && !isAttacking)
    46.         {
    47.             isAttacking = true;
    48.             animator.Play("Attack1");
    49.             horizontalMove = 0f;
    50.             Invoke("ResetAttack", .5f);
    51.         }
    52.  
    53.         if (Input.GetButtonDown("Dash"))
    54.         {
    55.             Dash();
    56.         }
    57.  
    58.         #endregion
    59.  
    60.     }
    61.  
    62.     void ResetAttack()
    63.     {
    64.         isAttacking = false;
    65.         rb2d.gravityScale = 0f;
    66.     }
    67.  
    68.     public void OnLanding()
    69.     {
    70.         animator.SetBool("Jumping", false);
    71.         jump = false;
    72.     }
    73.  
    74.     void FixedUpdate()
    75.     {
    76.         controller.Move(horizontalMove * Time.deltaTime, false, jump);
    77.     }
    78.  
    79.     void Dash()
    80.     {
    81.         rb2d.velocity = Vector2.zero;
    82.         rb2d.gravityScale = 0f;
    83.         rb2d.velocity += new Vector2(horizontalMove, 0).normalized * dashDistance;
    84.         Invoke("ResetAttack", .3f);
    85.     }
    86. }
     
  2. Yoreki

    Yoreki

    Joined:
    Apr 10, 2019
    Posts:
    2,605
    Hi and welcome!
    You are not supposed to use CharacterController together with Rigidbodies. May lead to unintended behavior and at some point even become imperformant. Rigidbodies are used when you want physically accurate behaviour, which makes it easy to make things bounce, or fly off in a realistic way, but is hard to control.
    CharacterController gives you perfect control, but you'll have to introduce a bit of fluidity yourself, if wanted.
    That said, i believe you want to use a CharacterController for this type of movement. That way you have to apply your own "gravity" (your downwards force), which should also make it easier to control, or turn off, in certain situations like your dash.

    Code quality:
    What i can see from this small script looks really good for a beginner. You are using the right naming conventions, which is always a huge plus in my books. As a rule of thumb, FixedUpdate() should only be used for physics related code (Rigidbodies) tho, with very few exceptions. So CharacterController movement would rather fit in the normal Update() loop.

    As a final piece of advice for the future: when your code starts getting a bit more complex than "on this button input do XYZ", you will definitely want to introduce some form of documentation for yourself. Even if it's just some "headline" comments, summing up whatever it is you are doing for the next 5-10 lines of code. Your own code will always seem logical to you while you write it, but coming back to it a couple weeks later, you wont understand a thing. Comments help you find what you are looking for more easily then. Again, it's a piece of advice more directed at future code where you may or may not want to write bigger methods or update loops for some game mechanics.
     
  3. unity_4six12

    unity_4six12

    Joined:
    Aug 20, 2019
    Posts:
    8
    Thanks you so much! This means a lot to me. Makes me more inspired to learn than ever before.

    I learned through YouTube, Google searches, and a few books at the local library. No one really stated the difference Update() and FixedUpdate(), at least from my resources, I kinda just understood it myself. But I admit, most of the time while coding, I either watch or search for a script, but I try to avoid copying it directly, instead I try to understand the general logic behind it and try to write on my own.

    To be honest, I really want to learn to write a basic 2d platformer movement script that works like Castlevania or Megaman in just a single C# script that is flexible enough in case I make a game with new mechanics. I'll just need to study more before I do that.

    PS: I always get errors that says Warning CS0649: Never assigned - null something like that even though the code works. Is that something I should be worried about?
     
  4. EdGunther

    EdGunther

    Joined:
    Jun 25, 2018
    Posts:
    183
    On what line do you get this error message
     
  5. unity_4six12

    unity_4six12

    Joined:
    Aug 20, 2019
    Posts:
    8
    The ground check, ceiling check, crouch disable check, and some other serialized fields.. I'm still using the CharacterController2D posted by a YouTube channel named Brackeys.. Some google forums says just ignore them as long as the code works and that it's just a part of unity/microsoft bug.. All of them are assigned and I can play the game normally but they always show up.. I'm using 2019.2.3f1
     
  6. unity_4six12

    unity_4six12

    Joined:
    Aug 20, 2019
    Posts:
    8
    That worked! But I wonder why it gives warning though..
    Thank you!
     
  7. Yoreki

    Yoreki

    Joined:
    Apr 10, 2019
    Posts:
    2,605
    I have those as well before pressing play, was never looking for an answer since i always assumed they are just a bug that's eventually going to be fixed, since the stuff they warn about is obviously assigned in the inspector. It's quite annoying tho. So if there is a fix i'd be interrested in that as well.
     
  8. Dextozz

    Dextozz

    Joined:
    Apr 8, 2018
    Posts:
    493
    It's there to notify the programmer that the variable will have a value of "null" unless otherwise specified.

    Give some default value to the variables right there in the code. Something like this:

    Code (CSharp):
    1. [SerializeField] private GameObject randomObject = null;
    2. [SerializeField] private float dashDistance = 0f;
    Generally, I add = null to "class" variables (GameObject, Transform, SpriteRenderer etc.) and some starting value to regular variables (0f, 0, Vector3.zero etc.)
     
    Yoreki likes this.
  9. Yoreki

    Yoreki

    Joined:
    Apr 10, 2019
    Posts:
    2,605
    Great to know, thanks!
     
  10. geyluigi223

    geyluigi223

    Joined:
    Dec 14, 2020
    Posts:
    14
    i also so those developers use something different like that in this game called Rockman X DiVE.