playMaker

Author Topic: GetNextChild revisited  (Read 6146 times)

jeanfabre

  • Administrator
  • Hero Member
  • *****
  • Posts: 15500
  • Official Playmaker Support
GetNextChild revisited
« on: February 13, 2012, 03:18:19 AM »
Hi,

 Here is a revisited version of getNextchild (http://hutonggames.com/playmakerforum/index.php?topic=1057.0) allowing you to re iterate over and over again: It provides a more stable behavior if it is supposed to be called several times during the lifetime of the fsm.


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

using UnityEngine;

namespace HutongGames.PlayMaker.Actions
{
[ActionCategory(ActionCategory.GameObject)]
[Tooltip("Each time this action is called it gets the next child of a GameObject. This lets you quickly loop through all the children of an object to perform actions on them. NOTE: To find a specific child use Find Child.")]
public class GetNextChild : FsmStateAction
{
[RequiredField]
[Tooltip("The parent GameObject. Note, if GameObject changes, this action will reset and start again at the first child.")]
public FsmOwnerDefault gameObject;

[RequiredField]
[UIHint(UIHint.Variable)]
[Tooltip("Store the next child in a GameObject variable.")]
public FsmGameObject storeNextChild;

[Tooltip("Event to send to get the next child.")]
public FsmEvent loopEvent;

[Tooltip("Event to send when there are no more children.")]
public FsmEvent finishedEvent;

public override void Reset()
{
gameObject = null;
storeNextChild = null;
loopEvent = null;
finishedEvent = null;
}

// cache the gameObject so we no if it changes
private GameObject go;

// increment a child index as we loop through children
private int nextChildIndex;

public override void OnEnter()
{

DoGetNextChild(Fsm.GetOwnerDefaultTarget(gameObject));

Finish();
}

void DoGetNextChild(GameObject parent)
{
if (parent == null)
{
return;
}

// reset?

if (go != parent)
{
go = parent;
nextChildIndex = 0;
}

// no more children?
// check first to avoid errors.

if (nextChildIndex >= go.transform.childCount)
{
nextChildIndex = 0;
Fsm.Event(finishedEvent);
return;
}

// get next child

storeNextChild.Value = parent.transform.GetChild(nextChildIndex).gameObject;


// no more children?
// check a second time to avoid process lock and possible infinite loop if the action is called again.
// Practically, this enabled calling again this state and it will start again iterating from the first child.

if (nextChildIndex >= go.transform.childCount)
{
nextChildIndex = 0;
Fsm.Event(finishedEvent);
return;
}

// iterate the next child
nextChildIndex++;

if (loopEvent!=null)
{
Fsm.Event(loopEvent);
}
}
}
}

Feel free to step in if something is wrong.
 
Bye,

 Jean
« Last Edit: February 13, 2012, 03:20:19 AM by jeanfabre »

Alex Chouls

  • Administrator
  • Hero Member
  • *****
  • Posts: 3987
  • Official Playmaker Support
    • LinkedIn
Re: GetNextChild revisited
« Reply #1 on: February 13, 2012, 04:19:07 PM »
Nice one! I've integrated these changes into the next build. Thanks!

justifun

  • 1.2 Beta
  • Sr. Member
  • *
  • Posts: 280
Re: GetNextChild revisited
« Reply #2 on: March 08, 2012, 11:35:11 PM »
Fantastic! Worked like a charm!

I was able to setup a empty game object and parent several different pickup items underneath it.
Then i used GetNextChild to deactivate all of them.
Once it finished, it went to a new state where i used "get random child" and activated just that one.
Now i can place my ItemPrefab all over my game, and each time you play it will end up with a random item drop each time you play!

Thanks Jean!