playMaker

Author Topic: ControllerMove with everyFrame checkbox.  (Read 3070 times)

ClaudioFreda

  • Playmaker Newbie
  • *
  • Posts: 9
ControllerMove with everyFrame checkbox.
« on: February 17, 2014, 12:28:54 PM »
Since I rarely use the actions which execute on Update, as I prefer to do all my update loops using a Next Frame Event (like this), I needed a way to execute the ControllerMove action upon entering a state.

So I added the everyFrame checkbox that almost every other action has.

Tested on my project and works properly. Hope you find it useful.

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

using UnityEngine;

namespace HutongGames.PlayMaker.Actions
{
[ActionCategory(ActionCategory.Character)]
[Tooltip("Moves a Game Object with a Character Controller. See also Controller Simple Move. NOTE: It is recommended that you make only one call to Move or SimpleMove per frame.")]
public class ControllerMove : FsmStateAction
{
[RequiredField]
[CheckForComponent(typeof(CharacterController))]
[Tooltip("The GameObject to move.")]
public FsmOwnerDefault gameObject;

[RequiredField]
[Tooltip("The movement vector.")]
public FsmVector3 moveVector;

[Tooltip("Move in local or word space.")]
public Space space;

[Tooltip("Movement vector is defined in units per second. Makes movement frame rate independent.")]
public FsmBool perSecond;

public bool everyFrame;


private GameObject previousGo; // remember so we can get new controller only when it changes.
private CharacterController controller;

public override void Reset()
{
gameObject = null;
moveVector = new FsmVector3 {UseVariable = true};
space = Space.World;
perSecond = true;
}

public override void OnEnter()
{
DoCharacterMove();

if (!everyFrame)
Finish();
}

public override void OnUpdate()
{
DoCharacterMove();
}

private void DoCharacterMove()
{
var go = Fsm.GetOwnerDefaultTarget(gameObject);
if (go == null) return;

if (go != previousGo)
{
controller = go.GetComponent<CharacterController>();
previousGo = go;
}

if (controller != null)
{
var move = space == Space.World ? moveVector.Value : go.transform.TransformDirection(moveVector.Value);

if (perSecond.Value)
{
controller.Move(move * Time.deltaTime);
}
else
{
controller.Move(move);
}
}
}
}
}
« Last Edit: February 17, 2014, 12:32:07 PM by ClaudioFreda »

jeanfabre

  • Administrator
  • Hero Member
  • *****
  • Posts: 15500
  • Official Playmaker Support
Re: ControllerMove with everyFrame checkbox.
« Reply #1 on: February 17, 2014, 11:33:08 PM »
Hi,

 Be careful with official action modifications. Rename them for safety otherwise they will be overwritten back to the official action everytime you update PlayMaker.

Also:

Can you describe further why you use the next frame event for everything. You are aware that this implies some performances issues that you don't have with the "everyframe" options of actions.

 I am curious to see what problem you encountered with this. you may have some very good reasons actually.


 Bye,

 Jean

ClaudioFreda

  • Playmaker Newbie
  • *
  • Posts: 9
Re: ControllerMove with everyFrame checkbox.
« Reply #2 on: February 18, 2014, 02:59:37 PM »
Yes, in the version I used the action has a different name. I posted it with the original name for clarity.

About the performance issues, the only thing I can think of is having to memorize more states. Can you elaborate on the reason for the performance loss? I didn't notice any in the profiler.

Anyway, I write update cycles "by hand" (as in, as a collection of chained states) mostly when I have to implement complex control structures like loops and ifs during the update cycle. Usually then I save the cycle as a template and run it with the "Run FSM" action in a more general FSM.

It helps make the logic of what's happening clearer and easier to work on as a team.

So, I don't actually use it "for everything", I just use it more than the tutorials recommend.

jeanfabre

  • Administrator
  • Hero Member
  • *****
  • Posts: 15500
  • Official Playmaker Support
Re: ControllerMove with everyFrame checkbox.
« Reply #3 on: February 18, 2014, 11:53:19 PM »
Hi,

 Very good.

 the main reason as far as performance where I think everyframe as an edge is that actions do not need to re start every update.

 if you have an action that instantiate several objects, get some components on the targeted gameobject and all this, using an everyframe based action always there means only ONE instanciatation for the whole cycle, possible the whole game. If you do a next frame event, states are entered and left every update and therefore each and every action instantiates, initiated destroyed, garbage collected somehow by the memory managed and all its internal stuff as well.

So, yes for small cases I am sure nothing will be noticeable, but for larger project, that would certainly become a possible issue. This also very much depends on the actions used in that cycle of course.

bye,

 Jean

ClaudioFreda

  • Playmaker Newbie
  • *
  • Posts: 9
Re: ControllerMove with everyFrame checkbox.
« Reply #4 on: February 19, 2014, 07:44:53 AM »
Yep, I do all those performance-heavy stuff like instantiating and getting components before entering the loop, so it should be fine.

Thanks for the interest :D