Playmaker Forum

PlayMaker Updates & Downloads => Share New Actions => Topic started by: collidernyc on July 05, 2014, 06:25:05 PM

Title: Swap Single Sprite
Post by: collidernyc on July 05, 2014, 06:25:05 PM
Very simple Sprite switch. Useful for home made buttons, swapping that sword for the rail gun, dressing your macho hero up in that brand new skull helmet with the cute pink bow etc....

Make sure you have a 2D Sprite Renderer attached to your object. Choose your new sprite.

Besides the simplicity, this differs from Jeans awesome Play Sprites Animation by the fact that you can call it from a touch began/touch ended and it always calls finished()  - you can click/touch quickly and always get to the next state. Jean's needs to finish the animation before finished() - not good for quick touches (your finger might have already moved before the animation is done so touch ended never gets called). There's probably a way to interrupt this in the Play Sprites Animation code, but I like having the stripped down simplicity of this one.

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

using UnityEngine;
using System.Collections;


namespace HutongGames.PlayMaker.Actions
{
[ActionCategory(ActionCategory.Animation)]
[Tooltip("Replaces a single Sprite on any GameObject. Object must have a Sprite Renderer.")]
public class SwapSingleSprite : FsmStateAction
{

[RequiredField]
[CheckForComponent(typeof(SpriteRenderer))]
public FsmOwnerDefault gameObject;

public Sprite spriteToSwap;

private SpriteRenderer spriteRenderer;

public override void Reset()
{
gameObject = null;

spriteToSwap = new Sprite();
}

public override void OnEnter()
{
GameObject go = Fsm.GetOwnerDefaultTarget(gameObject);
if (go == null) return;

spriteRenderer = go.GetComponent<SpriteRenderer>();

if (spriteRenderer == null)
{
LogError("SwapSingleSprite: Missing SpriteRenderer!");
return;
}

SwapSprites();

Finish();
}

void SwapSprites()
{
spriteRenderer.sprite = spriteToSwap;
}

}
}
Title: Re: Swap Single Sprite
Post by: jeanfabre on July 07, 2014, 11:26:14 AM
Hi,

 That makes perfect sense. Thanks. I have added it to ecosystem. You already spotted the commenting "//--- __ECO__ __ACTION__" which is key for the ecosystem to find this action, thanks :)

I modified the class name to "SwapSprite", I don't think "single is adding to the comprehension of what it does, and I added a "ResetOnExit" option so that you can easily toggle without reference the original sprite by just leaving the state, very useful for user interactions. I also declared a "Sprite" category, as it seems more appropriate than using the Animation category.

 Bye,

 Jean

btw: Your showreel is really impressive!
Title: Re: Swap Single Sprite
Post by: collidernyc on July 07, 2014, 07:01:22 PM
Thanks Jean - all good changes. I had thought about making a Sprite category, but didn't know if it was cool to just add new ones like that - thanks!

My reel is ancient by now, but thanks. I've been so busy the last few years I haven't updated it. And now when I have a bit of free time I'd rather make a game than work on my website or reel... Which is too bad, as we've been doing some pretty cool projects :)
Title: Re: Swap Single Sprite
Post by: TheBadFeeling on September 21, 2014, 09:30:17 AM
This action is just what I needed. Thanks a lot!  :)
Title: Re: Swap Single Sprite
Post by: nrhyde on October 20, 2014, 04:46:40 AM
Please provide more information about how to use this script. 

How do I add this script to playmaker?  I used Create Script, pasted the script text in and saved it, and dragged it to one of my gameobjects.  In the inspector there's an error message under the script component: The associated script cannot be loaded. Please fix any compile errors and assign a valid script.

How do I add this script to an FSM?  I assume I would use Send Message, but what message name should I use? SwapSingleSprite?  How do I specify the new sprite I want to use? With a variable of type texture?
Title: Re: Swap Single Sprite
Post by: Lane on October 20, 2014, 07:18:19 AM
Please provide more information about how to use this script.

Download this, then drag it anywhere into your Project Hierarchy.

Add the action via the action browser per usual.
Title: Re: Swap Single Sprite
Post by: jeanfabre on October 20, 2014, 07:24:30 AM
Hi,

 it's also on the EcoSystem browser (https://hutonggames.fogbugz.com/default.asp?W1181) which allow you to search fo custom actions and download them directly in your project in one click.

 Bye,

 Jean
Title: Re: Swap Single Sprite
Post by: nrhyde on October 20, 2014, 10:32:22 AM
Thanks.  I used the ecosystem browser that worked. 

New question:  I want to pull the image that is swapped from an array of textures.  However, the variable pull-down menu does not show any options, even though I have variables of type texture, Object UnityEngine.Texture2D, and Object UnityEngine.SpriteRenderer.  Is there any way to do this? 
Title: Re: Swap Single Sprite
Post by: collidernyc on October 20, 2014, 10:54:28 AM
Hi @nrhyde... I've had to put this away for a bit while I finish a job, so I can't give you a specific answer. But thinking about this quickly, you would first get the sprite from your array, then run swap sprite on it. I'm sure someone here can be more specific, but the general idea is to store the sprite from the array in a Sprite variable, then run SwapSprite on that variable. Does that make sense? I can't remember if that's easy to do in Playmaker, but I think it is...

And thanks @TheBadFeeling :)
Title: Re: Swap Single Sprite
Post by: nrhyde on October 20, 2014, 02:56:23 PM
Actually, there isn't a variable pull-down list for the Sprite to Swap field.  The pull-down I was looking at was for the Reset on Exit field, and only accepts a Bool. 

So it looks like the only option is to have a separate state for each of the possible images and drag them to the field manually. 

Or could someone modify the Swap Single Sprite code so that it accepts variables?  If so, what type of variable would it be?  A texture or an object UnityEngine.Texture2D?

Thanks!  Even if I can't use a variable, the Swap Single Sprite is a cool action to have.
Title: Re: Swap Single Sprite
Post by: nikosurfing on October 20, 2014, 06:41:21 PM
I ask the same question about it and i tried to reach the author on email.
Yes i do agree with @nrhyde, it would be nice if someone here can modify this action to accepts variable texture, maybe @jean can help us?
Title: Re: Swap Single Sprite
Post by: jeanfabre on October 21, 2014, 04:28:48 AM
Hi,

 yeah, it should be given the option to define a variable, Come back to me next week if nothing come up from other people, and I'll update the action ( likely create a new one actually to not break existing projects).

 Bye,

 Jean
Title: Re: Swap Single Sprite
Post by: djaydino on December 01, 2014, 03:24:56 AM
hi i have been trying to get it to work with a variable, but failing so far

there is not fsmSprite so it has to be done differently.

i have been trying with fsmGameobject but getting errors
Title: Re: Swap Single Sprite
Post by: djaydino on December 01, 2014, 08:25:57 AM
i think i got this to work now AND should not break please test and confirm so i can change it on the EcoSystem :

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

using UnityEngine;
using System.Collections;


namespace HutongGames.PlayMaker.Actions
{
[ActionCategory("sprite")]
[Tooltip("Replaces a single Sprite on any GameObject. Object must have a Sprite Renderer.")]
public class SwapSprite : FsmStateAction
{

[RequiredField]
[CheckForComponent(typeof(SpriteRenderer))]
public FsmOwnerDefault gameObject;
[ObjectType(typeof(Sprite))]
public FsmObject spriteToSwap;

public FsmBool resetOnExit;

private SpriteRenderer spriteRenderer;

Sprite _orig;

public override void Reset()
{
gameObject = null;
resetOnExit = false;

spriteToSwap = new Sprite();
}

public override void OnEnter()
{
GameObject go = Fsm.GetOwnerDefaultTarget(gameObject);
if (go == null) return;

spriteRenderer = go.GetComponent<SpriteRenderer>();

if (spriteRenderer == null)
{
LogError("SwapSingleSprite: Missing SpriteRenderer!");
return;
}

_orig = spriteRenderer.sprite;

SwapSprites();

Finish();
}

public override void OnExit()
{
if (resetOnExit.Value)
{
spriteRenderer.sprite = _orig;
}
}
void SwapSprites()
{
spriteRenderer.sprite = spriteToSwap.Value as Sprite;
}



}
}
Title: Re: Swap Single Sprite
Post by: jeanfabre on December 02, 2014, 11:39:38 AM
Hi,

 thanks for this. I found several issues that I reported to Alex, so I would wait until the release of this action because:

-- if you click on the selector, the list proposed contains junk, not just sprites, so that will lead to confusion.

-- on the up coming beta version, FsmObject do not get created properly if you create a variable right from the action interface.

 Bye,

 Jean
Title: Re: Swap Single Sprite[SOLVED]
Post by: djaydino on December 03, 2014, 11:38:37 AM
Hi,

i pm-ed Alex to also get access to the beta version.

what junk are you getting?
I want to test this.
as i'm trying to reproduce this

Greetings,

Dino
Title: Re: Swap Single Sprite
Post by: jeanfabre on December 08, 2014, 03:43:49 AM
Hi,

It's ok actually. It's within the beta that we found an issue when using an FsmObject, selecting a content for a FsmObject in the Unity Asset Browser was returning everything, but now that we found the problem, it wasn't related to your action per say.

 Bye,

 Jean
Title: Re: Swap Single Sprite
Post by: djaydino on December 09, 2014, 04:17:57 AM
Ok, i will update this on github then :)
Title: Re: Swap Single Sprite
Post by: dharry on July 09, 2015, 10:04:36 PM
Hi Guys,

Not sure if you can help, i'm still learning Unity and Playmaker but I have a PSM that is meant to swap a sprite when a user enteres a trigger, I can see the FSM fire off and the Swap Sprite action fire but my sprite doesn't change...

Is there anything special I need to do to get this to work?

I'm making a pacman type clone so the trigger is when the player enters big dot and it's supposed to swap the enemy sprite.

Cheers
Dean
Title: Re: Swap Single Sprite
Post by: djaydino on July 10, 2015, 05:35:47 AM
Hi,
what version is your playmaker?

be sure to check that your image is a sprite and not texture2d.
Title: Re: Swap Single Sprite
Post by: dharry on July 10, 2015, 05:42:01 AM
Hi Dino,

Version 1.7.8.3 (latest version) and the 2 sprites are Sprite (2D and UI). The sprites are just from an image I created in Photoshop and imported so I think they are ok... I'm still learning a lot :)

Regards,
Dean
Title: Re: Swap Single Sprite
Post by: djaydino on July 10, 2015, 10:51:54 AM
hmm, strange...

can you make some picture or video with the actions?
Title: Re: Swap Single Sprite
Post by: dharry on July 10, 2015, 08:08:22 PM
Hi Dino,

Sure thing... here's how it looks...

This is the first time iv'e worked with sprites so maybe I have done something wrong with them?

Dean

Title: Re: Swap Single Sprite
Post by: djaydino on July 11, 2015, 04:59:33 AM
is there also a swap sprite in the 1st state (entered trigger)
if so you need to use on trigger exit in the 2nd state.
Title: Re: Swap Single Sprite
Post by: dharry on July 11, 2015, 05:16:08 AM
Hi Dino,

No, the first state is simply an Trigger 2D Event to capture the player trigger.

Dean
Title: Re: Swap Single Sprite
Post by: dharry on July 11, 2015, 05:31:45 AM
Hi Dino,

I think I almost have the problem, it's not the swap sprites script, I have an animation running on the original sprites that is still running after the swap. If I turn the Animator off they swap out fine...

Thanks for your help

Dean
Title: Re: Swap Single Sprite
Post by: Fat Pug Studio on July 16, 2018, 04:16:37 AM
Edit: Oh, the action's fixed in 2018, nevermind :D