playMaker

Author Topic: How to find a game object through a custom action?  (Read 4349 times)

Coopaloops

  • Playmaker Newbie
  • *
  • Posts: 6
How to find a game object through a custom action?
« on: June 25, 2014, 11:49:04 PM »
Hey guys! Just bought PlayMaker for a project I'm working on, and I am loving it so far! I'm in the process of trying to write a very simple custom action that involves finding a game object - my GameController object - and calling a function in the GameController to lock player input. I can't for the life of me figure out the best way to find my GameController object via the script...I'm trying to do it the way I usually find things :

GameObject.FindObjectWithTag("GameController").GetComponent<GameController>()

And here is what I currently have for the custom action:

using UnityEngine;
using System.Collections;

namespace HutongGames.PlayMaker.Actions {

   [ActionCategory("Custom")]
   public class PLYMKRLockPlayerAttack : FsmStateAction {

      private GameController gameController;

      public override void Awake() {
         gameController = GameObject.FindGameObjectWithTag("GameController").GetComponent<GameController>();
      }

      public override void OnEnter() {
         gameController.LockPlayerAttack();
      }

   } // end class

} // end namespace


I keep getting a null reference exception when I start up the scene in Unity. A couple hours of Googling, and I haven't found much. I'm guessing it doesn't work the same way finding game objects in normal Unity scripts work...any help would be appreciated. This is probably the easiest thing ever, but I'm just missing some minor detail...I'm kind of a noob with custom actions, but am trying to learn. Thanks!

Alex Chouls

  • Administrator
  • Hero Member
  • *****
  • Posts: 4003
  • Official Playmaker Support
    • LinkedIn
Re: How to find a game object through a custom action?
« Reply #1 on: June 26, 2014, 01:17:32 AM »
Awake is called when the action is first loaded and it's quite likely the scene hasn't been initialized yet. Put GameObject.FindGameObjectWithTag in OnEnter instead.

However, you can also do this in Playmaker without custom actions:
Find Game Object to find by tag.
Send Message to call LockPlayerAttack.

Coopaloops

  • Playmaker Newbie
  • *
  • Posts: 6
Re: How to find a game object through a custom action?
« Reply #2 on: June 26, 2014, 11:46:47 PM »
Thanks for the quick reply. I tried putting the call inside OnEnter(), but no dice. Still getting a null reference exception when I start the scene. Is there a problem with using the GameObject.FindObjectWithTag() function in a custom action? The interesting thing is that the game still runs fine...it ends up working when my character moves to another state and then back. It seems like when the FSM is initially loaded, it can't find the GameController object.

Here is my updated script:

using UnityEngine;
using System;

namespace HutongGames.PlayMaker.Actions {

   [ActionCategory("Custom")]
   public class PLYMKRUnlockPlayerAttack : FsmStateAction {

      public override void OnEnter() {
         GameController gameController = GameObject.FindGameObjectWithTag("GameController").GetComponent<GameController>();
         gameController.UnlockPlayerAttack();
      }

   } // end class

} // end namespace



I've also attached a pic of my state machine in PlayMaker. The error is happening in the first state (PlayerOutOfRange), which is where the unlock attack custom action gets called. No idea why this seemingly trivial thing is throwing an error.

Here is the call stack as well:

NullReferenceException: Object reference not set to an instance of an object
GameController.UnlockPlayerAttack () (at Assets/08-Scripts/GameController.cs:221)
HutongGames.PlayMaker.Actions.PLYMKRUnlockPlayerAttack.OnEnter () (at Assets/08-Scripts/Actions/PLYMKRUnlockPlayerAttack.cs:16)
HutongGames.PlayMaker.FsmState.ActivateActions (Int32 startIndex)
HutongGames.PlayMaker.FsmState.OnEnter ()
HutongGames.PlayMaker.Fsm.EnterState (HutongGames.PlayMaker.FsmState state)
HutongGames.PlayMaker.Fsm.SwitchState (HutongGames.PlayMaker.FsmState toState)
HutongGames.PlayMaker.Fsm.UpdateStateChanges ()
HutongGames.PlayMaker.Fsm.Start ()
HutongGames.PlayMaker.Fsm.ProcessEvent (HutongGames.PlayMaker.FsmEvent fsmEvent, HutongGames.PlayMaker.FsmEventData eventData)
HutongGames.PlayMaker.Fsm.Event (HutongGames.PlayMaker.FsmEventTarget eventTarget, HutongGames.PlayMaker.FsmEvent fsmEvent)
HutongGames.PlayMaker.Fsm.Event (HutongGames.PlayMaker.FsmEvent fsmEvent)
PlayMakerFSM.OnLevelWasLoaded ()


Ideally I would like to get this working without having to use the SendMessage. Thanks for the help!

Alex Chouls

  • Administrator
  • Hero Member
  • *****
  • Posts: 4003
  • Official Playmaker Support
    • LinkedIn
Re: How to find a game object through a custom action?
« Reply #3 on: June 27, 2014, 01:42:04 AM »
The error log shows the null reference error is here:
GameController.UnlockPlayerAttack () (at Assets/08-Scripts/GameController.cs:221)

So it's finding the GameController then failing inside UnlockPlayerAttack. What's at line 221?


Coopaloops

  • Playmaker Newbie
  • *
  • Posts: 6
Re: How to find a game object through a custom action?
« Reply #4 on: June 27, 2014, 11:07:09 AM »
That line is calling a function in another game object - my player object - which is initialized in the GameController's Start() function. It only breaks when PlayMaker tries to call it in the first state of the state machine.

Alex Chouls

  • Administrator
  • Hero Member
  • *****
  • Posts: 4003
  • Official Playmaker Support
    • LinkedIn
Re: How to find a game object through a custom action?
« Reply #5 on: June 27, 2014, 12:15:49 PM »
Unity doesn't guarantee execution order of MonoBehaviours, so the PlayMakerFSM component is probably running before the GameController Start.

Some options:

- Put the GameController initialization in Awake instead of Start.
- Make the player object a Property and initialize it when it's accessed.
- Delay the FSM by one frame (use Next Frame Event).