playMaker

Author Topic: Simulate key press with Playmaker  (Read 4731 times)

RICK

  • Playmaker Newbie
  • *
  • Posts: 39
Simulate key press with Playmaker
« on: October 19, 2019, 05:39:51 PM »
Hi,

Say I have a state machine and at a certain state I want It to simulate a key or button press, how could I go about doing this?

Thanks,

Rick C

Thore

  • Sr. Member
  • ****
  • Posts: 480
Re: Simulate key press with Playmaker
« Reply #1 on: October 20, 2019, 06:27:42 AM »
Depends on what it means exactly. My guess is that you usually e.g. jump by pressing a key, but you want to automatically jump sometimes. The solution is to trigger the behaviour directly. In this case, the jump is triggered by a mechanic.

You can do this by adding a global event to the state that comes after the key is pressed, and some mechanic (probably on a different FSM) that sends out the event.

RICK

  • Playmaker Newbie
  • *
  • Posts: 39
Re: Simulate key press with Playmaker
« Reply #2 on: October 20, 2019, 08:28:00 AM »
Thanks for replying. Let me tell you exactly what I'm trying to do.

I have an asset from the asset store called Active Ragdoll. In the rag doll scene, it has a rag doll character that can go from mecanim animation to rag doll and back to mecanim animation with get up animations. In Play mode there are 5 key inputs to control the rag doll character:
Q- Convert to/from  ragdoll+connected
1- Connected=false
2- Connected=true
3- IsRagdoll=false
4- IsRagdoll=true

I thought there might be a way to simulate the key presses I need automatically in
the FSM state machine where I need to.

The Active Ragdoll asset uses C# scripts so I guess I'm going to have to access
the script to set the booleans controlling the rag doll. I don't know how to script.

I did some research after my first post, I'm thinking maybe I need to make those
bools public and then access them through playmaker with the call method action,
Is that correct? I pulled up the call method action, put the script in the behavior
slot, picked inherited as method and got a drop down list. That's as far as I got, I
don't know what to do know. Is this the right way to do it?

Thanks,

Rick C




Broken Stylus

  • Beta Group
  • Hero Member
  • *
  • Posts: 772
Re: Simulate key press with Playmaker
« Reply #3 on: October 22, 2019, 06:35:56 AM »
Drag and drop the script into any state's action tab and see what it suggests. Maybe Call Method would be necessary there too.

RICK

  • Playmaker Newbie
  • *
  • Posts: 39
Re: Simulate key press with Playmaker
« Reply #4 on: October 22, 2019, 09:00:56 AM »
Did That and I don't know if it is correct. It didn't work. When _ragdoll.IsConnected is made true, the character should ragdoll. See screen shots of what I tried.

Rick C

Broken Stylus

  • Beta Group
  • Hero Member
  • *
  • Posts: 772
Re: Simulate key press with Playmaker
« Reply #5 on: October 22, 2019, 10:51:04 AM »
Are you trying to run methods found inside a script attached to the game object that also has the FSM on it?
What are the methods' names and their arguments (parameters)?

RICK

  • Playmaker Newbie
  • *
  • Posts: 39
Re: Simulate key press with Playmaker
« Reply #6 on: October 22, 2019, 11:14:08 AM »
Yes, I need to set the bools to true or false via Playmaker.

_ragdoll.IsConnected

Rick C

RICK

  • Playmaker Newbie
  • *
  • Posts: 39
Re: Simulate key press with Playmaker
« Reply #7 on: October 22, 2019, 11:18:59 AM »
In the script, it has GetKeyDown. Key 1 makes the bool false and Key 2 makes the bool true.

Rick C

RICK

  • Playmaker Newbie
  • *
  • Posts: 39
Re: Simulate key press with Playmaker
« Reply #8 on: October 22, 2019, 11:25:13 AM »
Here is the script





Code: [Select]
System;
using System.Linq;
using BzKovSoft.ActiveRagdoll;
using UnityEngine;

namespace BzKovSoft.ActiveRagdollSamples
{
public class BzThirdPersonActiveRagdoll : MonoBehaviour
{
readonly int _animatorVelocityX = Animator.StringToHash("VelocityX");
readonly int _animatorVelocityY = Animator.StringToHash("VelocityY");

Animator _animator;
IBzRagdoll _ragdoll;
IBzBalancer _balancer;
float _connectionTime;

void OnEnable()
{
_animator = GetComponent<Animator>();
_ragdoll = GetComponent<IBzRagdoll>();
_balancer = GetComponent<IBzBalancer>();

if (_balancer == null)
throw new InvalidOperationException("No balancer defined on the character");

RefreshLayout();
}

private void Update()
{
ProcessKeyPressings();

float x = Input.GetAxis("Horizontal");
float y = Input.GetAxis("Vertical");

if (Input.GetMouseButton(1))
{
x = 0;
y = 0;
}

if (_ragdoll.IsConnected)
{
Vector3 balVel = _balancer.BalanceVelocity;
float magnitude = balVel.magnitude;
if (magnitude > 1.5f & _connectionTime + 2f < Time.time)
{
_ragdoll.IsConnected = false;
RefreshLayout();
return;
}

balVel *= 2f;

if (magnitude > 0.1f)
{
balVel = transform.InverseTransformDirection(balVel);
x += balVel.x;
y += balVel.z;
}
}

// update the animator parameters
//_animator.SetFloat(_animatorVelocityX, x, 0.2f, Time.deltaTime);
//_animator.SetFloat(_animatorVelocityY, y, 0.2f, Time.deltaTime);
}

private void ProcessKeyPressings()
{
if (Input.GetKeyDown(KeyCode.Keypad1) | Input.GetKeyDown(KeyCode.Alpha1))
{
_ragdoll.IsConnected = false;
RefreshLayout();
}
if (Input.GetKeyDown(KeyCode.Keypad2) | Input.GetKeyDown(KeyCode.Alpha2))
{
_ragdoll.IsConnected = true;
_connectionTime = Time.time;
RefreshLayout();
}
if (Input.GetKeyDown(KeyCode.Keypad3) | Input.GetKeyDown(KeyCode.Alpha3))
{
_ragdoll.IsRagdolled = false;
RefreshLayout();
}
if (Input.GetKeyDown(KeyCode.Keypad4) | Input.GetKeyDown(KeyCode.Alpha4))
{
_ragdoll.IsRagdolled = true;
RefreshLayout();
}
if (Input.GetKeyDown(KeyCode.Q))
{
if (_ragdoll.IsRagdolled)
{
_ragdoll.IsConnected = false;
_ragdoll.IsRagdolled = false;
}
else
{
_ragdoll.IsRagdolled = true;
_ragdoll.IsConnected = true;
_connectionTime = Time.time;
}
RefreshLayout();
}
}

public void RefreshLayout()
{
drawText =
@"Q - Convert to/from Ragdoll+Connected
1 - Connected = false
2 - Connected = true
3 - IsRagdoll = false
4 - IsRagdoll = true
ConnectedToSkeleton == " + _ragdoll.IsConnected.ToString() + @"
IsRagdolled == " + _ragdoll.IsRagdolled.ToString();
}

static string drawText = null;

void OnGUI()
{
GUI.Label(new Rect(10, 10, 2000, 2000), drawText);
}
}
}
« Last Edit: October 22, 2019, 06:34:45 PM by djaydino »

djaydino

  • Administrator
  • Hero Member
  • *****
  • Posts: 7615
    • jinxtergames
Re: Simulate key press with Playmaker
« Reply #9 on: October 22, 2019, 06:36:13 PM »
Hi.
I have wraped you code (use the # on the icons above the text editor)

have you tried using Set Properties?

RICK

  • Playmaker Newbie
  • *
  • Posts: 39
Re: Simulate key press with Playmaker
« Reply #10 on: October 22, 2019, 09:42:25 PM »
Yes I have tried set property. Sorry to sound dumb but I don't know what you mean
by "I have wraped you code (use the # on the icons above the text editor) "

Thanks,

Rick C

Broken Stylus

  • Beta Group
  • Hero Member
  • *
  • Posts: 772
Re: Simulate key press with Playmaker
« Reply #11 on: October 25, 2019, 06:11:04 AM »
Here is the script





Code: [Select]
System;
using System.Linq;
using BzKovSoft.ActiveRagdoll;
using UnityEngine;

namespace BzKovSoft.ActiveRagdollSamples
{
public class BzThirdPersonActiveRagdoll : MonoBehaviour
{
readonly int _animatorVelocityX = Animator.StringToHash("VelocityX");
readonly int _animatorVelocityY = Animator.StringToHash("VelocityY");

Animator _animator;
IBzRagdoll _ragdoll;
IBzBalancer _balancer;
float _connectionTime;

void OnEnable()
{
_animator = GetComponent<Animator>();
_ragdoll = GetComponent<IBzRagdoll>();
_balancer = GetComponent<IBzBalancer>();

if (_balancer == null)
throw new InvalidOperationException("No balancer defined on the character");

RefreshLayout();
}

private void Update()
{
ProcessKeyPressings();

float x = Input.GetAxis("Horizontal");
float y = Input.GetAxis("Vertical");

if (Input.GetMouseButton(1))
{
x = 0;
y = 0;
}

if (_ragdoll.IsConnected)
{
Vector3 balVel = _balancer.BalanceVelocity;
float magnitude = balVel.magnitude;
if (magnitude > 1.5f & _connectionTime + 2f < Time.time)
{
_ragdoll.IsConnected = false;
RefreshLayout();
return;
}

balVel *= 2f;

if (magnitude > 0.1f)
{
balVel = transform.InverseTransformDirection(balVel);
x += balVel.x;
y += balVel.z;
}
}

// update the animator parameters
//_animator.SetFloat(_animatorVelocityX, x, 0.2f, Time.deltaTime);
//_animator.SetFloat(_animatorVelocityY, y, 0.2f, Time.deltaTime);
}

private void ProcessKeyPressings()
{
if (Input.GetKeyDown(KeyCode.Keypad1) | Input.GetKeyDown(KeyCode.Alpha1))
{
_ragdoll.IsConnected = false;
RefreshLayout();
}
if (Input.GetKeyDown(KeyCode.Keypad2) | Input.GetKeyDown(KeyCode.Alpha2))
{
_ragdoll.IsConnected = true;
_connectionTime = Time.time;
RefreshLayout();
}
if (Input.GetKeyDown(KeyCode.Keypad3) | Input.GetKeyDown(KeyCode.Alpha3))
{
_ragdoll.IsRagdolled = false;
RefreshLayout();
}
if (Input.GetKeyDown(KeyCode.Keypad4) | Input.GetKeyDown(KeyCode.Alpha4))
{
_ragdoll.IsRagdolled = true;
RefreshLayout();
}
if (Input.GetKeyDown(KeyCode.Q))
{
if (_ragdoll.IsRagdolled)
{
_ragdoll.IsConnected = false;
_ragdoll.IsRagdolled = false;
}
else
{
_ragdoll.IsRagdolled = true;
_ragdoll.IsConnected = true;
_connectionTime = Time.time;
}
RefreshLayout();
}
}

public void RefreshLayout()
{
drawText =
@"Q - Convert to/from Ragdoll+Connected
1 - Connected = false
2 - Connected = true
3 - IsRagdoll = false
4 - IsRagdoll = true
ConnectedToSkeleton == " + _ragdoll.IsConnected.ToString() + @"
IsRagdolled == " + _ragdoll.IsRagdolled.ToString();
}

static string drawText = null;

void OnGUI()
{
GUI.Label(new Rect(10, 10, 2000, 2000), drawText);
}
}
}

I kinda see. The author declares this:

IBzRagdoll _ragdoll;

Likely an Interface, so that's defined elsewhere (he "Uses" BzKovSoft.ActiveRagdoll).
Then throughout this script you quoted, it allows you the change the value of this bool by pressing keys.
For example, in his method ProcessKeyPressings(), he checks for Keypad1 or Alpha1. I guess the latter is left to the dev's discretion and his a key you can bind?

So, you want to be able to send these key inputs, but through Playmaker?

I suppose four or five little actions could be produced. For example, one that would do:

_ragdoll.IsConnected = false;
RefreshLayout();

This one would set the "IsConnected" state to false.

I guess all these micro-actions could be fused into a bigger one and having a dropdown menu (a local enum) to provide a choice among the four listed ones.

"Q - Convert to/from Ragdoll+Connected" seems to toggle between R+C and !R+C.
Maybe that one would need a separate mini-action, since it's a toggle.

I also see "_connectionTime = Time.time" too. I'd guess it returns the time (in a float) that was needed to establish the ragdoll connection.
So the action would also need to have a field that returns a float value you could save in a FsmFloat.