playMaker

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Topics - Thore

Pages: [1] 2
1
Share New Actions / Button + Direction (Get Button Down And Axis)
« on: October 14, 2018, 03:33:45 PM »
You look for a simple way for Button+Direction input? Here's my version.

GetButtonDownAndAxis.cs
When a Button is pressed, sends an event based on current axis direction, i.e. up+button, left+button. Useful for fighting games, combos etc. If you only want to use one direction (say, only up+button), simply leave the other direction blank.

All my actions are now also on Github.

2
Share New Actions / Set Distance Joint 2d
« on: October 05, 2018, 05:32:53 AM »
Hello,

Set Distance Joint 2d Properties
Not much to explain: I recreated the entire Distance Joint component panel as it is, and threw in the "enable" of the entire component for good measure (something I wish all component related actions had).

This one gave me a few headaches in the way FSMs handle a second gameObject. I think that's the correct method (/worksforme), but I am not totally sure. I threw in a few things from Jean's hinge joint script I don't quite understand (the private T part), I recommend that Jean or someone else looks over it to see if something is odd. Also, I didn't know what's the standard for floats with "infinity", so I made a boolean that allows to set this. Feel free to improve it to conform to Fsm standards.

I still don't have GitHub. As always, this action is free to use, upload to ecosystem (but please check), free to modify, adapt, adjust, improve as is anyway stipulated in the forum rules). :)

3
Feature Requests / On Awake Mimic
« on: October 04, 2018, 07:51:56 AM »
Hello,

Maybe there is already a way to do this. I look for a good, elegant and robust way to initialize FSMs, to set them up before they can be interrupted by incoming events. Ideal would be an AWAKE global transition that is called on awake, and before START. Another way would be a fake Awake Mimic. It would also be added as a global transition, but would priotize the actions in its state, and only opens the global event transitions once it's done (or perhaps a closing global event is called, similar to Finish();

If there's already a good method that doesn't involve spaghetti, null-check loops etc all over the place etc, or wait-actions and hoping for the best, please let me know :)

4
Share New Actions / Movement Controller: Axis to Velocity 2D
« on: September 28, 2018, 05:53:00 PM »
I made two actions for myself, I thought I might as well share, too. There are also two test scenes to show you what's different to the other versions that exist.

What it does
Gets the axis, W/A/S/D, arrow keys, controller stick (as specified in Input Manager), and uses it to set velocity, with features you probably need, sending event based on direction, and more.

Use Case
The combination of getting the axis, storing various floats to then power animator and velocity was very common in my setups. But I wouldn't have done an extra action wasn't it for a specific problem I encountered. Because SetVelocity2D always sets some value (including zero), it interferes with physics. You won't notice this most of the time, unless the actor is for example attached to joints. You can account for this, by stacking together other actions and using multiple states, but this does it all in one block (normally the purpose of actions is to keep them modular, but this pack is just very common, why not put it together).



Hence I made actions that not only combine those steps, but also have a setting for a neutral deadzone.

AxisToVelocity2D & AxisRawToVelocity2D
These are two action twins that work similar, but differ only that one uses Input.GetAxis and the other Input.GetAxisRaw. Here are the settings, explained:

Game Object
Must be an object that has a rigidbody2d, that will be affected.

Axis Name
As you name it in the Input Settings (Edit > Project Settings > Input), and is typically named "Horizontal" or "Vertical".

Axis Orientation
Here you can set which velocity axis (Y/vertical or X/horizontal) you want to affect. This will typically match your axis name.

Store Axis Abs
This is a neat option to store the current axis value as an absolute, which you typically then feed to the animator (as set animator float), to drive the animations.

Multiplier
The build-in multiplier (as in GetAxis action) is used to amplify the axis value and is effecticely a kind of max speed value (e.g. the axis gives you +1, so with multiplier 5, the max velocity can be 5).

HasNeutral / Deadzone
When set, the neutral axis position will not update velocity, allowing it to be affected by physics objects, like free-wheeling. This interestingly also leads to a kind of momentum/inertia effect with the right rigidbody settings. See the effect in the scenes.

Both actions use an identical principle. Since the neutral axis position (i.e. stick in the middle) in the Raw version is 0, it's simply a bool with nothing to configure. The standard version has a smooth ramp, and here you can set which values are considered as a deadzone. It's simply mirrored (i.e. "0.5" goes from -0.5 to 0.5).

Event Button
When set, simply fires off an event (thus leaving the state) when the axis is either negative or positive (called Positive Button and Negative Button in the Input Settings). The usual purpose is to go into a different state to flip the sprite around.

Every Frame
What it says on the tin.


Updated:
Now also with world/local space. ;)

5
Share New Actions / Get Axis to Button Down
« on: September 27, 2018, 04:07:26 PM »
I may be bad at finding actions I need. This one must exist already, and if not, now it does. :)

GetAxisToButtonDown.cs
Take the axis you provide, and treat the directions as buttons ("Negative Button" and "Positive Button", and also the alternatives as listed in Input Manager). To do this right now, you would get the axis, store it into a variable, and then feed it into a float compare. This makes it in one go.



Explanation for Beginners
It's recommended to use the Input Manager (Edit > Project Settings > Input) to map the player input from mouse, controller, keyboards etcetera.

Use Case
Suppose you want up for jumping, and down for crouching, hence you want to treat the input axis direction as if they were buttons (e.g. as they were in old gamepads).

Note
Uses the snappier GetAxisRaw function, which means, there is no ramp up (also see my GetAxisRaw action). That's a bit of taste, or Game Feel. You can change this by simply replacing "GetAxisRaw" with "GetAxis" in the code. It can also store whether the buttons were pressed, but I have out-commented that functionality, as I don't really see a purpose. If you want to add it back in, just open the code and uncomment it (it's easy for beginners, too). I also have a more advanced similar action I need to revise (on request, otherwise when I get to it), that has settings for stick deadzone and threshold. 

6
Playmaker Help / Scripting // strange Velocity behaviour
« on: September 27, 2018, 06:17:01 AM »
Hello,

I am attempting an AddExplosionForce2D, but it shows some strange behaviour. Can somebody with scripting knowledge give me an idea what might be the issue?

Code: [Select]
// (c) Copyright HutongGames, LLC 2010-2018. All rights reserved.
// Made by Thore: change anything you like, but if you do, you must stroll in a nearby park.

using UnityEngine;

namespace HutongGames.PlayMaker.Actions
{
    [ActionCategory(ActionCategory.Physics2D)]
    [Tooltip("Adds velocity to targets based on direction to explosive. Useful to create a blast effect.")]
    public class AddExplosionForce2D : ComponentAction<Rigidbody2D>
    {

        // BASE VARIABLES
        [RequiredField]
        [Tooltip("GameObject from where the force is coming from.")]
        public FsmOwnerDefault explosive;

        [RequiredField]
        [CheckForComponent(typeof(Rigidbody2D))]
        [Tooltip("To blow up, must have a Rigidbody2D attached.")]
        public FsmOwnerDefault target;

        [RequiredField]
        [Tooltip("The power of the sideways blast (uses velocity).")]
        public FsmFloat blast;
       
        [RequiredField]
        [Tooltip("Adds additional velocity.y force up.")]
        public FsmFloat blowup;

        private float direction;
         private Vector2 velocity;

        [Tooltip("Repeat every frame. Are you sure?")]
        public bool everyFrame;

        private Rigidbody2D rb;

        // STANDARD METHODS

        public override void Reset()
        {
            explosive = null;
            target = null;
            everyFrame = false;
            blast = null;
            blowup = null;
            direction = 0f;
            velocity = Vector3.zero;


        }

        public override void OnEnter()
        {
            BlastAway();

            if (!everyFrame)
            {
                Finish();
            }
        }

        public override void Awake()
        {
            Fsm.HandleFixedUpdate = true;
        }

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


        ///  BOOM! ///////////////////////////////////////////

        void BlastAway()
        {

           



            // Get Direction
            var posExplosive = Fsm.GetOwnerDefaultTarget(explosive).transform.position;
            var posTarget = Fsm.GetOwnerDefaultTarget(target).transform.position;

            direction = Mathf.Abs(posTarget.x) - Mathf.Abs(posExplosive.x);

            var isTargetRight = direction < 0;

            Debug.Log("Target is Right? " + isTargetRight);

            // Get Rigidbody2D
 

            var to = Fsm.GetOwnerDefaultTarget(target);
            rb = to.GetComponent<Rigidbody2D>();

            if (!UpdateCache(to)) // no idea what this does, but found it in official action.
            {
                return;
            }


            // Blast Away


            if (isTargetRight)
            {
                velocity.y = blast.Value + blowup.Value;
                velocity.x = 5;
                rb.velocity = velocity;

            }

           else
            {
                velocity.y = blast.Value + blowup.Value;
                velocity.x = -5; // Bug is here.  Once this is active, the object's vector seems to flip, and keeps orientation, resulting in hopping back and forth.
                rb.velocity = velocity;
               
            }



        } // END BlastAway



    } // END Class



} // END Namespace

I now hardcoded the 5/-5 values in there, to be clear what is going on (that's later a variable). The bug is likely in 121.

What it's supposed to do
When the target is left of explosive, blast it to the left, and when the target is right, blast it to the right direction. The direction itself isn't the issue (I made a custom action which works).

What it does wrongly
As long as I comment out the blast part, the direction is shown correctly (in log). It should therefore plug in -5 when the target is one direction, and +5 when it is in the other direction. However, when the target is to the right side, it strangely alternates directions with each blast. I can only assume that the velocity vector is somehow flipped and this orientation is not reset, but I am clutching straws.

Test Scene
I added a test scene with the action attached below.

7
Share New Actions / GetRelativeDirection2D
« on: September 26, 2018, 02:05:35 PM »
While learning to code some more, I wanted to do an AddExplosion2D version and ended up making a more generalized action that may be useful. I am almost certain something like this exists, but didn't find it.

GetRelativeDirection2DEvent
You provide an origin GameObject, and a target. It calculates the direction and distance, as X and Y separated. When the target is left or down from origin, it returns the distances as negative numbers.

Note, there is also GetDistance (in Ecosystem at least), which tells you the direction in a straight line from origin to target.



Store Directions: stores the float values for later use. Note that left and down return negative values. When you don't want this, use Float Abs in a later step. Though consider if this is the right action for you.

Store isRight & isUp: convenient bools to use later. E.g. with Bool Test when isUp is false, you know the target is downwards.

Every Frame: what it says on the tin. As is standard, will ignore events. I have made a twin action (GetRelativeDirection2D) that doens't have the events, which you may prefer.

Preference: Allows you to set how to "interpret" the data. Also see my graphic attached.
  • Match Best
    'Common Sense' view, which is in mathematical terms the distance that is furthest away and thus "clearest", i.e. if the target is more up than left, then consider it upwards.
  • Horizontal/Vertical Only
    Only considers one axis.
  • Short Axis
    The opposite from Match Best. Best explained with a use case. Take an arcade shooter like Space Invaders. The enemies might be considered best as "upwards", but to shoot them, you want to move either a bit to the right or left, i.e. along the shorter distance axis.
  • Inverted
    Inverted version from Match Best. Makes intuitive sense to think of the roles reversed, i.e. not the target is upwards from origin, but origin is downwards from target.

As Usual
I'm not a coder, it may or may not be the best way to do this. However, it does the trick nicely. There's an alternative method out-commented to also allow to switch local/world space, which I adapted from another action. However, that didn't make sense to me, so I didn't use it.

If someone wants to improve on it, make more actions based on this, test it, and upload it to Ecosystem, feel free! :)

8
Share New Actions / Set Rigidbody2D BodyType & Simulated
« on: September 25, 2018, 01:15:35 PM »
SetRigidBodyType2D
The action allows you to change the body type and simulated parameters in a Rigidbody 2D (I was surprised that no acion exists, or I overlooked it).

Purpose
I needed the action because I have physics objects in the scene that are tempoarily bound to the character, for which these parameters need to be changed temporarily. But it's probably an esoteric need.

Small Caveat
In a perfect action, the body type drop down's default would be "don't change". However, it's populated by Unity enums and I don't know how to add a nice extra option in there. However, that's cosmetics.

My simple workaround is a bool that asks if you want to leave body type alone, and only change the simulated property (which was what I needed in the end). Perhaps a more elegant way would be to split the action into two, for each separate setting.

I also read in documentation that these changes are best in FixedUpdate. But when I plug them there, they show no effect. It's now a standard OnEnter affair, and works.

As Usual
Anyone can of course use this and modify it. Someone with access can also upload it to Ecosystem, too (though beware, I am not a coder, please doublecheck). ;)

9
Share New Actions / SetParent Canvas Issue (and alternative action)
« on: September 22, 2018, 02:14:21 PM »
Hello,

When using "Set Parent" on objects within the canvas, Unity will throw the error notification shown below. It still lets you play, but there are scaling issues.

Code: [Select]
Parent of RectTransform is being set with parent property. Consider using the SetParent method instead, with the worldPositionStays argument set to false. This will retain local orientation and scale rather than world orientation and scale, which can prevent common UI scaling issues.
UnityEngine.Transform:set_parent(Transform)
HutongGames.PlayMaker.Actions.SetParent:OnEnter() (at Assets/PlayMaker/Actions/GameObject/SetParent.cs:38)
HutongGames.PlayMaker.FsmState:ActivateActions(Int32) (at C:/Projects/Playmaker_1.9.0/Projects/Playmaker.source.unity/Assets/PlayMaker/Classes/FsmState.cs:205)
HutongGames.PlayMaker.FsmState:OnEnter() (at C:/Projects/Playmaker_1.9.0/Projects/Playmaker.source.unity/Assets/PlayMaker/Classes/FsmState.cs:175)
HutongGames.PlayMaker.Fsm:EnterState(FsmState) (at C:/Projects/Playmaker_1.9.0/Projects/Playmaker.source.unity/Assets/PlayMaker/Classes/Fsm.cs:2767)
HutongGames.PlayMaker.Fsm:SwitchState(FsmState) (at C:/Projects/Playmaker_1.9.0/Projects/Playmaker.source.unity/Assets/PlayMaker/Classes/Fsm.cs:2714)
HutongGames.PlayMaker.Fsm:UpdateStateChanges() (at C:/Projects/Playmaker_1.9.0/Projects/Playmaker.source.unity/Assets/PlayMaker/Classes/Fsm.cs:2642)
HutongGames.PlayMaker.Fsm:Start() (at C:/Projects/Playmaker_1.9.0/Projects/Playmaker.source.unity/Assets/PlayMaker/Classes/Fsm.cs:1925)
PlayMakerFSM:Start() (at C:/Projects/Playmaker_1.9.0/Projects/Playmaker.source.unity/Assets/PlayMaker/PlayMakerFSM.cs:548)

Though I have no idea what I am doing, I somehow created an action using the suggested SetParent method which works and doesn't throw errors. I named it SetParent3 (there is already a second one in Ecosystem).

This action will do the (basic) trick, however, it currently has no other parameters (I have no clue how/what). If a regular wants to complete it, and upload it to ecosystem, you're super welcome. It would be best, I guess, when the default "Set Parent" works universally.

Cheers.
 




10
Share New Actions / ColorMix
« on: September 20, 2018, 03:56:06 PM »
Humble beginnings, part three. I made another tiny action.

ColorMix
You provide two colors, and a mix value (0.5 is 50% of each), and it returns you the resulting color, which you can store and use from there.

Use Case
You can tint sprites using the color field in the inspector. This action makes it possible for example to tint "just a bit" towards a second color, which is particularily useful when sprites use different tints, or when you want to change the amount of tint based on some gameplay parameter, e.g. health bar changing color based on HP left.

Tip: Use FloatRemap (Ecosystem) to convert any range to [0-1], which you can then feed as mix value.


11
Playmaker Help / SetEventData + Enum?
« on: September 19, 2018, 09:47:28 AM »
Hello,

I'd like to use SetEventData, which has all sorts of variable types in it, except for the enum. The critical part of the action is in the method, where all available types are listed.

Code: [Select]
               Fsm.EventData.BoolData = setBoolData.Value;
Fsm.EventData.IntData = setIntData.Value;
Fsm.EventData.FloatData = setFloatData.Value;
Fsm.EventData.Vector2Data = setVector2Data.Value;
Fsm.EventData.Vector3Data = setVector3Data.Value;
Fsm.EventData.StringData = setStringData.Value;
Fsm.EventData.GameObjectData = setGameObjectData.Value;
Fsm.EventData.RectData = setRectData.Value;
Fsm.EventData.QuaternionData = setQuaternionData.Value;
Fsm.EventData.ColorData = setColorData.Value;
Fsm.EventData.MaterialData = setMaterialData.Value;
Fsm.EventData.TextureData = setTextureData.Value;
Fsm.EventData.ObjectData = setObjectData.Value;

Fsm.EventData.EnumData is unknown, and I don't know how to declare enums in the fsm script. I'm aware that I can convert enums to something else, and then pass this on, but I'd like to keep things tidy and neat, if possible.

Can anyone help me with a bit of code that adds Fsm.EventData.EnumData to the Fsm script?








12
Share New Actions / Sprite / SetOrderInLayer
« on: September 06, 2018, 04:38:13 PM »
SetOrderInLayer.cs
Gets the SpriteRenderer of suitable GameObject, and sets the "Order in Layer" property to an integer you provide.

Purpose
In 2D games with a camera set to orthographic projection, the Z axis is ignored. The layers are used to roughly sort what is background, foreground etc. But within those layers, you use order in layer to determine what is in front of something else. With this action, you can change that order.

Example
In my case, a character carries a weapon on their back. When the weapon is drawn, it needs to change order in layer so it's drawn in front of the character.

13
Share New Actions / GetAxisRaw (Tighter, Snappier Input)
« on: August 29, 2018, 02:32:19 AM »
Hello :)

UPDATED: made an exact mirror version of GetAxis for GetAxisRaw, and the functionality below is now dubbed GetAxisRawSwitch. That seems cleaner and better.

You feel that the movement of your character could be "snappier" or "tighter", especially for a platformer? Then you want to try out this action.

What it does.
The action is identical to GetAxis, but gets the GetAxisRaw value instead. This value is not smoothed out, and makes for "snappy" input. GetAxisRawSwitch has a checkbox to switch between GetAxis and GetAxisRaw, also at runtime. This also gives you the ability to try out the difference as you play, which is good for prototyping.

A little bit of explanation
The typical way, Input.GetAxis gets the input from the player in a smooth way: assuming a controller with an analog stick, the axis value is smoothly cranked up to to 1 when you push right (-1 when left). Now, there is a twin called Input.GetAxisRaw, which does not smooth out the input. It's either hard left (-1) or hard right (1), with gives a snappier and tighter control, which might be more suitable for your game. You can also use the raw to calculate your own smoothing (see Unity's documentation linked to above, or e.g. Ease Float action).

14
General Discussion / Tutorial: Custom Scripting 101
« on: October 07, 2017, 11:01:53 AM »
Hi,

I came across this small video series and found it super useful. It goes over stuff that is probably second nature to coders, but for us Playmaker people often quite obscure, especially when you transition to some light coding and custom actions yourself. Enjoy.

http://www.youtube.com/playlist?list=PL5KbKbJ6Gf9_H4MZC1v6ETs_ifnLfNJVw

15
Playmaker Help / How to: FSM to FSM Communication
« on: October 02, 2017, 02:23:37 PM »
Hi,

Despite that I have built quite a lot of mechanics with Playmaker already, I still feel unsure about the FSM to FSM commuication, which is an increasingly common challenge.

For example, creating a new object and passing variables to it. What's the best way to go about it? Are Send Events always fast enough to ensure the variables are set in Start state? Or should you create the object, have Start run empty (or only do configuration that are self-contained), set variables, and then trigger a global event to really set it into motion?

Another example: When a projectile hits a target: what's the best way to do this? Is it better for the Health FSM to be hit, then get projectile information, or is it better that the projectile hits an object, and passes its variables onto the object? Or some combination thereof?

Are there any good tricks that make communication between FSMs less complicated? A rule of thumb or something of the sort?

I also ask because I've seen many different tutorials and even more ways how this can be done, but none stick out as clearly superior. Any pointers, and reasons?


Pages: [1] 2