playMaker

Author Topic: How do I get a component from within a PM script?  (Read 1180 times)

Red

  • Hero Member
  • *****
  • Posts: 563
    • View Profile
How do I get a component from within a PM script?
« on: March 22, 2015, 01:40:18 PM »
Here's the code that I'm stumped on... I'm trying to use this to apply velocity to the object this is on (while keeping it clamped within a certain zone that the user defines.)

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

namespace HutongGames.PlayMaker.Actions
{
[ActionCategory(ActionCategory.Character)]
[Tooltip("Simple movement of a character while constrained within a user-defined area.")]
public class ClampedMovement : FsmStateAction
{
public Rigidbody rb;
public enum AxisPlane
{
XZ,
XY,
YZ
}

[RequiredField]
[CheckForComponent(typeof(Rigidbody))]

[Tooltip("The GameObject to move.")]
public FsmOwnerDefault gameObject;

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

[RequiredField]
[Tooltip("The world plane that the 2d input is mapped onto.")]
public AxisPlane mappedToPlane;

[Tooltip("Lateral clamp minimum value.")]
public FsmFloat horizontalMin;

[Tooltip("Lateral clamp maximum value.")]
public FsmFloat horizontalMax;

[Tooltip("Vertical clamp minimum value.")]
public FsmFloat verticalMin;

[Tooltip("Vertical clamp maximum value.")]
public FsmFloat verticalMax;

public override void Reset()
{
gameObject = null;
moveVector = null;
mappedToPlane = AxisPlane.XZ;
horizontalMax = 0.0f;
horizontalMin = 0.0f;
verticalMax = 0.0f;
verticalMin = 0.0f;
}

public override void OnEnter()
{
rb = GetComponent<Rigidbody>(); // <-- Here is where the error is showing up in the console.
}

public override void OnFixedUpdate()
{
DoSetVelocity();
}

void DoSetVelocity()
{
var go = Fsm.GetOwnerDefaultTarget(gameObject);

rb.velocity = moveVector.Value;

switch (mappedToPlane)
{
case AxisPlane.XZ:
go.transform.position = new Vector3 (Mathf.Clamp(go.transform.position.x, horizontalMin.Value, horizontalMax.Value), go.transform.position.y, Mathf.Clamp(go.transform.position.z, verticalMin.Value, verticalMax.Value));
break;

case AxisPlane.XY:
go.transform.position = new Vector3 (Mathf.Clamp(go.transform.position.x, horizontalMin.Value, horizontalMax.Value), Mathf.Clamp(go.transform.position.y, verticalMin.Value, verticalMax.Value), go.transform.position.z);
break;

case AxisPlane.YZ:
go.transform.position = new Vector3 (go.transform.position.y, Mathf.Clamp(go.transform.position.y, horizontalMin.Value, horizontalMax.Value), Mathf.Clamp(go.transform.position.z, verticalMin.Value, verticalMax.Value));
break;
}

}
}
}

I know that offering a raw code dump like this might be a little intimidating but I think I've got the clamping mechanics down as that's not reporting any errors... I haven't been able to test it with a preview though since I'm coming up against an error at line 57.

What I'm hoping to do is just applying the velocity (I don't know if I have to add in a world-vs-self space thingamabob but for now I'm only working with it raw as is to see how it goes.)

I'm a bit stumped here. Anyone want to show me what I've got wrong? Is this some layer that I need to dig into since this is a PM action?

(edit: Wasn't sure if this would be more appropriate for Character or Physics in the category... That's a minor thing though.)
« Last Edit: March 22, 2015, 01:43:55 PM by Red »

Red

  • Hero Member
  • *****
  • Posts: 563
    • View Profile
Re: How do I get a component from within a PM script?
« Reply #1 on: March 22, 2015, 02:51:21 PM »
Checked (after a coffee-break) a couple other actions to see how they did their thing... I think I cracked this one... So, have at it. (I have to still finish this up by polishing it up but I tested it and this does work now.

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

namespace HutongGames.PlayMaker.Actions
{
[ActionCategory(ActionCategory.Character)]
[Tooltip("Simple movement of a character while constrained within a user-defined area.")]
public class ClampedMovement : FsmStateAction
{
private Rigidbody rb;
public enum AxisPlane
{
XZ,
XY,
YZ
}

[RequiredField]
[CheckForComponent(typeof(Rigidbody))]

[Tooltip("The GameObject to move.")]
public FsmOwnerDefault gameObject;

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

[RequiredField]
[Tooltip("The world plane that the 2d input is mapped onto.")]
public AxisPlane mappedToPlane;

[Tooltip("Lateral clamp minimum value.")]
public FsmFloat horizontalMin;

[Tooltip("Lateral clamp maximum value.")]
public FsmFloat horizontalMax;

[Tooltip("Vertical clamp minimum value.")]
public FsmFloat verticalMin;

[Tooltip("Vertical clamp maximum value.")]
public FsmFloat verticalMax;

public override void Reset()
{
gameObject = null;
moveVector = null;
mappedToPlane = AxisPlane.XZ;
horizontalMax = 0.0f;
horizontalMin = 0.0f;
verticalMax = 0.0f;
verticalMin = 0.0f;
}

public override void OnFixedUpdate()
{
DoSetVelocity();
}

void DoSetVelocity()
{
var go = Fsm.GetOwnerDefaultTarget(gameObject);
rb = go.GetComponent<Rigidbody>();
rb.velocity = moveVector.Value;

switch (mappedToPlane)
{
case AxisPlane.XZ:
go.transform.position = new Vector3 (Mathf.Clamp(go.transform.position.x, horizontalMin.Value, horizontalMax.Value), go.transform.position.y, Mathf.Clamp(go.transform.position.z, verticalMin.Value, verticalMax.Value));
break;

case AxisPlane.XY:
go.transform.position = new Vector3 (Mathf.Clamp(go.transform.position.x, horizontalMin.Value, horizontalMax.Value), Mathf.Clamp(go.transform.position.y, verticalMin.Value, verticalMax.Value), go.transform.position.z);
break;

case AxisPlane.YZ:
go.transform.position = new Vector3 (go.transform.position.y, Mathf.Clamp(go.transform.position.y, horizontalMin.Value, horizontalMax.Value), Mathf.Clamp(go.transform.position.z, verticalMin.Value, verticalMax.Value));
break;
}

}
}
}

I Think I'm going to have to keep in mind this kinda stuff though (and I have no idea if this is the most elegant way of doing it since this is my first time working with custom actions and also seriously working with C# as is.) But for the most part this is a start and possibly a final action.

I know I'll likely have to add in some redundancy and error-checking since I suspect if the values for the borders of the clamping are not filled in it'll cause errors... But at least it's a start.
« Last Edit: March 22, 2015, 02:52:57 PM by Red »