Search Unity

SpriteManager - draw lots of sprites in a single draw call!

Discussion in 'iOS and tvOS' started by Brady, Jan 15, 2009.

  1. RBerg

    RBerg

    Joined:
    Aug 14, 2008
    Posts:
    10
    EDIT: Nevermind, the error went away after a save of the scene, and reopening the project. Not sure why, but it works now! This is really great.


    MrJoy - This is an amazing contribution! Thank you!

    I am running into a problem though when I try to integrate it into my project. I keep getting a Matrix Stack Overflow error. Do you know what could be causing this?

    Code (csharp):
    1.  
    2. ----UnityEngine.GL:INTERNAL_CALL_PushMatrix()
    3. ----UnityEngine.GL:INTERNAL_CALL_PushMatrix()
    4. ----UnityEngine.GL:PushMatrix() (at /Users/joe/iphone-clean/Runtime/Export/Generated/Graphics.cs:2435)
    5. ----ScreenSpaceSpriteManager:OnDrawGizmos() (at Assets/Scripts/Community/WidgetManager/SpriteManager/ScreenSpaceSpriteManager.cs:64)
    6. Matrix stack overflow
    7. UnityEngine.GL:PushMatrix() (at /Users/joe/iphone-clean/Runtime/Export/Generated/Graphics.cs:2435)
    8. ScreenSpaceSpriteManager:OnDrawGizmos() (at Assets/Scripts/Community/WidgetManager/SpriteManager/ScreenSpaceSpriteManager.cs:64)
    9.  
    10. [/Users/joe/iphone-clean/Projects/../Runtime/GfxDevice/opengl/GfxDeviceGL.cpp line 566]
    11. (Filename: Assets/Scripts/Community/WidgetManager/SpriteManager/ScreenSpaceSpriteManager.cs Line: 64)
    12.  
    13. Matrix stack overflow (Filename: /Users/joe/iphone-clean/Projects/../Runtime/GfxDevice/opengl/GfxDeviceGL.cpp Line: 566)
    14. Matrix stack overflow (Filename: /Users/joe/iphone-clean/Projects/../Runtime/GfxDevice/opengl/GfxDeviceGL.cpp Line: 566)
    15. ----UnityEngine.GL:INTERNAL_CALL_PushMatrix()
    16. ----UnityEngine.GL:INTERNAL_CALL_PushMatrix()
    17. ----UnityEngine.GL:PushMatrix() (at /Users/joe/iphone-clean/Runtime/Export/Generated/Graphics.cs:2435)
    18. ----ScreenSpaceSpriteManager:OnDrawGizmos() (at Assets/Scripts/Community/WidgetManager/SpriteManager/ScreenSpaceSpriteManager.cs:64)
    19. Matrix stack overflow
    20. UnityEngine.GL:PushMatrix() (at /Users/joe/iphone-clean/Runtime/Export/Generated/Graphics.cs:2435)
    21. ScreenSpaceSpriteManager:OnDrawGizmos() (at Assets/Scripts/Community/WidgetManager/SpriteManager/ScreenSpaceSpriteManager.cs:64)
    22.  
    23.  
    Thanks.
    -Ryan
     
  2. dock

    dock

    Joined:
    Jan 2, 2008
    Posts:
    605
    I keep on having a problem when the number of Sprites hits the AllocBlockSize. Sometimes, seemingly at random, it seems to fail to AddSprite. This is even when I am using RemoveSprite to clear up space in advance. I feel it ought to be coping fine in both cases, but right now my game crashes on the iPhone after a while. Has anyone encountered any problems like this?

    Also, is there any way to force refresh the entire sprite system?

    edit: It is definitely something to do with AddSprite after RemoveSprite has been applied. If I change 'RemoveSprite' to 'HideSprite' it appears to work, but of course my scene gets heavier and heavier all the time.
     
  3. dock

    dock

    Joined:
    Jan 2, 2008
    Posts:
    605
    I've ended up creating a workaround so that I never have to re-allocate sprites. I destroy my SpriteManager object and create a new one. Not ideal, but it works for me in this instance.

    Something to watch out for I think!
     
  4. Brady

    Brady

    Joined:
    Sep 25, 2008
    Posts:
    2,474
    Sorry I've been AWOL, guys! For some reason I stopped receiving notifications on this thread, so I've been gone far too long.

    Mr. Frisby, thanks for the contrib! Great work, I'm looking forward to check it out. I don't know if you remember me, but we met at GDC Austin. I'm planning on going back this year, so I hope to see you there!

    dock, I'm not sure about the crashing problem... I haven't had that problem at all. Has anyone else experienced this?

    As for your vertex coloring question, make sure you're using a shader that supporters per-vertex coloring. That could be the problem.

    Somebody had PM'd me earlier about an add-on they had that made the system render at edit time. Has anyone seen hide or hair of that? That's going to be a REALLY helpful addition.
     
  5. MrJoy

    MrJoy

    Joined:
    Oct 31, 2007
    Posts:
    60
    Brady,

    I tend to remember faces more than names. If I saw a picture of you, I'm sure I'd remember you. :)

    My screen-space stuff runs at edit-time, although somewhat badly. Might be able to use it as a reference point.
     
  6. CedarParkDad

    CedarParkDad

    Joined:
    May 28, 2008
    Posts:
    98
    Sorry it took me so long to make this, but here is a sample project for the GUI using the sprite manager which I posted. This contains an updated SpriteUI as well as the 1-line change to SpriteManager needed to override the Awake function. Some inefficiencies and System.XML dependencies were also removed. You may only have 10 layers of UI (0-9), but I don't think that's a hard limit to live by. It will now work with horizontal or vertical orientation as well.

    Excuse the art, I'm a programmer.

    If you have any questions feel free to post them here or PM me.
     

    Attached Files:

  7. CedarParkDad

    CedarParkDad

    Joined:
    May 28, 2008
    Posts:
    98
    Attached is the full example which might work a little better...sorry about not getting the full export. I didn't realized that inheritance wasn't followed when exporting a scene :) I've also changed the callback to give the position within the button, and an example turning knob using that position.
     

    Attached Files:

  8. imparare

    imparare

    Joined:
    Jun 24, 2008
    Posts:
    369
    Thank you for sharing this (have downloaded and will hopefully implement in the coming week).


    thanks again
     
  9. fallin

    fallin

    Joined:
    Mar 31, 2009
    Posts:
    2
    Hi,

    Thanks for all of this terrific info and for the work!

    I tried downloading the sample packages above and the one on the first page but get an error (could not decompress package) when I try to import the package into Unity 2.5 (Windows). Is this because they are for iPhone or maybe not compatible with Windows or am I doing something wrong? (I'm still very new!)

    Thank you!
    F
     
  10. CedarParkDad

    CedarParkDad

    Joined:
    May 28, 2008
    Posts:
    98
  11. Langaert

    Langaert

    Joined:
    Mar 2, 2009
    Posts:
    21
    So, I sort of got my shader issues solved, but not really. I was able to get the Particle Alpha Blend shader source from a link in the shaders forum. I created a copy and added "ZWrite On" to it.

    I now have a problem where areas where the texture has partial alpha seem to drill through the display (hopefully this explanation also relates the fact that I am not at all experienced in dealing with shaders).

    Basically, anywhere that the texture has a non-0, non-1 alpha value, the background color comes through the textures instead. Even if there is another sprite behind the top sprite, the area where the top sprite has partial alpha will show up as dark blue (the color of the background), rather than the expected texture data from either the top or bottom sprite.

    I have reduced the visibility of this problem by adding "AlphaTest Greater .5". But that just removes all of the soft edges. Anyone have any ideas how I can modify the shader to allow soft edges? Or is the problem maybe not with the shader? Thanks.

    Here is the shader:
    Code (csharp):
    1. Shader "Particles/Alpha Blended ZWrite" {
    2. Properties {
    3.     _TintColor ("Tint Color", Color) = (0,0,0,0)
    4.     _MainTex ("Particle Texture", 2D) = "white" {}
    5. }
    6.  
    7. Category {
    8.     Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" }
    9.     Blend SrcAlpha OneMinusSrcAlpha
    10.     AlphaTest Greater .5
    11.     ColorMask RGB
    12.     Cull Off
    13.     Lighting Off
    14.     ZWrite On
    15.     BindChannels {
    16.         Bind "Color", color
    17.         Bind "Vertex", vertex
    18.         Bind "TexCoord", texcoord
    19.     }
    20.    
    21.     // ---- Dual texture cards
    22.     SubShader {
    23.         Pass {
    24.             SetTexture [_MainTex] {
    25.                 constantColor [_TintColor]
    26.                 combine constant * primary
    27.             }
    28.             SetTexture [_MainTex] {
    29.                 combine texture * previous DOUBLE
    30.             }
    31.         }
    32.     }
    33.    
    34.     // ---- Single texture cards (does not do color tint)
    35.     SubShader {
    36.         Pass {
    37.             SetTexture [_MainTex] {
    38.                 combine texture * primary
    39.             }
    40.         }
    41.     }
    42. }
    43. }
     
  12. MrJoy

    MrJoy

    Joined:
    Oct 31, 2007
    Posts:
    60
    Langaert,

    The problem is that translucent triangles need to be sorted according to Z-order (back to front, I believe). That's why my WidgetManager has a sorting button.

    -JF
     
  13. rr525356

    rr525356

    Joined:
    Mar 30, 2009
    Posts:
    7
    I'm having some instantiation difficulty using JavaScript, and I'd love any suggestions.

    I've added a SpriteManager GameObject (called SpriteObject), created a GameObject for the sprite(called Cloud) and put it into a prefab. If I drag a the prefab onto the stage (and set a SpriteObject ref in the inspector), it shows the sprite. If I attempt to instantiate it at runtime, I I get a NullReferenceException.

    How can I force the prefab to get a reference to SpriteObject at runtime? On the prefab, the inspector will not let me reference an object in scene, only items in the project folder. Do I need to create a new SpriteObject everytime I want to create a Cloud?

    Here is the script attached to my Cloud Prefab :
    Code (csharp):
    1.  
    2. var _spriteManagerReference:GameObject;
    3. var _mySpriteManager:SpriteManager;
    4.  
    5. function Awake () {
    6.     _mySpriteManager = GameObject.Find("SpriteObect").GetComponent(typeof(SpriteManager)) as SpriteManager;
    7.     //_mySpriteManager = _spriteManagerReference.GetComponent(typeof(SpriteManager)) as SpriteManager;
    8.    
    9. }
    10.  
    11. function Start() {
    12.     _mySpriteManager.AddSprite(this.gameObject, .5, .5, 3, 120, 128, 128, true);
    13. }
    14.  
    I'd love to get this working and put together a sample project using JavaScript for people like myself. Thanks!
     
  14. seon

    seon

    Joined:
    Jan 10, 2007
    Posts:
    1,441
    rr525356: Read further back in this thread, all of this has been asked and covered already.
     
  15. rr525356

    rr525356

    Joined:
    Mar 30, 2009
    Posts:
    7
    You've been very helpful in my quest to get this working with your earlier code samples. I've re-read every post multiple times and tried everything. briwil and se7en had similar issues, and I've tried everything they've mentioned, but something is still broken. I put together a very simple package, and I'd be grateful if anyone could look at it for two seconds to see what I'm doing wrong.

    I keep getting "ArgumentOutOfRangeException", and I have no idea what's causing it. Thanks.
     

    Attached Files:

  16. seon

    seon

    Joined:
    Jan 10, 2007
    Posts:
    1,441
    Can you zip it please... I cant download it.
     
  17. rr525356

    rr525356

    Joined:
    Mar 30, 2009
    Posts:
    7
    I've attached a zip of the project (built with Unity / iPhone). Thanks a ton for taking a look.
     

    Attached Files:

  18. seon

    seon

    Joined:
    Jan 10, 2007
    Posts:
    1,441
    Code (csharp):
    1. var _spriteManagerReference:GameObject;
    2. var _mySpriteManager:SpriteManager;
    3.  
    4. function Awake () {
    5.     //_mySpriteManager = GameObject.Find("SpriteManagerGO").GetComponent(typeof(SpriteManager)) as SpriteManager;
    6.     //_mySpriteManager = _spriteManagerReference.GetComponent(typeof(SpriteManager)) as SpriteManager;
    7.     //_mySpriteManager = _spriteManagerReference.GetComponent("LinkedSpriteManager");
    8.     var _spriteManagerReference : GameObject =  GameObject.Find("SpriteManagerGO");
    9.     _mySpriteManager = _spriteManagerReference.GetComponent(SpriteManager) as SpriteManager;
    10. }
    11.  
    12. function Start() {
    13.     _mySpriteManager.AddSprite(this.gameObject, .5, .5, 3, 120, 128, 128, true);
    14. }
    You are creating a public variable called _spriteManagerReference but then you are assigning a local one in your awake.

    Code (csharp):
    1. var _spriteManagerReference : GameObject =  GameObject.Find("SpriteManagerGO");
    This has nothing to do with SpriteManager but simple variable scope issues.

    Try this out...

    Code (csharp):
    1.  
    2. var _spriteManagerReference:GameObject;
    3. var _mySpriteManager:SpriteManager;
    4.  
    5. function Awake () {
    6.     _spriteManagerReference : GameObject =  GameObject.Find("SpriteManagerGO");
    7.     _mySpriteManager = _spriteManagerReference.GetComponent("SpriteManager");
    8. }
    9.  
    10. function Start() {
    11.     _mySpriteManager.AddSprite(gameObject, .5, .5, 3, 120, 128, 128, true);
    12. }
    13.  
     
  19. rr525356

    rr525356

    Joined:
    Mar 30, 2009
    Posts:
    7
    My apologies, I seem to have gone codeblind and re-declared that var. I'm running the sample you posted, and I'm getting an "Unexpected token" error at the line where _spriteManagerReference is retyped as GameObject. If I remove : GameObject, I continue to get the ArgumentOutOfRange exception.

    I come from a Flash/ActionScript background, and the scoping seems to work the exact same way. I've spent about 20 hours in the last 3 days trying to get this SpriteManager class to work and I get the feeling that I'm missing some fundamental underlying part of how scoping works in Unity, or there is just too much inconsistency in the JavaScript implementation. I'm starting to consider porting this to C# to avoid the headaches :oops:
     
  20. Brady

    Brady

    Joined:
    Sep 25, 2008
    Posts:
    2,474
    I'm not a Javascripter, but shouldn't the part inside "Awake()" lack the ":GameObject" part? Shouldn't it just be?:

    _spriteManagerReference = GameObject.Find("SpriteManagerGO");

    It seems to me that still having the ": GameObject" is telling the compiler that you are still wanting to instantiate a new instance.
     
  21. seon

    seon

    Joined:
    Jan 10, 2007
    Posts:
    1,441
    Sorry, my bad... I posted the last code without checking as I was running out for dinner.

    Code (csharp):
    1. function Awake () {
    2.    _spriteManagerReference : GameObject =  GameObject.Find("SpriteManagerGO");
    3.    _mySpriteManager = _spriteManagerReference.GetComponent("SpriteManager");
    4. }
    Should be...

    Code (csharp):
    1. function Awake () {
    2.    _spriteManagerReference =  GameObject.Find("SpriteManagerGO");
    3.    _mySpriteManager = _spriteManagerReference.GetComponent("SpriteManager");
    4. }
    And your Out Of Index issues is because you have not set Alloc Block Size in your sprite manager. It must be bigger than 0.
     
  22. rr525356

    rr525356

    Joined:
    Mar 30, 2009
    Posts:
    7
    !!!!!!!!!!!!!!

    I can't believe I overlooked that, never crossed my mind. Thanks for all your help. I've attached a working package / zip file for anyone that may be having issues. There is a sprite instance on the stage, as well as a runtime instantiation from SpriteGenerator (attached to camera).
     

    Attached Files:

  23. Langaert

    Langaert

    Joined:
    Mar 2, 2009
    Posts:
    21
    Thanks for pointing me in the right direction, but can you be a bit more specific? I'm quite far along in development so I'm not interested in implementing your widget manager. My computer won't open the unitypackage you posted anyway (even though I have Unity and Unity iPhone installed).

    More to the point though- what do mean I need to sort the Z-Order? The sprites in question are already appropriately positioned in y-depth (the sprites are on the xz plane) and the y positions are not dynamic.
     
  24. MrJoy

    MrJoy

    Joined:
    Oct 31, 2007
    Posts:
    60
    Z-order from the perspective of the camera, not world-space.

    The triangles within a mesh must be submitted to the GPU such that they are ordered back-to-front. The phenomena you are describing occurs when you have a triangle later in the list of triangles but which should be drawn "below" a triangle that occurs earlier in the mesh.

    Alpha testing is an imperfect solution, and also has the drawback of hampering certain optimizations on the MBX Lite related to avoiding unnecessary work (no, I do not fully understand the impact; I am going only by the vague references I've seen in various presentations coming out of Imagination, makers of the MBX Lite).

    If you don't need to rotate sprites, you may find it more useful to use a particle emitter/renderer set to "Sorted Billboard" mode. The alternative is to modify the SpriteManager class to sort the triangle list -- in your case, apparently you would sort by the Y position of the sprites.

    -JF
     
  25. zibba

    zibba

    Joined:
    Mar 13, 2009
    Posts:
    165
    Regarding Z-Order, do I need to do this if I have several billboard sprites scattered around a world acting as item pickups? I'm finding they're not ordered correctly with the 3d objects.
     
  26. MrJoy

    MrJoy

    Joined:
    Oct 31, 2007
    Posts:
    60
    The issue of z-ordering as it related to other objects is separate. This is only relevant to the case of having a single mesh with several triangles that will overlap when displayed, and which are rendered with translucency (blending).
     
  27. zibba

    zibba

    Joined:
    Mar 13, 2009
    Posts:
    165
    cool, do you know the solution for z-ordering related to other objects?
     
  28. Langaert

    Langaert

    Joined:
    Mar 2, 2009
    Posts:
    21
    I second the question, I've searched the forums, the documentation, and google and haven't come up with anything with regards to this z-ordering. Any help is appreciated!
     
  29. MrJoy

    MrJoy

    Joined:
    Oct 31, 2007
    Posts:
    60
    Make sure the shader you are using for your sprites has:
    Tags { Queue=Transparent }
    And, IIRC, it needs to not write the depth buffer (ZWrite Off) -- I could be wrong about that though, so experiment and see.

    I believe Unity sorts *meshes* according to their AABB centerpoint, which in the case of SpriteManager is a very coarse measure. I believe that's only relevant if the other objects are also transparent. If they aren't, it shouldn't matter due to the use of the transparent render queue (I.E. all transparent objects come after all opaque objects).
     
  30. zibba

    zibba

    Joined:
    Mar 13, 2009
    Posts:
    165
    Ah I see. It has something to do with alpha blending. I was using the shader "Particles/Alpha Blended", changing it to "Tranparent/Cutout/VertexLit" fixed the world z-ordering. Not sure if that's entirely the right thing to do though.
     
  31. Langaert

    Langaert

    Joined:
    Mar 2, 2009
    Posts:
    21
    Hmm, this is troubling now, I appear to be being led in circles!

    I was previously having a problem with objects not appearing the correct order (objects that should have been appearing on top were mysteriously appearing at the back, etc).

    As a solution, earlier in this thread someone suggested that I edit my shader to turn ZWrite On. I did so, and it solved the problem of sprites not appearing in the correct order.

    But it would appear that this same change is also what is causing the alpha issue I am now having.

    So, how do I get SpriteManager to show sprites with alphas correctly AND also draw them in the right order?
     
  32. MrJoy

    MrJoy

    Joined:
    Oct 31, 2007
    Posts:
    60
    On iPhone, you want to avoid any shader that uses alpha testing (I.E. all the Cutout shaders, some of the particle shaders, etc). It causes the MBX Lite to be unable to do certain important optimizations that reduce memory bandwidth consumption and rasterization workload.

    -JF
     
  33. Brady

    Brady

    Joined:
    Sep 25, 2008
    Posts:
    2,474
    Alpha testing is different, however, from alpha blending.
     
  34. Langaert

    Langaert

    Joined:
    Mar 2, 2009
    Posts:
    21
    Just to clarify, I do not WANT to be using alphatest. Using alphatest is simply the only way I have found to minimize the appearance of the strange artifacts where partially transparent parts of the texture appear as the background color. I would rather just find a solution to why I am getting these weird artifacts, and skip the alphaTest completely. After all the alphatest causes jaggies around the edges of my sprites. And now I come to find out it could be causing performance issues to boot!
     
  35. zibba

    zibba

    Joined:
    Mar 13, 2009
    Posts:
    165
    So for particles and sprites which require alpha blending, which is the best performing MBX Lite shader to use?
     
  36. GamesByJerry

    GamesByJerry

    Joined:
    Oct 27, 2008
    Posts:
    71
    This is getting confusing for me too :( I've been working with a custom shader with:

    Tags { "Queue" = "Transparent" }
    Blend SrcAlpha OneMinusSrcAlpha
    AlphaTest Greater .01
    ColorMask RGB
    Cull Off
    Lighting Off
    ZWrite On

    Should these settings be modified in someway? Advantages and disadvantages? I've been using this for my current project with decent performance with 30+ sprites moving around and only 1 being animated for the time being.

    Is there someone out there with enough knowledge to update the wiki with a true example including source and custom shader that provides the best performance?
     
  37. MrJoy

    MrJoy

    Joined:
    Oct 31, 2007
    Posts:
    60
    The solution isn't in the shader. The solution is to sort the triangle list from back to front.

    For particles, use "Billboard Sorted" and Unity will make it happen for you. For SpriteManager... Well... You're on your own there for now.

    For WidgetManager, I have a button in the editor interface that does the sort for you (brute force method you don't want to use at runtime -- I'm serializing/deserializing widgets).

    -JF
     
  38. imparare

    imparare

    Joined:
    Jun 24, 2008
    Posts:
    369
    @CedarParkDad. Thanks again for the GUI extension to SM. I worked thru the code but in the end found it was too heavy a job to integrate into my existing code. The coding is nice work indeed and I would certainly recommend it to anyone starting a new game or using it in a game where the GUI is more independent from the game itself.

    Anyhow after looking at it and playing around with it for a while I had a lightbulb moment with it for my own game. I have several GUITextures which respond to a touch (checking to see if the GUILayer had been hit). The GUITexture's are parented and the parent had a transform on the position once the 'button' had been pressed.

    The workaround I put in place to reduce down to 1 draw call was to add a second camera and another SM GameObject and position the Sprites (taken from a single Atlas) exactly where the GUITexture's were. I then removed the GUITexture textures and animated the second camera to mimic the movement on the GUITexture parent. The result is one draw call and a single atlas to replace the GUITexture individual textures. There were no code changes other than the second camera movement and the additional SM (both straightforward) and the GUITexture although empty still responds to a hit as a GUILayer.

    Great job on the SpriteManager and thanks to all those who have contributed.
     
  39. GamesByJerry

    GamesByJerry

    Joined:
    Oct 27, 2008
    Posts:
    71
    Thanks MrJoy for the reply. I understand you require code to sort the sprites, but it's been mentioned that we need to avoid using alpha testing, which I assume is this line in my custom shader:

    AlphaTest Greater .01

    I'm asking if this is a great performance hit and do I need to consider coding a sorting algorithm for my game? Or has anyone actually got one that runs at runtime faster than using alphatest?

    And can someone supply a custom shader that is suited for SpriteManager that gives the best performance and allows transparent portions of a sprite (translucent would be a bonus)? Then I can at least try to write my own sorting algorithm and know I'm getting the best bang for buck.

    Cheers :)
     
  40. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    the iphone hardware defacto really suffers from alpha test. Its opted for alpha blend instead and works quite different with alpha blending than you are used to from common GPUs as it does prerasterization visibility checks.

    So you basically have higher performance with translucent than you would have with "masking" (alpha test) on the iphone.
     
  41. Langaert

    Langaert

    Joined:
    Mar 2, 2009
    Posts:
    21
    I had a chance to play around with trying to better order my objects, but it ends up just replacing one problem with another. That is, I now have my objects properly ordered- they don't change depth during the game, so the trick was simply to make sure that they were all created in the same order that they would appear in. But I still have to leave alphaTest at .5, because otherwise the transparent boxes around my sprites end up masking one another.

    Thanks for the tip on using translucency rather than alpha test. Any practical advise on how to implement this switch would be greatly appreciated. Can you at least throw us a link? I've searched the Unity shader references and find no mention of a translucency feature.
     
  42. MrJoy

    MrJoy

    Joined:
    Oct 31, 2007
    Posts:
    60
    Langaert,

    Reverse the order of the sprites. If you are seeing that problem, the sort order is wrong.

    The feature you want from ShaderLab is "Blend". Something like "Blend SrcAlpha OneMinusSrcAlpha" should do the trick.

    -JF
     
  43. MikaMobile

    MikaMobile

    Joined:
    Jan 29, 2009
    Posts:
    845
    For what its worth, I've used the built-in alpha test (cutout) shaders with my 2d games and it seems to have little negative impact on performance - virtually every element on screen in Zombieville is using alpha testing to resolve sorting issues. To test the performance impact of these shaders, I tried using regular transparent diffuse shaders and could percieve no performance difference even with dozens of moving parts on screen at once. It may be sub-optimal, but its not completely unusable.
     
  44. Michael-Ryan

    Michael-Ryan

    Joined:
    Apr 10, 2009
    Posts:
    184
    Like most people, I usually browse through forums and only create an account and log in if I have something to share.

    For those new to Unity or these forums ... You cannot see or access attached files unless you've created a forum account and have logged in first.

    It would have helped if this information was provided in the first thread. Better yet, the forum software should inform "guests" that there are attached files and that the user needs to be logged in to access them.
     
  45. kb_dev

    kb_dev

    Joined:
    Feb 11, 2009
    Posts:
    29
    void CreateGameObjects()
    {
    // Create balls:
    balls.Add(Instantiate(ballPrefab, new Vector3(-5f, 7f, 0), Quaternion.identity));
    balls.Add(Instantiate(ballPrefab, new Vector3(-4f, 7f, 0), Quaternion.identity));
    balls.Add(Instantiate(ballPrefab, new Vector3(-3f, 7f, 0), Quaternion.identity));

    balls.Add(Instantiate(ballPrefab, new Vector3(3f, 7f, 0), Quaternion.identity));
    balls.Add(Instantiate(ballPrefab, new Vector3(4f, 7f, 0), Quaternion.identity));
    balls.Add(Instantiate(ballPrefab, new Vector3(5f, 7f, 0), Quaternion.identity));

    // Create cans:
    cans.Add(Instantiate(canPrefab, new Vector3(-5.1f, 8.5f, 0), Quaternion.identity));
    cans.Add(Instantiate(canPrefab, new Vector3(-4.1f, 8.5f, 0), Quaternion.identity));
    cans.Add(Instantiate(canPrefab, new Vector3(-3.1f, 8.5f, 0), Quaternion.identity));

    cans.Add(Instantiate(canPrefab, new Vector3(3.1f, 8.5f, 0), Quaternion.identity));
    cans.Add(Instantiate(canPrefab, new Vector3(4.1f, 8.5f, 0), Quaternion.identity));
    cans.Add(Instantiate(canPrefab, new Vector3(5.1f, 8.5f, 0), Quaternion.identity));
    }

    void CreateSprites()
    {
    // Create sprites for three of the balls:
    for(int i=0; i<3; ++i)
    {
    Sprite s = spriteMan.AddSprite((GameObject)balls, // The game object to associate the sprite to
    1f, // The width of the sprite
    1f, // The height of the sprite
    251, // Left pixel
    509, // Bottom pixel
    256, // Width in pixels
    256, // Height in pixels
    false); // Billboarded?
    ballSprites.Add(s);
    }

    }

    I am adding the following method to the SpriteClientDemo.cs pasted in part above.

    void OnCollisionEnter(Collision collision)
    {

    spriteMan.RemoveSprite(????);

    Debug.Log("Collision");
    }

    How do I access the sprite that has collided? I have tried different options in vain.

    Thanks.

    --Thanks a lot to Brady and others who have contributed this awesome work.
     
  46. Brady

    Brady

    Joined:
    Sep 25, 2008
    Posts:
    2,474
    Presently, SpriteManager doesn't have a routine to automatically look up a sprite based on its associated gameObject. That would be relatively easy to implement, however. But another way to tackle the problem would be to store your game entities in a struct or a class that contains both the gameObject and sprite. This way, you'd get the gameObject in your collision handler, then get the script with the container class using GetComponent. Then the object returned will contain references to both the gameObject and the sprite. So it would look something like this (psuedocode):

    Code (csharp):
    1.  
    2. MyClass obj = (MyClass) collision.gameObject.GetComponent(typeof(MyClass));
    3.  
    4. spriteMan.RemoveSprite(obj.sprite);
    5.  
     
  47. zoul

    zoul

    Joined:
    May 5, 2007
    Posts:
    50
    I seem to be having an issue with disappearing sprites.

    I am using the SpriteManager.cs, and then manually calling sprite.Transform() on a single moving sprite in an Update(), my game consists of a 16x16 grid of 'tiles' and only one tile moves at any given time. The other tiles are static, and do not move.

    I modified SpriteManager slightly, and added a 'public static SpriteManager Instance { get; set; }' to it and set a private static var in Awake to 'this'. I also added a 'RemoveAll' method which just iterates through 'sprites' in the SpriteManager.cs and clears out all of the sprites, to help facility my 'clear the level' code, I clear the sprites from SpriteManager first and then destroy all the game objects that were being referenced by it or had references to 'sprite'.

    When my sprites disappear, the game object they are associated with is still in the scene, however the SpriteManager just seems to 'forget where it was'.

    Anyone else experienced this, or have any suggestions/solutions for correcting this? (I'm developing with Unity iPhone, if that matters)
     
  48. imparare

    imparare

    Joined:
    Jun 24, 2008
    Posts:
    369
    Am I correct with the following:

    RemoveSprite() adds the sprite to the availableBlocks array and removes it from the activeBlocks array.

    AddSprite() will check the availableBlocks array and if there is a sprite there it will remove it from availableBlocks and add it to activeBlocks.

    so if I have 500 sprites throughout the life of the game and I am adding/removing such that I only ever have 20 active sprites then I can set my AllocBlockSize to 20 ?

    Also, is there a benefit to setting SM AllocBlockSize to the lowest number you can rather than over allocating just in case?

    thank you
     
  49. zoul

    zoul

    Joined:
    May 5, 2007
    Posts:
    50
    You should set allocBlockSize to a value which is appropriate.

    If you only ever have 20 sprites allocated at a time, and you don't go over that ever ... then set it to 20.

    If you start off with 20, but eventually wind up with 100 over time ... you could set it to 100, to prevent the 'hiccup' in performance when it re-allocates and adds 20 more Sprite's to the 'sprite' array.

    You'd really have to test to see where your performance comes into play with this.

    I have a 16x16 grid of 'tiles' in my game ... 16*16=256, but I don't fill my entire grid ... and don't expect it to be filled at any point, so I set my allocBlockSize to 128 ... and, so far, have run into very few occasions where the array is increased during actual game play.
     
  50. imparare

    imparare

    Joined:
    Jun 24, 2008
    Posts:
    369
    Hey Zoul,

    the couple of questions I had were 1) the reallocation of available space in SM and 2) the over allocation of AllocBlockSize not the under allocation. I am unsure what happens if for example you set the block size to 1000 versus 100 (if you only every use 100).

    For now the answer to question 1 is the most important as I constantly add/remove sprites and want to be doubly sure that RemoveSprite() will mean that I am indeed reusing that space on the next AddSprite() rather than just making it inactive and having to add another slot.

    thanks for the reply