Simple/Charged Trigger Module Fails to Fire After Reloading When UseCompleteEvent Duration = 0

airoll

Member
I have my weapon set to a Simple or Charged trigger module and to reload automatically when the clip is empty. Once the clip is empty, the weapon reloads, then I try to fire the weapon, it fails to fire. After debugging, I noticed that this is caused by the fact that

C#:
m_WasTriggered = true

when I try to fire the weapon a 2nd time. After debugging, I noticed that this is because UseItemTrigger() which sets m_WasTriggered = true fires AFTER StopItemUse() which sets m_WasTriggered = false. Upon further debugging, I discovered that this happens when the UseCompleteEvent has a duration of 0. If I set the duration to 0.01 or a non zero value, it works fine.

Here's the call stack of what's causing this. First, StopItemUse causes m_WasTriggered to be false. The ItemUseComplete() call triggers Reload to try to reload the weapon. I have a usable action module called Interrupt that tries to stop any active Use ability when Reload starts. This causes StopItemUse() to be called.

C#:
SimpleBaseTrigger.StopItemUse() at C:\Perforce\-\Assets\Opsive\UltimateCharacterController\Scripts\Items\Actions\Modules\TriggerModule.cs:line 447
UsableAction.<>c.<StopItemUse>b__146_0() at C:\Perforce\-\Assets\Opsive\UltimateCharacterController\Scripts\Items\Actions\UsableAction.cs:line 830
CharacterItemAction.InvokeOnModulesWithType<IModuleStopItemUse>()
UsableAction.StopItemUse()
UsableAction.ItemAbilityStopped()
Use.AbilityStopped()
Ability.StopAbility() [2]
UltimateCharacterLocomotion.TryStopAbility()
Ability.StopAbility() [1]
Ability.StopAbility()
Interrupt.StartItemReload()
ShootableAction.<>c.<StartItemReload>b__93_0()
CharacterItemAction.InvokeOnModulesWithType<IModuleStartItemReload>()
ShootableAction.StartItemReload()
Reload.AbilityStarted()
Ability.StartAbility()
UltimateCharacterLocomotion.TryStartAbility()
UltimateCharacterLocomotion.TryStartAbility()
Ability.StartAbility()
Reload.OnTryReload()
InvokableAction<int, IItemIdentifier, IItemIdentifier, bool, bool>.Invoke()
EventHandler.ExecuteEvent<int, IItemIdentifier, IItemIdentifier, bool, bool>()
TimedReloader.ItemUseComplete()
UsableAction.<>c.<ItemUseComplete>b__140_0()
CharacterItemAction.InvokeOnModulesWithType<IModuleItemUseComplete>()
UsableAction.ItemUseComplete()
UsableAction.HandleItemUseCompleteAnimationSlotEvent()
AnimationEventTrigger.NotifyEventListeners()
AnimationSlotEventTrigger.NotifyEventListeners()
AnimationEventTrigger.InvokeScheduledEvent()
SchedulerBase.AddEventInternal()
SchedulerBase.ScheduleFixed()
AnimationEventTrigger.WaitForEvent()
UsableAction.TriggeredUseItemActionComplete()
ShootableAction.TriggerItemAction()
[B]SimpleBaseTrigger.UseItemTrigger()[/B]
UsableAction.UseItem()
ShootableAction.UseItem()
UsableAction.UseItemUpdateInternal()
UsableAction.UseItemUpdate()
Use.LateUpdate()
UltimateCharacterLocomotion.LateUpdateActiveAbilities()
UltimateCharacterLocomotion.UpdateCharacter()
CharacterLocomotion.Move()
SimulationManager.CharacterComponents.Move()
SimulationManager.MoveCharacters()
SimulationManager.FixedUpdate()

Then, m_WasTriggered = true was set in SimpleBaseTrigger.UseItemTrigger() (see the bolded item in the call stack).

Can you suggest a mechanism for how to fix this use case where UseCompleteEvent needs to be zero and my weapons are using Simple / Charged as a trigger module?
 
Last edited:
I was able to fix this be adding in UseItemTrigger():

C#:
if (UsableAction.IsItemInUse())
{
    m_WasTriggered = true;    
}

Do you think this approach is safe?
 
Thank you for letting us know.

I'm not sure how safe that is...

Could you try this instead:

Code:
    /// <summary>
    /// A base class for simple trigger which execute the action once.
    /// </summary>
    [Serializable]
    public abstract class SimpleBaseTrigger : TriggerModuleAnimatorAudioStateSet, IModuleReloadItem

And

Code:
        /// <summary>
        /// Reloads the item.
        /// </summary>
        /// <param name="fullClip">Should the full clip be force reloaded?</param>
        public virtual void ReloadItem(bool fullClip)
        {
            m_WasTriggered = false;
            m_IsTriggering = false;
        }

I think that should be a bit safer.
 
Top