playMaker

Author Topic: Add FSM Template at Runtime? [SOLVED]  (Read 11309 times)

JennaReanne

  • Junior Playmaker
  • **
  • Posts: 57
    • View Profile
    • Little Worlds Interactive
Re: Add FSM Template at Runtime?
« Reply #15 on: June 19, 2014, 10:52:03 AM »
I know this thread is old but wow, these actions are amazing.  Thank you so much for sharing!

xunxun

  • Junior Playmaker
  • **
  • Posts: 53
    • View Profile
Re: Add FSM Template at Runtime? [SOLVED]
« Reply #16 on: September 25, 2014, 01:45:54 AM »
this is awesome. Thanks much!

ClintonReddie

  • Playmaker Newbie
  • *
  • Posts: 7
    • View Profile
Re: Add FSM Template at Runtime? [SOLVED]
« Reply #17 on: October 12, 2014, 10:57:22 PM »
More thanks.

joepalos

  • Playmaker Newbie
  • *
  • Posts: 28
    • View Profile
Re: Add FSM Template at Runtime? [SOLVED]
« Reply #18 on: July 31, 2016, 11:56:20 AM »
Thanks a lot for this, amazing.

MarkD

  • Junior Playmaker
  • **
  • Posts: 90
    • View Profile
Re: Add FSM Template at Runtime? [SOLVED]
« Reply #19 on: September 30, 2016, 11:33:38 PM »
This is really fantastic - thank you for posting it!

One thing I'm having trouble with however:  I can add an FSM template to my player and then have that FSM destroy itself when the "buff" is finished.  But after that buff has expired, I can't get that same template to be applied again to the player. 

I want it so that it only adds the script again IF the buff has expired.  I don't want to use "exists" to add another template, rather I want the buff to be applied, run its full course, and then be able to be applied again.

Any ideas?  Am I missing something?

Here's my setup in case it's something in my setup.

« Last Edit: October 01, 2016, 09:29:12 AM by MarkD »

ransomink

  • Playmaker Newbie
  • *
  • Posts: 44
    • View Profile
Re: Add FSM Template at Runtime?
« Reply #20 on: October 08, 2016, 02:28:38 AM »
Last but not least you can optionally send variables to the newly added template. This will initially disable the FSM, add the template, change the variables, then enable the FSM so it can properly start with the variables added.

Code: [Select]
using System.Collections.Generic;
using UnityEngine;

namespace HutongGames.PlayMaker.Actions {
[ActionCategory(ActionCategory.StateMachine)]
public class AddFsmTemplate : FsmStateAction {
[RequiredField]
public FsmOwnerDefault gameObject;
[RequiredField]
public FsmTemplate template;
public FsmString name;
public FsmBool active;
public FsmBool unique;
[CompoundArray("Variables", "Name", "Variable")]
[RequiredField]
public FsmString[] variableNames;
[RequiredField]
public FsmVar[] variables;

private GameObject previousGo;
private List<PlayMakerFSM> fsms;

public override void Reset() {
gameObject = null;
template = null;
name = new FsmString { UseVariable = true };
active = new FsmBool { Value = true };
unique = new FsmBool { Value = false };
variableNames = new FsmString[0];
variables = new FsmVar[0];
}

public override void OnEnter() {
var go = Fsm.GetOwnerDefaultTarget( gameObject );

if ( go == null ) {
return;
}

bool exists = false;

if ( ! unique.Value ) {
if ( go != previousGo ) {
fsms = new List<PlayMakerFSM>();

fsms.AddRange( go.GetComponents<PlayMakerFSM>() );

previousGo = go;
}

if ( fsms.Count > 0 ) foreach ( PlayMakerFSM fsm in fsms ) {
if ( ( ( name.Value != "" ) && ( fsm.FsmName == name.Value ) ) || ( ( fsm.FsmTemplate != null ) && ( fsm.FsmTemplate.name == template.name ) ) ) {
exists = true;
}
}
}

if ( ! exists ) {
PlayMakerFSM newFsm = go.AddComponent<PlayMakerFSM>();

if ( name.Value != "" ) {
newFsm.FsmName = name.Value;
}

if ( ( ! active.Value ) || ( variableNames.Length > 0 ) ) {
newFsm.enabled = false;
}

newFsm.SetFsmTemplate( template );

if ( variableNames.Length > 0 ) {
if ( variableNames.Length > 0 ) for ( int i = 0; i < variableNames.Length; i++ ) {
if ( ! variableNames[i].IsNone ) {
NamedVariable target = newFsm.Fsm.Variables.GetVariable( variableNames[i].Value );

if ( target != null ) {
variables[i].ApplyValueTo( target );
}
}
}

if ( active.Value && ( ! newFsm.enabled ) ) {
newFsm.enabled = true;
}
}

if ( ! unique.Value ) {
fsms.Add( newFsm );
}
}

Finish();
}
}
}

Now all that's left is a "DestroyFSM" action to completely get rid of the FSM component. I have yet to figure this one out yet, but once I do this can be used very effectively for spell debuffs, temporary affects like drag on a rigidbody to simulate "slowing", and much much more.

Regarding performance using the above I saw very little loss, if any at all, so it seams perfectly safe to use as needed.

Is there anyone else having trouble getting the variables to update? Adding the template works great, but when I choose variables to use for the template, it does not operate correctly...

jeanfabre

  • Administrator
  • Hero Member
  • *****
  • Posts: 14832
  • Official Playmaker Support
    • View Profile
Re: Add FSM Template at Runtime? [SOLVED]
« Reply #21 on: October 19, 2016, 11:24:33 PM »
Hi,

 the variable is only used on Enter, it doesn't udpdate everyframe.

 For this you'll need to use GetFsmXXX and GetHost or GetHostInfo from the Ecosystem, and then your template can get fsm variables this way ( AND set variables too). If you want to decouple the variable name, have as public variable the names of the variables, and then within your template you use them names to access variables, then your template doesn't have to know the variables names of the host.


Bye,

 Jean

abend

  • Playmaker Newbie
  • *
  • Posts: 25
    • View Profile
Re: Add FSM Template at Runtime? [SOLVED]
« Reply #22 on: October 02, 2019, 01:09:50 PM »
I am using this script to add a template at runtime from a loop to 4 or 5 game objects. I have 1 variable on my template called Target which is a GameObject. When running, sometimes the variable is populated with what I expect, other times all variables are None, and sometimes the middle of the loop objects are populated, bnut the first and last object are none. I see that there are paired variable arrays here. When I step through, it always seems to populate correctly, but when I run it freely, it's hit or miss. Is there another aspect to this that I am not understanding?

UPDATE: I have skipped the variables section in this script and run set fsm variable right after this. It seems to be working now.

Thanks!
« Last Edit: October 02, 2019, 02:05:37 PM by abend »