Home > OS >  How to make a dash ability with rigidbodies?
How to make a dash ability with rigidbodies?

Time:05-17

I'm currently trying to make a dash ability using .AddForce(), however, it seems to not feel like a proper dash something about it just doesn't feel right, but I'm not sure of an alternative way to code it.

public class AbilityBase : ScriptableObject
{
    public new string name;
    public float cooldownTime;
    public float activeTime;

    public enum AbilityState
    {
        ready,
        active,
        cooldown
    }
    public AbilityState state = AbilityState.ready;

    public virtual void Activate(GameObject parent)
    {
        
    }
}

[CreateAssetMenu(fileName = "GuardRush", menuName = "Abilities/WarriorClass/Guard Rush")]
public class GuardRush : AbilityBase
{
    public float dashSpeed = 5f;

    public override void Activate(GameObject parent)
    {
        Rigidbody playerRigidbody = parent.GetComponent<Rigidbody>();

        playerRigidbody.AddForce(parent.transform.forward * dashSpeed, ForceMode.Impulse);        
    }
}

CodePudding user response:

You do not have to give an initial force for this because it acts like hitting the ball. You have to give a constant force to the caster for a very short time and then stop the force. Use the IEnumerator for this purpose:

public class Dash : AbilityBase
{
    public bool isDashed; // This Boolean prevents the dash from repeating during execution.
    public float power = 50f; // for e.g

    public IEnumerator Run(Rigidbody body)
    {
        isDashed = true;
        body.velocity = body.transform.forward * power;

        yield return new WaitForSeconds(.15f);

        body.velocity = Vector3.zero;

        isDashed = false;
    }
}

After that, just excute dash IEnumerator (Run) from the player code. I deposited the scriptable object from Start() here, but you can also put it in the inspector:

public class Player: MonoBehaviour
{
    public Dash _ability;
    private Rigidbody rb;

    public void Start()
    {
        rb = GetComponent<Rigidbody>();
        _ability = ScriptableObject.CreateInstance<Dash>();
        _ability.name = "Dash";
    }
    public void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space) && !_ability.isDashed)
        {
            StartCoroutine(_ability.Run(rb));
        }
    }
}

This is a simple and dry example of a dash, if you want it to be smoother and better I suggest you use Do Tween Pro, this is a great plugin for making smooth movements and Tweeners with returning callback's.

CodePudding user response:

As previously mentioned, you need to give a bit more detail as to why you don't like your current implementation. It looks like your adding a set amount of force to the rigid body in one go which I'm guessing is just jumping forward then stopping.

One way of changing this would be applying more force over a period of time after activation instead of lots of force instantly to give the feel of acceleration, something similar can be done in reverse to give the feel of slowing down. Camera effects and such can also change the "feel" of a action done by a player without changing how the dash action itself works mechanically.

It's worth determining what your looking for in your dash such as "Can they only run in a straight line?", "Do they need time to accelerate or do they hit max speed straight away" or "Can they perform other actions or not while dashing?". Once you know what your looking for, it becomes easier both for you to figure out how to implement it and for people to help you with your implementation.

  • Related