Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

SM2 - 2D made easy and efficient!

Discussion in 'iOS and tvOS' started by Brady, Nov 4, 2009.

  1. Schnelle

    Schnelle

    Joined:
    Jan 17, 2011
    Posts:
    89
    I do this for UI elements that have an on/off state. For example, a health heart that can be empty or full will have 2 frames in the default animation (found inside the Sprite Timeline window)

    //Health empty:
    packedSpriteComponent.SetCurrentFrameForAnimation(0, 0);

    //Health full:
    packedSpriteComponent.SetCurrentFrameForAnimation(0, 1);
     
  2. tvalleau

    tvalleau

    Joined:
    Jul 1, 2010
    Posts:
    108
    Hi. I'm still new to SM2, and while I've done a bunch of stuff with it, there seems to be something -very- fundamental I'm just not understanding here.

    In the game editor window, (NOT in code) I create an object (call it "mySprite") and add in a packed sprite component. Dress it all up, build atlases... everything is good so far.

    There it is on the screen.

    What I don't get is how to call the basic, built-in object methods on it.

    I have a script that I've attached to the mySprite object. It's got functions in it, and one of them is supposed to hide or show the sprite.

    That's the SM2 "obj.Hide(boolean)" call. I see it there in the docs. (or I see "Just call obj.Hide..." with some other name like "sprite.Hide()" or "yourSprite.Hide()" in the docs.

    Yes, I get that obj = sprite = yourSprite. I understand variables and object names. (I've actually been coding for a while now.) I just don't understand HOW to get that obj/sprite/yourSprite so I can use it.

    I've tried
    Code (csharp):
    1.  
    2.         var obj : GameObject = GameObject.Find(mySprite);      
    3.         obj.GetComponent(PackedSprite).Hide(false);
    4.  
    I thought would work, but that does nothing at all.

    So, obviously I was out sick on day two of kindergarten.

    What do I need, what exact code, to be able to call Hide(), or Delete() or Draw() or any of the hundreds of other SM2 calls....?

    In short, how do I get "obj." ?

    I'm sorry to be so dense, when this is so fundamental, and it's a minor miracle that I've made it as far as I have.

    Would someone take me by the hand, and explain this to me (or slap some sense into me) please?
     
  3. Brady

    Brady

    Joined:
    Sep 25, 2008
    Posts:
    2,474
    No problem. This is actually an important concept for Unity in general, so you'll find that this will help you in many ways far beyond SM2 as well. Even though this is a link to an EZ GUI thread, the concepts are exactly the same:

    http://forum.anbsoft.com/viewtopic.php?f=9&t=1408

    That thread should explain what you're after. If not, let me know.
     
  4. tvalleau

    tvalleau

    Joined:
    Jul 1, 2010
    Posts:
    108
    Yes! Of course! and Duh!

    OK: I feel silly.

    Thanks, Brady. (sheepish grin follows...)
     
  5. CoCoNutti

    CoCoNutti

    Joined:
    Nov 30, 2009
    Posts:
    513

    Hi Brady

    I just have a quick question about the examples you give in this link. For the code:
    Code (csharp):
    1.  
    2. var healthBar : UIProgressBar;
    3.  
    4. function Start()
    5. {
    6.    healthBar = GetComponent("UIProgressBar");
    7.  
    8.    // Now do something with it:
    9.    healthBar.Value = 1; // 100% health
    10. }
    11.  
    ... why can't you just use...

    Code (csharp):
    1.  
    2. healthBar.Value = 1;
    3.  
    ... i.e removing the GetComponent part... I thought by having it declared in the variable with var healthBar : UIProgressBar; you are already doing so?

    Sorry if this is a silly/noobish questions. Whilst my programming skills are improving, there are still fine details i need to learn.
    Cheers :)
     
  6. CoCoNutti

    CoCoNutti

    Joined:
    Nov 30, 2009
    Posts:
    513
    //double post sorry//
     
  7. Brady

    Brady

    Joined:
    Sep 25, 2008
    Posts:
    2,474
    You can do it that way as long as you populate that public reference by dragging it onto it in the inspector, and that is what is shown in the first example. Just declaring it public, however, isn't enough - you have to then populate it with the reference you want via the inspector. But the purpose of the second example was to show that if you don't want to use the inspector, you can do it programmatically using GetComponent().
     
  8. renman3000

    renman3000

    Joined:
    Nov 7, 2011
    Posts:
    6,697
    Hi Brady,
    I want to use PlayAnim() but I am told that PlayAnim() is not a member of Unity GameObject.


    How do I assign a packedSprite to be seen by Unity?
     
  9. Brady

    Brady

    Joined:
    Sep 25, 2008
    Posts:
    2,474
    See the thread I referenced above.
     
  10. renman3000

    renman3000

    Joined:
    Nov 7, 2011
    Posts:
    6,697
    HI Brady,
    I tried this...
    Code (csharp):
    1.  
    2.         var packedSpriteData = other.GetComponent(PackedSprite);
    3.         packedSpriteData.other.PlayAnim("animName");
    4.  
    but other, is "not a member of packed sprite"


    Sorry I know this seems trivial I would like an answer.
    Thanks
     
  11. Brady

    Brady

    Joined:
    Sep 25, 2008
    Posts:
    2,474
    You don't need ".other" in there. PlayAnim() is a member of PackedSprite (and therefore your "packedSpriteData" reference), but ".other" is your own variable/reference. The line should read:

    packedSpriteData.PlayAnim("animName");

    Also, note that you don't want to use GetComponent() every time you go to access the sprite. Instead, if you don't want to use the inspector to populate your reference, then use GetComponent() to populate it in Start(), and then save the reference for later use.
     
  12. renman3000

    renman3000

    Joined:
    Nov 7, 2011
    Posts:
    6,697
    d'oh!
    Right, thanks.

    I have got it working but it now says that it can not find the animation.


    the following is my code. I have the identical name in the SpriteTimeLine Editor for this packed sprite. Including caps. It matches in the inspector but again, it says that it can not find the animation.


    Code (csharp):
    1.  
    2. #pragma strict
    3. var dummyFace : GameObject;
    4. var animName : String;
    5.  
    6. function OnTriggerEnter (other : Collider)
    7. {  
    8.     if(other.tag == "dummy")
    9.     {  
    10.         var packedSpriteData = dummyFace.GetComponent(PackedSprite);
    11.         packedSpriteData.PlayAnim("animName");
    12.     }
    13. }
    14.  
     
  13. Brady

    Brady

    Joined:
    Sep 25, 2008
    Posts:
    2,474
    I'm not sure. Perhaps there are one or more trailing spaces in the name? Try using the index of the animation instead - that's faster anyway.
     
  14. renman3000

    renman3000

    Joined:
    Nov 7, 2011
    Posts:
    6,697
    ok. great.

    Thanks.
     
  15. hattrik4

    hattrik4

    Joined:
    May 10, 2012
    Posts:
    1
    Hi Brady,

    Being new to both SM2 and TimelineFX, I was wondering if you could send a quick guide/recommendation on how to best use TimelineFX with SM2. Specifically, what export options/format to use and if there are any other tips that would be helpful to make the importing of those animations smoother.

    Thanks!

    Ryan
     
  16. Brady

    Brady

    Joined:
    Sep 25, 2008
    Posts:
    2,474
    There's not much to it, really. In my opinion, the easiest workflow is to export the animations as a batch of individual frames (I don't have the precise steps to do that here in front of me, but as I recall it's pretty straight-forward). Then use a PackedSprite component for your sprite, create a new animation on that PackedSprite (see the video tutorials on the steps for doing this) and drag the exported frames onto the animation timeline. That's pretty much all there is to it. Just build your atlas and you're good to go.
     
  17. renman3000

    renman3000

    Joined:
    Nov 7, 2011
    Posts:
    6,697
    edit:
    I am trying to access the frame rate of a sprite so I can change it dynamiclly.

    However, when I use..
    Code (csharp):
    1.  
    2. packedSpriteData.SetFramerate(1);
    3.  
    it does nothing.


    Here is my full code.
    Code (csharp):
    1.  
    2.     for (var i : int = 0; i < coinMemberLength; i++)
    3.     {
    4.         var coin : GameObject;
    5.         coin = Instantiate(coinPF, coinMemberPos[i], transform.rotation);
    6.         if(i == 0)
    7.         {  
    8.             var packedSpriteData = coin.GetComponent(PackedSprite);
    9.             packedSpriteData.SetFramerate(1);
    10.         }
    11.     }
     
    Last edited: May 16, 2012
  18. Brady

    Brady

    Joined:
    Sep 25, 2008
    Posts:
    2,474
    I think the issue is that since you just instantiated the object, its Start() hasn't run yet, and so there's no chance an animation is playing yet. The framerate gets set when you start an animation, and then you can change it from there, but when you first run the animation, it gets set to the default that is set for that animation. So it's getting changed as soon as the animation begins to play. You need to either call Start() on the component explicitly, or wait a frame before setting the framerate.
     
  19. renman3000

    renman3000

    Joined:
    Nov 7, 2011
    Posts:
    6,697
    Great. Thank you.
     
  20. Markusn

    Markusn

    Joined:
    Jul 15, 2012
    Posts:
    22
    Hello,

    just wanted to let you guys know that I had to contact AnBSoft with a licensing problem I had after purchasing SM2 and received excellent help from Brady.

    Always good to know a middleware provider puts customers first, thought that's worth sharing.

    Cheers,

    Markus
     
  21. stephan7

    stephan7

    Joined:
    Jul 3, 2012
    Posts:
    44
    I'm using SpriteManager for over a year now. Really great software!

    In version 1.9 atlas building no longer works with children like in the past.

    Reproducible with the following steps:
    - create a empty GameObject 'p' (PackedSprite) with two children (also PackedSprites) 'c1' and 'c2'
    - switch pixel perfect on for all three GameObjects
    - assign a image to the three GameObjects
    - create a Prefab with 'p'
    - now delete 'p' in the scene
    - select the atlas and press <alt> + 'm' (build atlas for material)
    - check 'scan project folder'
    - press create

    In the atlas there is now only the sprite image associated with 'p'. The sprite images for 'c1' and 'c2' are missing.

    Works well with version 1.89!

    I can provide a small test project if desired. Simply drop me a note.


    Stephan
    --
    http://www.software7.com
     
  22. Brady

    Brady

    Joined:
    Sep 25, 2008
    Posts:
    2,474
    Thanks for the report. This was discovered by a couple of others and I'm looking into the cause. Thanks!
     
  23. sriram90

    sriram90

    Joined:
    Oct 14, 2010
    Posts:
    94
    Hi we have recently purchased sprite manager and started working with it. it's totally awesome.

    And here is the problem what we're facing,

    Actually we're created sprites using SM2 and we just need to drag the sprites around the screen. the sprite attached rigidbody and collider with it, these are perfect. when am trying to drag the a sprite on the screen its make blinking effect on screen. when we touch on the sprite its getting hide, when releasing the finger its showing, and when we're dragging its starting blink in iOS. but it's working well in standalone.

    We just need to know why this problem happening or anyone faced this problem before ?

    thanks.
     
  24. Brady

    Brady

    Joined:
    Sep 25, 2008
    Posts:
    2,474
    The only things I can think of that are likely to cause blinking are if you have an animation of some kind running and you're seeing other frames display very briefly, or if while dragging the sprite it is passing briefly beyond the near or far clipping planes. Make sure that while it is being dragged it remains safely within the camera's frustum. That might explain why it's only happening on mobile since there is less Z-precision by default on mobile than on desktop or in-editor.
     
  25. StoneFish

    StoneFish

    Joined:
    Aug 26, 2012
    Posts:
    123
    Hi
    I'm wondering if with the latest version of SM2 if it's most optimal to remove the source assets before creating a build? (For real and virtual memory performance).

    Thanks
     
  26. Brady

    Brady

    Joined:
    Sep 25, 2008
    Posts:
    2,474
    There is no need to remove source assets as SM2 takes great care not to directly reference the source assets so that they are not included in the final build.
     
  27. crafTDev

    crafTDev

    Joined:
    Nov 5, 2008
    Posts:
    1,820
    Hey, I am trying to access the OnAnimEnd from scripting, so I can set it from script. How would I do that? I get errors doing this:

    Code (csharp):
    1. SM2Sprite.GetComponent(TextureAnim).onAnimEnd = UVAnimation.ANIM_END_ACTION.Play_Default_Anim;
    Error and warning:
    Thanks.
     
  28. crafTDev

    crafTDev

    Joined:
    Nov 5, 2008
    Posts:
    1,820
    Figured it out:

    Code (csharp):
    1. SM2Sprites[spriteAmount].GetComponent(PackedSprite).textureAnimations[0].onAnimEnd = SM2Sprites[spriteAmount].GetComponent(UVAnimation).ANIM_END_ACTION.Play_Default_Anim;
     
  29. test84

    test84

    Joined:
    Jun 28, 2011
    Posts:
    25
    Is there any trial version that I can play with?
     
  30. Brady

    Brady

    Joined:
    Sep 25, 2008
    Posts:
    2,474
    Since SM2 is distributed as source code, there isn't a trial version, but if you order from the AnBSoft.com website, I can offer a 30-day money back guarantee.
     
  31. Crazy Robot

    Crazy Robot

    Joined:
    Apr 18, 2009
    Posts:
    921
    Hey Brady,

    Any update on Unity 4.0 compatibility with both SM2 and EZGui concerning the errors I encountered?

    Thanks,
     
  32. test84

    test84

    Joined:
    Jun 28, 2011
    Posts:
    25
    Thanks but the thing is it's not easy for me to pay and I can have one shot of either buying or not. So it would be nice if I would playtest with it but it's plain sad that apparently not possible, as I'm planning to do 2D.
     
  33. Brady

    Brady

    Joined:
    Sep 25, 2008
    Posts:
    2,474
    @Crazy Robot
    I didn't see any issues you reported regarding SM2, just EZ GUI (UIButton and UIScrollList), the latter of which you should have an e-mail from me regarding.
     
  34. xikky

    xikky

    Joined:
    Dec 11, 2012
    Posts:
    47
    Thanks Brady for such a great tool.

    I am still learning your tool and one thing I have noticed is that there is a difference between the PackedSprite script in your tutorial to the one I have. I found out that I can access the 'Static Texture' from the Sprite Timeline window, but I can't find where to fill the frames with different textures.

    Any help pls?

    Thank you.
     
  35. Neefy

    Neefy

    Joined:
    Nov 28, 2012
    Posts:
    24
    Basically I want to trigger an animation when the character controller passes through a box collider. I got it to work but I want the animation to play once and destroy/deactivate itself and not play every time the character walked through it. I tried setting "On Anim End" to Destroy in the inspector window but that doesn't seem to work. I've been struggling for hours since I am very much new to scripting and this is what I've done so far.

    Code (csharp):
    1. #pragma strict
    2.  
    3. var Dialogue1 : GameObject;
    4.  
    5. var animName : String;
    6.  
    7.  
    8.  
    9. function OnTriggerEnter (other : Collider)
    10.  
    11. {  
    12.  
    13.     if(other.tag == "Player")
    14.  
    15.     {  
    16.  
    17.         var packedSpriteData = Dialogue1.GetComponent(PackedSprite);
    18.  
    19.         packedSpriteData.PlayAnim("dialogue1");
    20.  
    21.     }
    22.  
    23. }
     
  36. Brady

    Brady

    Joined:
    Sep 25, 2008
    Posts:
    2,474
    You can register an animation-complete delegate to be called when the animation completes, and then you can do whatever you want:
    Code (csharp):
    1.  
    2. // Inside your trigger handler:
    3. packedSpriteData.SetAnimCompleteDelegate( DoSomething );
    4. ...
    5.  
    6. function DoSomething( sprite : SpriteBase )
    7. {
    8.    // The animation completed, now destroy the sprite or whatever:
    9.    Destroy(sprite);
    10. }
    11.  
     
  37. StevenSauer

    StevenSauer

    Joined:
    Mar 25, 2013
    Posts:
    19
    Hello Brady,

    So far EZGUI + SM2 has been amazing to work with, though I've run into an odd predicament I cannot find a solution for.
    Right now I'm using a SuperSprite that has multiple animations. It starts off playing the Idle animation perfectly fine and then I do a 'trick' animation that has many different sized frames that have been trimmed in the atlas. On this trick animation I have auto-resize on because without it the frames are all contorted and warped. The first time I do this trick, it looks perfect. Then, I'll go back to the Idle animation and try to do that same trick again. This time, it seems that auto-resize is sizing it as 0? Some other factors could be that I am not using Pixel Perfect or that my Animation is ping-pong. I have turned off auto-resize and it will work multiple times, though it is still warped. Is my only option to turn off trimming and turn off auto-resize? Or am I missing something?

    Thanks a lot!
     
  38. Brady

    Brady

    Joined:
    Sep 25, 2008
    Posts:
    2,474
    It definitely should work. If it is getting set to 0, then it sounds like somehow the metrics AutoResize uses to calculate the proportionate size are getting changed. If you could PM me or e-mail me privately with a sample package that demonstrates the issue, I can help troubleshoot it.
     
  39. StevenSauer

    StevenSauer

    Joined:
    Mar 25, 2013
    Posts:
    19
    While building the unity package it came to me that there was one thing I didn't try. I did not have a static texture in the animation.

    I'm not sure why or what possible fixes could be applied to change it, but it looks like having no static texture messes with the AutoResize metrics once the animation hits it's static state. That's why it still worked the first time but never after that. I just gave it the same texture as it's first frame in the static texture and it worked fine.

    If you'd like, I could still send you the unity package if this seems like an issue worth having a look at. A warning message or default case for that situation would save a couple people a lot of time in the future.
     
    Last edited: Mar 26, 2013
  40. Brady

    Brady

    Joined:
    Sep 25, 2008
    Posts:
    2,474
    Ahh yes, that make sense. Without a static texture, the initial pixel-to-size ratio computation would come out zero. I'll see about adding a warning message in that case. Thanks!
     
  41. KentRobertS

    KentRobertS

    Joined:
    Oct 19, 2012
    Posts:
    1
    Don't know if this would be the correct place to post it, but I need some help with my animation script.
    Im trying to make the run animation play correctly after the character jumps or attacks, so far no luck.
    So was wondering if anyone here could perhaps help me?
    And it's for a 2D hack n'slash platformer game.
    Any help would be appreciated.

    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class HackAnimation : MonoBehaviour
    5. {
    6.     public PackedSprite Player; // assign your sprite to this in Unity  
    7.     public float moveSpeed = 2f;  
    8.     private float movement;  
    9.  
    10.     void Update()
    11.     {
    12.         movement = Input.GetAxis("Horizontal") * moveSpeed;  
    13.         movement *= Time.deltaTime;  
    14.        
    15.         if(Input.GetKeyDown(KeyCode.RightArrow))
    16.         {
    17.             Player.DoAnim(0);
    18.         }
    19.         if(Input.GetKeyUp(KeyCode.RightArrow))
    20.         {
    21.             Player.DoAnim(4);
    22.         }
    23.        
    24.         if(Input.GetKeyDown(KeyCode.LeftArrow))
    25.         {
    26.             Player.DoAnim(1);
    27.         }
    28.         if(Input.GetKeyUp(KeyCode.LeftArrow))
    29.         {
    30.             Player.DoAnim(5);
    31.         }
    32.        
    33.         if(Input.GetKey(KeyCode.Space))
    34.         {
    35.             if(movement < -0.01f)
    36.             {
    37.                 Player.DoAnim(7);
    38.             }
    39.             else if(movement > 0.01f)
    40.             {
    41.                 Player.DoAnim(6);
    42.             }
    43.            
    44.         }
    45.        
    46.         if(Input.GetKey(KeyCode.F))
    47.         {
    48.             if(movement < -0.01f)
    49.             {
    50.                 Player.DoAnim(3);
    51.             }
    52.             else if(movement > 0.01f)
    53.             {
    54.                 Player.DoAnim(2);
    55.             }
    56.         }
    57.     }
    58. }
     
  42. Brady

    Brady

    Joined:
    Sep 25, 2008
    Posts:
    2,474
    I'm not entirely sure what the problem is you're experiencing since you didn't describe the problem itself. But you mentioned jumping, and I don't see any code here that checks to see whether the player is still in the air or has made contact with the ground, at which point you would switch animations. I'd recommend having a look at some of the standard character controller prefabs in the standard Unity assets. These have jump/grounded detection code in them and might give you some ideas about how to process input and determine the state of the player and play the appropriate animation in response. As far as your use of SM2 is concerned, your .DoAnim() calls are correct. So your problem doesn't seem to be your use of SM2, probably just the logic specific to how your game responds to input and detects the player's state in the game world.