playMaker

Author Topic: [Solved? probably] Trigger Event storing a bool instead of sending an event?  (Read 2280 times)

nuFF3

  • Beta Group
  • Junior Playmaker
  • *
  • Posts: 73
  • Are we even real?
    • One Month Studio
I need an trigger action that stores a bool when the player is inside the triggerbox, but there seems to not be one on the ecosystem, and I'm too dumb to make my own.
I could do it the broken way of having the script check in one state with the 'Trigger Event' as 'On Trigger Stay' and the next as 'On Trigger Exit', then have them flip between eachother.
But this leaves a split second of where the script thinks the player is outside the triggerbox if I have two boxes next to each other.
Because the script has an 'On Trigger Exit', if the player triggers the next box but is still inside the first, as soon as the player has stopped triggering the first box; the code HAS to fire an event when 'On Trigger Exit' is triggered.
I have many solutions to this problem, but that's all sidestepping the issue.

I think the proper way to solve this problem would be to have an action that stores a bool when the 'On Trigger Stay' is triggered.
Regardless of how many objects is 'exited' as long as something is triggering the bool would stay 'true'... that's the idea anyway.
« Last Edit: June 03, 2020, 05:13:25 AM by nuFF3 »

nuFF3

  • Beta Group
  • Junior Playmaker
  • *
  • Posts: 73
  • Are we even real?
    • One Month Studio
Re: Trigger Event storing a bool instead of sending an event?
« Reply #1 on: June 02, 2020, 11:47:57 AM »
I set out to make this action myself, but I just can't get the if statement to work :-\

Well... actually that's not true, the if statement works just the way it should.
The problem I think stems from the fact that the trigger doesn't clear the stored gameobject if it's not being hit.
So it keeps thinking the last trigger it hit is still what is being triggered.
God this is just annoying me at this point >:(
« Last Edit: June 02, 2020, 11:53:23 AM by nuFF3 »

nuFF3

  • Beta Group
  • Junior Playmaker
  • *
  • Posts: 73
  • Are we even real?
    • One Month Studio
Re: Trigger Event storing a bool instead of sending an event?
« Reply #2 on: June 02, 2020, 03:28:43 PM »
Currently the custom action looks like this:

Code: [Select]
using UnityEngine;

namespace HutongGames.PlayMaker.Actions

{
[ActionCategory(ActionCategory.Physics)]
[Tooltip("Sets a boolean value based on if trigger is hit or not.")]
public class TriggerBool : FsmStateAction
{
[Tooltip("The GameObject to detect trigger events on.")]
public FsmOwnerDefault gameObject;

[Tooltip("Only OnTriggerStay works.")]
public TriggerType trigger;

[UIHint(UIHint.TagMenu)]
[Tooltip("Filter by Tag.")]
public FsmString collideTag;

[UIHint(UIHint.Variable)]
[Tooltip("Store a boolean value based on trigger state.")]
public FsmBool hitTrigger;

[UIHint(UIHint.Variable)]
[Tooltip("Store the GameObject that collided with the Owner of this FSM.")]
public FsmGameObject storeCollider;

public override void Reset()
{
gameObject = null;
trigger = TriggerType.OnTriggerStay;
collideTag = new FsmString() {UseVariable=false};
hitTrigger = null;
storeCollider = null;
}

public override void OnPreprocess()
{
switch (trigger)
{
case TriggerType.OnTriggerStay:
Fsm.HandleTriggerStay = true;
break;
}
}

void StoreCollisionInfo(Collider collisionInfo)
{
storeCollider.Value = collisionInfo.gameObject;
}

public override void DoTriggerStay(Collider collisionCheck)
{
if (trigger == TriggerType.OnTriggerStay)
{
if (collisionCheck.tag == collideTag.Value || collideTag.IsNone)
{
StoreCollisionInfo(collisionCheck);
hitTrigger.Value = true;
}

else if (collisionCheck.tag != collideTag.Value)
{
StoreCollisionInfo(collisionCheck);
hitTrigger.Value = false;
}
}
}
}
}

It works, but it works just like I would do with 'Trigger Event' actions and 'Set Bool Value'.   :-\
It only works when set to 'On Trigger Stay', and it will not clear the "stored" value once you've left the trigger.

Idk how to make that work. I even tried making a normal C# script but it works just like this custom action.
Annoyed to say the least.  >:(

I might need some help figuring this one out.

jeanfabre

  • Administrator
  • Hero Member
  • *****
  • Posts: 15620
  • Official Playmaker Support
Re: Trigger Event storing a bool instead of sending an event?
« Reply #3 on: June 03, 2020, 02:40:24 AM »
Hi,

 this is slightly more complex indeed, because you can't rely on the stay callback, you must use Enter and exit callback for this.

Also, the action I pasted below assumes you have only one object triggered at a time, because if you have two objects, then the first one exiting will trigger toggle it back off. There is a triggerCount action on the Ecosystem that could also help you should you want to go further and make sure you get a toggle off only when no more colliders are triggering.

Code: [Select]
// (c) Copyright HutongGames, LLC 2010-2013. All rights reserved.

using UnityEngine;

namespace HutongGames.PlayMaker.Actions
{
[ActionCategory(ActionCategory.Physics)]
[Tooltip("Detect trigger collisions between GameObjects that have RigidBody/Collider components and toggle a boolean when triggered.")]
public class TriggerEventToggle : FsmStateAction
{
        [Tooltip("The GameObject to detect trigger events on.")]
    public FsmOwnerDefault gameObject;

    [UIHint(UIHint.TagMenu)]
        [Tooltip("Filter by Tag.")]
public FsmString collideTag;

        [Tooltip("Event to send if the trigger event is detected.")]
public FsmEvent triggerEnterEvent;

[Tooltip("Event to send when the trigger has exited.")]
public FsmEvent triggerExitEvent;

[Tooltip("true while an collider is triggering")]
public FsmBool isTriggered;

        [UIHint(UIHint.Variable)]
        [Tooltip("Store the GameObject that collided with the Owner of this FSM.")]
public FsmGameObject storeCollider;

    // cached proxy component for callbacks
    private PlayMakerProxyBase cachedEnterProxy;
    private PlayMakerProxyBase cachedExitProxy;
   
public override void Reset()
{
    gameObject = null;
collideTag = "";
triggerEnterEvent = null;
triggerExitEvent = null;
isTriggered = null;

storeCollider = null;
}

public override void OnPreprocess()
{
            if (gameObject == null) gameObject = new FsmOwnerDefault();
           
    if (gameObject.OwnerOption == OwnerDefaultOption.UseOwner)
    {
    Fsm.HandleTriggerEnter = true;
    Fsm.HandleTriggerExit = true;
    }
    else
    {
        // Add proxy components now if we can
        GetProxyComponent();
    }
}

    public override void OnEnter()
    {
        if (gameObject.OwnerOption == OwnerDefaultOption.UseOwner)
            return;

        if (cachedEnterProxy == null || cachedExitProxy == null)
            GetProxyComponent();

        AddCallback();

        gameObject.GameObject.OnChange += UpdateCallback;
    }

    public override void OnExit()
    {
        if (gameObject.OwnerOption == OwnerDefaultOption.UseOwner)
            return;

        RemoveCallback();

        gameObject.GameObject.OnChange -= UpdateCallback;
    }

    private void UpdateCallback()
    {
        RemoveCallback();
        GetProxyComponent();
        AddCallback();
    }

    private void GetProxyComponent()
    {
    cachedEnterProxy = null;
    cachedExitProxy = null;
   
        var source = gameObject.GameObject.Value;
        if (source == null)
            return;

    cachedEnterProxy = PlayMakerFSM.GetEventHandlerComponent<PlayMakerTriggerEnter>(source);
     
    cachedExitProxy = PlayMakerFSM.GetEventHandlerComponent<PlayMakerTriggerExit>(source);
               
       
    }

    private void AddCallback()
    {
        if (cachedEnterProxy != null)  cachedEnterProxy.AddTriggerEventCallback(TriggerEnter);
       
        if (cachedExitProxy != null)  cachedEnterProxy.AddTriggerEventCallback(TriggerExit);

       
    }

    private void RemoveCallback()
    {
    if (cachedEnterProxy != null)  cachedEnterProxy.RemoveTriggerEventCallback(TriggerEnter);
       
        if (cachedExitProxy != null)  cachedEnterProxy.RemoveTriggerEventCallback(TriggerExit);

    }

    private void StoreCollisionInfo(Collider collisionInfo)
{
storeCollider.Value = collisionInfo.gameObject;
}

public override void DoTriggerEnter(Collider other)
{
    if (gameObject.OwnerOption == OwnerDefaultOption.UseOwner)
        TriggerEnter(other);
}


public override void DoTriggerExit(Collider other)
{
    if (gameObject.OwnerOption == OwnerDefaultOption.UseOwner)
        TriggerExit(other);
}

    private void TriggerEnter(Collider other)
    {
    if (TagMatches(collideTag, other))
    {
    isTriggered = true;
    StoreCollisionInfo(other);
    Fsm.Event(triggerEnterEvent);
    }
    }


    private void TriggerExit(Collider other)
    {
    if (TagMatches(collideTag, other))
    {
    isTriggered = false;
    StoreCollisionInfo(other);
    Fsm.Event(triggerExitEvent);
    }
    }

public override string ErrorCheck()
{
return ActionHelpers.CheckPhysicsSetup(Fsm.GetOwnerDefaultTarget(gameObject));
}
}
}

Bye,

 Jean
« Last Edit: June 03, 2020, 02:49:37 AM by jeanfabre »

nuFF3

  • Beta Group
  • Junior Playmaker
  • *
  • Posts: 73
  • Are we even real?
    • One Month Studio
Re: Trigger Event storing a bool instead of sending an event?
« Reply #4 on: June 03, 2020, 04:41:39 AM »
Thanks Jean.
I'm gonna try the 'triggerCount' action, and I'll post back if I got it working.

I'm no programmer, so this process was kinda painful. I had to go in blind and copy logic from different actions, and searching the unity forums for similar ideas.
Problems arose when I tried putting the same logic from the C# scripts into the Playmaker actions. It seems you guys are doing your own thing on many of these functions.
And I couldn't for the life of me find any documentation on it. So I had to essentially do it by trial and error.

nuFF3

  • Beta Group
  • Junior Playmaker
  • *
  • Posts: 73
  • Are we even real?
    • One Month Studio
Re: Trigger Event storing a bool instead of sending an event?
« Reply #5 on: June 03, 2020, 04:59:08 AM »
Just tested the 'Trigger Count' action, and it seems to work exactly how I was hoping for in the first place.
I guess it was there under my nose the whole time :P

I'm gonna set this post as [Solved] now, I'm not going to bother making custom actions for a while I think.
« Last Edit: June 03, 2020, 05:13:03 AM by nuFF3 »