← Back to all addons

Cast Time Abilities

Posted by SvanDark on Sep 18, 2025 at 2:00 PM

Gameplay
πŸ‘πŸ» 5 πŸ”₯ 1

Here’s how you can import Cast Times to your Abilities, it’s super simple too!

Note that this does not come with a cast time bar, only the actual system itself

First of all, start by adding those lines in the ActiveAbilitySheet script

[Header("Cast Settings")]
[SerializeField, Min(0f)] private float m_castTime = 0f;            // seconds, 0 = instant
[SerializeField] private bool m_interruptOnDamage = true;            // cancel when damaged
[SerializeField] private bool m_lockMovementWhileCasting = true;     // disable Move/Interact/UseAbility during cast

public float castTime => m_castTime;
public bool interruptOnDamage => m_interruptOnDamage;
public bool lockMovementWhileCasting => m_lockMovementWhileCasting;

After that, just replace your ProjectileAbility script with the one i attached

And you’re done! Now just set the amount of cast time you want an ability to take to cast on the ability prefab(s)!

πŸ“œ Scripts

πŸ’¬ Comments (26)

Mr.Titan Sep 18, 2025 at 08:38 PM
Aaah nice! It would be even cooler if it could repeat the casting animation until the trigger. That would be top!
Mr.Titan Sep 18, 2025 at 08:39 PM
If you changed from “afterAnimationEnd” to that timer, it would be tutally doable
SvanDark Sep 18, 2025 at 09:03 PM

Yeah i was thinking of doing that actually, i can look into it right now!

but now that you here i do have a request, would you be able to make a cast time bar addon? 😜

not a must of course but im just shooting my shot lol

Mr.Titan Sep 19, 2025 at 07:59 AM
Ahahaha yes sure why not. Where would this bar be?
SvanDark Sep 19, 2025 at 08:00 AM
i was thinking of it being above the abilities, so maybe somewhere here ish?
πŸ‘ 1
SvanDark Sep 20, 2025 at 07:54 PM
following up on this (if you’re still doing it), it would also be nice if you could see the enmies casting abilities with a cast timer bar (maybe above their HP?)
Mr.Titan Sep 20, 2025 at 08:50 PM
I tried to do something yesterday, but your shared the entire script, i can’t compromisse my current development. Sould you split things up instead of just sharing the entire thing?
SvanDark Sep 20, 2025 at 08:54 PM
ah, yeah sure let me get the lines that i added then, 1 sec
SvanDark Sep 20, 2025 at 08:59 PM

okay first of all, add using System.Collections; at the top of the script

then, under your existing fields (after m_projectiles list), add:

private bool m_castInterrupted;
private string m_castLockKey;

After that, replace your current protected override void Fire() with:

protected override void Fire() // REPLACE
{
    // Instead of immediately firing, do an optional cast first.
    StartCoroutine(CastThen(() =>
    {
        // What used to happen directly in Fire()
        m_animator?.SetTrigger(m_fireAnimationParameter);
    }));
}

Then after that, add this whole method below Fire();

SvanDark Sep 20, 2025 at 08:59 PM
private IEnumerator CastThen(Action onCastComplete) // ADD
{
    float cast = activeAbilitySheet.castTime;

    // No cast time? Just go.
    if (cast <= 0f)
    {
        onCastComplete?.Invoke();
        yield break;
    }

    // Optionally lock actions while casting
    if (activeAbilitySheet.lockMovementWhileCasting)
    {
        // Reuse the sheet's Disabled Actions mask
        m_castLockKey = m_character.LockActions(activeAbilitySheet.disabledActionsWhileCasting);
    }

    // Optionally interrupt on damage
    m_castInterrupted = false;
    void OnDamage(CharacterBase target, DamageInputDescriptor _, EEffectVisualFlags __)
    {
        if (target == m_character) m_castInterrupted = true;
    }
    if (activeAbilitySheet.interruptOnDamage)
        GameManager.NotificationSystem.damageApplied.AddListener(OnDamage);

    // Wait out the cast
    while (cast > 0f)
    {
        if (activeAbilitySheet.interruptOnDamage && m_castInterrupted) break;
        cast -= Time.deltaTime;
        yield return null;
    }

    // Cleanup
    if (activeAbilitySheet.interruptOnDamage)
        GameManager.NotificationSystem.damageApplied.RemoveListener(OnDamage);

    if (!string.IsNullOrEmpty(m_castLockKey))
    {
        m_character.UnlockActions(m_castLockKey);
        m_castLockKey = null;
    }

    // If not interrupted, continue with the ability logic
    if (!(activeAbilitySheet.interruptOnDamage && m_castInterrupted))
    {
        onCastComplete?.Invoke();
    }
    else
    {
        // Cast was cancelled – stop here
        TerminateCasting();
    }
}
SvanDark Sep 20, 2025 at 09:01 PM
this is all for the ProjectileAbility script ^
Mr.Titan Sep 21, 2025 at 04:31 PM

@SvanDark see if it suits you You can put it anywhere (in my case i just put it in the ability prefab) and call (uiCountdownBar.show(<nΒΊ_seconds>)). IΒ΄ve also provided a way to say if you want to fill or reduce(default), just use a second parameter (uiCountdownBar.show(<nΒΊ_seconds>, <boolean => fill> )).

(note in my case only appears in the combo, i.e. in the tree shot ability… and i also added some camera shake for niceness!)

SvanDark Sep 21, 2025 at 04:33 PM
Interesting, yeah i’d say something like that works! And yeah the camera shake looks very nice!
Mr.Titan Sep 21, 2025 at 04:35 PM
since it’s a reusable prefab, you can put in the the user, the ability, the abilities bar… but call somewhere the method and pass the nΒΊ of seconds.
SvanDark Sep 21, 2025 at 04:38 PM

One thing that would make it even better is making it wow style ish and putting the name of the ability in the actual bar, but that would also mean that you have to make the bar bigger lol

Obviously this is not a must since it might be a bit too much for users, but once again this is amazing!

SvanDark Sep 21, 2025 at 04:39 PM
It would probably be better to make another thread in <#1237781019940098108> to set this up, or?
Mr.Titan Sep 21, 2025 at 04:40 PM
Ah i see what you are looking for… now i undestand why you wanted that position in the print. I have to advite at first i tough it was weard πŸ˜… now i get it
SvanDark Sep 21, 2025 at 04:41 PM
Haha yeah, like wow style ish
SvanDark Sep 21, 2025 at 04:41 PM
I probably shouldve mentioned that, my bad
Mr.Titan Sep 21, 2025 at 04:42 PM
that’s fairlly easy to do, just add a text inside (in fact initially had a text fecause i copied the gameobject from the monster prefab), add a text and add a “text” property. Regarding the position, you put it associated with the user, and in the CharacterBase in the (fire) method you call this.
SvanDark Sep 21, 2025 at 04:43 PM
Gotcha, thanks!!
Mr.Titan Sep 21, 2025 at 05:00 PM
@SvanDark this?
SvanDark Sep 21, 2025 at 05:01 PM
yeah, that looks very good in my opinion!
Mr.Titan Sep 21, 2025 at 05:21 PM
Mr.Titan Sep 21, 2025 at 05:29 PM
Addicionally i advice to put the method CastThen in the ActivityAbility.cs as well as the 2 private properties but make it all protected, since the ActiveAbilitySheet it’s used by all abilities, otherwise you’ll see this feature for all abilities but just can use in projectile.
🫑 1
JP Sep 27, 2025 at 07:40 PM
Works Great! πŸ‘

Want to continue the conversation?