playMaker

Author Topic: [SOLVED] How to handle a "isStoppedForXSeconds" state  (Read 2910 times)

David

  • Playmaker Newbie
  • *
  • Posts: 18
[SOLVED] How to handle a "isStoppedForXSeconds" state
« on: July 29, 2012, 07:34:50 AM »
Hey guys,

just bought playmaker some days ago, and I'm loving it :) I'm now looking to reimplement some parts of my game with it.

I won't explain the whole game here as it will be a little too long and off topic but let's say I'm trying to program a kind of "Worms-like" game (the view is like a side scroller and characters walks along the terrain, and can fall if they're being shot at...)

To make my character walk I use a character controller that I deactivate when they are falling. At this moment I activate another Collider and sets a rigidbody "is Kinematic" property to false to make my character fall along the terrain. It works great and I'm now looking for a "playmaker" way to test if my rigidbody's speed is under a given value for X seconds.

I currently have a working solution, but as long as playmaker debug log is active I get a lot of "Infinite loop" logs, and if I set the "inifite loop thresold" to an higher value, I get Stack Overflow exceptions. Despite the loss of FPS due to the many logs, the FSM runs without any problem.

I attached a screenshot of my current FSM.

My StopCheck state works like this :
- it sets a "timeSinceStopped" variable to 0 once when entering the state
- it adds the deltaTime to "timeSinceStopped" each frame
- if the rigidbody's speed is above the min speed I've set, I emit the DidMove signal. It makes the FSM start the StopCheck state again (so timeSinceStopped is set to 0 again)
- if timeSinceStopped variable is above a given value, it emits the IsStopped signal that makes the FSM switch to StandUp state

Is this a wrong way to do what I'm trying to do ? Is there a better way ? Is it better to avoid having too many state change in a FSM ?

The best way I'd see yet to solve this problem would be to code an action that does the same as above without needing a state change, it would be very simple to do that but I was asking myself if there's a better way to do that with what we already have in playmaker.
« Last Edit: July 30, 2012, 04:23:10 AM by David »

PlatinumPlayer

  • Playmaker Newbie
  • *
  • Posts: 26
Re: How to handle a "isStoppedForXSeconds" state
« Reply #1 on: July 29, 2012, 08:10:28 AM »
If your looking for a certain speed why not get the objects velocity and compare that velocity with a float compare to the number you desire? Your question was a bit confusing to me, i'm not sure exactly what you are trying to do in game.

Example:
Get velocity(velocity)
Float compare (velocity) to 0, equal to 0 = do event walk.

Are you making a ragdoll that recovers when they land on solid ground? Or is this something like a fall damage/game over check?
« Last Edit: July 29, 2012, 08:16:21 AM by PlatinumPlayer »

David

  • Playmaker Newbie
  • *
  • Posts: 18
Re: How to handle a "isStoppedForXSeconds" state
« Reply #2 on: July 29, 2012, 08:26:44 AM »
Sorry, my post was maybe a little too long.

Let's say I have a character walking on terrain. I want him to fall under certain conditions (let's say when hit by a weapon, when there's an explosion...). When he's falling he's just a simple rigidbody with a collider (I don't need a ragdoll).

I just wanted to test if it's speed is below a given value for some seconds. I can't just test
Code: [Select]
if(speed < value) emit eventbecause sometimes speed = 0 for a frame or two, then the rigidbody slides or roll down a platform or a hill on the terrain. So I want to be sure that speed = 0 or speed < thresold for let's say 5 seconds before I emit an event.

The code for doing that is pretty simple (see below) but I just wanted to know if there's already a way to do that with the existing playmaker actions.

The corresponding action would be something like this, but as I've said before, I was searching for a way to do the same with the existing actions ;)

Code: [Select]
using UnityEngine;
using HutongGames.PlayMaker;

[ActionCategory(ActionCategory.Physics)]
[Tooltip("Emit an event as soon as the given rigidbody's speed has been under a given value for X seconds")]
public class IsRigidbodyStoppedForXSeconds : FsmStateAction
{
[RequiredField]
[CheckForComponent(typeof(Rigidbody))]
public FsmOwnerDefault gameObject;

[RequiredField]
[UIHint(UIHint.FsmFloat)]
public FsmFloat minimumStopSpeed;

[RequiredField]
[UIHint(UIHint.FsmFloat)]
public FsmFloat stoppedTimeBeforeEvent;
[RequiredField]
public FsmEvent sendEvent;

public FsmFloat storeStoppedTimeResult;

protected Rigidbody rigidbody;

// Code that runs on entering the state.
public override void OnEnter()
{
storeStoppedTimeResult.Value = 0;

GameObject go = Fsm.GetOwnerDefaultTarget(gameObject);
if (go == null)
{
return;
}

rigidbody = go.GetComponent<Rigidbody>();
if(rigidbody == null)
{
return;
}
}

// Code that runs every frame.
public override void OnUpdate()
{
if(isStoppedForXSeconds())
{
Fsm.Event(sendEvent);
}
}

protected bool isStoppedForXSeconds()
{
if(rigidbody.velocity.magnitude < minimumStopSpeed.Value)
{
storeStoppedTimeResult.Value += Time.deltaTime;
}
else
{
storeStoppedTimeResult.Value = 0;
}

if(storeStoppedTimeResult.Value >= stoppedTimeBeforeEvent.Value)
{
return true;
}
return false;
}
}

jeanfabre

  • Administrator
  • Hero Member
  • *****
  • Posts: 15500
  • Official Playmaker Support
Re: How to handle a "isStoppedForXSeconds" state
« Reply #3 on: July 30, 2012, 04:06:22 AM »
Hi,

 There is something similar in the M2H game samples I ported to playmaker.

 So download them examples here:
https://hutonggames.fogbugz.com/default.asp?W880

study the 3d break out game:
https://hutonggames.fogbugz.com/default.asp?W936


 have a look at this particular fsm:
https://hutonggames.fogbugz.com/default.asp?W942


That would be a good base to start a timer when it's going to slow and cancel that timer if it speeds ups again.

bye,

 Jean

David

  • Playmaker Newbie
  • *
  • Posts: 18
Re: How to handle a "isStoppedForXSeconds" state
« Reply #4 on: July 30, 2012, 04:22:55 AM »
Thank you for your answer :) My code/FSM is now working well with the custom action I did (the one pasted in my last post) but I will definitely check your samples. I guess playmaker didn't liked my "loop on itself each frame as long as speed != 0" state :)