Search Unity

Sprite Factory - Sprite Animation System

Discussion in 'Assets and Asset Store' started by guavaman, Jul 28, 2013.

  1. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,625
    James,

    I've determined the crash on clicking the "Select" button on the Source Image icon is a bug in Unity causing the OnGUI loop to end prematurely when clicked. (That image thumbnail control is a built-in Unity control.) The only solution to "fixing" Unity bugs like this is to come up with a workaround if possible. I will see what I can do. In the mean time, its totally usable by simply doing a drag-and-drop of your image onto the Source Image thumbnail instead of clicking the "Select" button to bring up the chooser window. Remember, dock your Sprite Factory window to some panel area or it will get closed when you click outside the window.
     
  2. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,625
    James,

    I've come up with a workaround for the bug and submitted the new version to the asset store. If you pm me your email address, I will add you to my database and you will be able to download the new full version immediately from my website.
     
    Last edited: Mar 16, 2014
  3. beefkake

    beefkake

    Joined:
    Mar 5, 2013
    Posts:
    2
    Thanks for the prompt reply Guavaman. I have sent you a PM. I will let you know how it all goes :D
     
  4. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,625
    Last edited: May 10, 2014
  5. kahong.chan

    kahong.chan

    Joined:
    Nov 22, 2013
    Posts:
    5
    It's a very nice tools bro! I have use this for my development now.
    But I have some question to ask and until now I still can't find the solution to solve this issue


    $Screenshot 2014-05-19 17.00.01.png

    How can I to avoid the above situation when the enemy is on top of the character ? Do I need to change the box collider to capsule?
    Thank you very very much !!
     
  6. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,625
    Hi! Thanks! I'm glad you hear you're using it and I'd love to see your game when its finished.

    As for your issue, that's a fairly common problem in both 2D and 3D games and there are many different ways to handle it.

    If you're not already doing so, make your main motive collider a CapsuleCollider, or if you're using 2D colliders, a box and 2 circle colliders (one circle for the foot area, one circle for the head area). It's generally best to use Sprite Factory's animated box colliders for the hit detection, but use a normal non-animated collider for moving the character around on the terrain. By having a rounded surface on the head and foot area, gravity will help push the character down. But there is still the possibility the collider will be perfectly centered on the character's head and gravity won't be enough to push it down. In that case, you're going to have to come up with some way to detect this situation and add some sideways force to make the collider fall off.

    Another possibility would be to ignore collisions between the standing character and the falling character at the moment the character is knocked down. The character would still collide with the floor but not the other character(s). When he gets up again, re-enable collisions between characters. Note: This may have the side effect of causing characters standing in the area to pop out of place when the fallen character stands back up and suddenly re-enables his collider while other characters are in his space.

    If you do not need characters to be able to push against each other, then making their motive colliders ignore collisions against each other would prevent this situation entirely.

    I hope this helps!
     
    Last edited: May 20, 2014
  7. billy-kahong-chan

    billy-kahong-chan

    Joined:
    May 23, 2014
    Posts:
    9
    Thanks for your reply. I will try this when I finish my air combo system. Your tools is very fit to my 2.5D fighting game!! Great job!! I can share my project progress if you interest in it.

    finally thank you so much !!
     
  8. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,625
    No problem! Sure, I'd love to see your project. Feel free to send me a PM about it any time.
     
  9. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,625
    Sprite Factory 1.107 is live on the Asset Store.


    This is a fairly important update. It includes some bug fixes to 2D collider collision detection as well as 2D colliders (finally) being able to ignore collisions within the same sprite. (Unity 4.5 is required for that feature, which was just released a couple of days ago.) The internal ignored collisions finally makes 2D colliders work just like 3D colliders so you don’t have to manage tons of collision layers to deal with certain situations. Example: Now all hit boxes can be on one collision layer and all hurt boxes be on another collision layer for all enemies and players when using the 2D system because each sprite will automatically ignore all of its own colliders inside itself so you’ll never have the problem of a character hitting himself. (This is how 3D worked all along, but Physics2D was missing a critical IgnoreCollision function which was added in 4.5).
     
  10. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,625
    Wow, two releases in one day? :confused: I didn't expect the asset store review team to be so fast, but they already got the next version up.

    So Sprite Factory 1.108 is live on the Asset Store.

    Sprite.SpriteMaterial Documentation

    This class helps you make changes to all of a Sprite's materials and shaders simultaneously. The main purpose of this class is to allow you to change properties on the shaders of a Sprite without having to manually make changes to all the materials for every atlas. This makes it easy to create special effects that require animation of a shader's properties such as a fade.

    To use it, get the SpriteMaterial from Sprite.spriteMaterial, then use the functions in the class to modify the shader properties you need to modify. It would work the same way as using Material to modify a shader’s properties, only it applies the change to all the materials on the sprite (if there is more than one sprite mesh).
     
  11. Cienfuegos

    Cienfuegos

    Joined:
    May 30, 2014
    Posts:
    1



    So, with this sprite factory asset, would I be able to create my own platform 2D character, and not just the one that's in the preview?
     
  12. KidSicarus

    KidSicarus

    Joined:
    Feb 3, 2014
    Posts:
    35
    Hey, guavaman.

    Is it possible to add scaling per frame or per animation? We have some animations that are slightly out of scale with each other.

    Keep up the great work.

    Thanks!
     
  13. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,625
    Hi,

    Certainly! That's what Sprite Factory is for. It doesn't come with the character shown in the demos. You provide your own artwork (frames of animation) and set up your animations in the editor. You can make as many animations as you want for whatever purpose you want. It's an animation framework that will let you create static and animated sprites for any type of 2D game.

    To create a character you'd do the following:

    1) Create a new sprite in the editor.
    2) Add new animations such as Stand, Walk, Run, etc.
    3) Add your bitmap image frames to each animation.
    4) Customize the animation settings for each (wrap mode, frame rate, etc).
    5) If you're going to use the animated collider system for hit detection, you would add colliders and animate them in the editor on each frame.
    6) Create the sprite in the scene.
    7) If your sprite is going to interact with the environment through physics (say the character needs to walk on platforms or hills), add a collider + rigidbody or a character controller to the sprite's game object.
    8) Create a script and add it to the sprite's game object. This script will contain the logic for your character. All the character's logic will be up to you to provide through scripting.
    9) In your script, control all the animation of the character through methods provided in the Sprite class and receive and react to collision events.

    If you'd like to try a demo version of Sprite Factory, PM me or contact me on the form at the bottom of http://www.guavaman.com/projects/spritefactory/
     
    Last edited: May 31, 2014
  14. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,625
    Hi KidSicarus,

    Are the source images out of scale with each other? I don't think adding scaling to compensate for that would give good results. You'd end up with noticeable filtering artifacts as some frames scale and others don't. If it's not the source images that are out of scale, perhaps you could show me some screen shots of what's going on?
     
  15. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,625
  16. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,625
  17. falonso

    falonso

    Joined:
    May 15, 2013
    Posts:
    13
    Hello Guavaman,

    Thanks for creating such a great set of tools. It seemed like there is currently a limit on the minimum collider size - the lowest size being 20x20. Is there a way I could override this to create smaller colliders? Otherwise is there a workaround you might suggest?
     
  18. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,625
    Hi falonso,

    You're welcome! :)

    There isn't currently. You're the 2nd person to ask about that issue though. It's really a matter of the editor preventing you from making the collider smaller than 20x20 simply because it would be really difficult to grab the corners of the box without zooming if it were any smaller. Also, the rotator widget in the center isn't much smaller than that and detecting whether you're trying to rotate or move the box would be problematic.

    I suppose I could change it so that the size limit of the box would depend on the current zoom level. Would that help?
     
  19. falonso

    falonso

    Joined:
    May 15, 2013
    Posts:
    13
    Thanks for the explanation of the reasoning behind it. Yes, I think that zoom level would be a great way to approach the limit! I often work in full zoom anyhow. Otherwise, even if it was as simple as checking/unchecking a box that said "Override Size Limit" or "Size Limit" it would be nice.

    In the meantime, as a workaround, I think I might be able to add a script that overrides the collider size in update(), but if you can add that feature it would be great!
     
  20. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,625
    I don't think the workaround would work if the colliders are animated. I'll make a quick update tomorrow for you. If you PM me your email address, I'll add you to my registered users database and then send you a link where you can download the latest version before it goes live on the asset store (it can take several days to go live, and probably longer with Unite keeping them busy.) You'll just need to enter your email and asset store invoice number.
     
  21. PandaPeleador

    PandaPeleador

    Joined:
    Nov 16, 2013
    Posts:
    5
    Hey guavaman, don´t know if you remember me but we were in touch a while ago. You helped me so much with my trial version that I ended up buying the full version, great tool. I'm a few versions behind now though, how can I update my copy of Sprite factory? I have my proof of purchase if you need it.

    Thank you!
     
  22. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,625
    Hi Panda,

    How are you? You can download the newest version through the asset store. Just login with your account that you purchased it with, then look for your list of purchased products. Sprite Factory will update itself and notify you if it needs to do any upgrading of files. Be sure you back up your project before upgrading! Let me know if you have any trouble.
     
  23. PandaPeleador

    PandaPeleador

    Joined:
    Nov 16, 2013
    Posts:
    5
    Just got it thank you!. I left a review too,off to see the changes now.

     
  24. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,625
    Okay, great! Thanks for the review too!

    FYI, I'll be adding Playmaker actions to Sprite Factory very soon (right after I finish up and launch my new input manager replacement Rewired).
     
  25. PandaPeleador

    PandaPeleador

    Joined:
    Nov 16, 2013
    Posts:
    5
    Wow,Frame independent inputs ? That alone is very very interesting to be honest.
     
  26. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,625
    Yes, it should be a quite useful feature. However it does have limitations. Currently it only works for controller peripherals and custom controllers, not keyboard/mouse. At some point I may add native KB/mouse support, but for now it wraps Unity's KB/mouse input so those are updated every Update as usual.
     
  27. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,625
    I'm happy to announce that my new input system, Rewired has been released on the Unity Asset Store!

    Rewired is an advanced input system that completely redefines how you work with input, giving you an unprecedented level of control over one of the most important components of your game. It is cross-platform, player-centric input system with many advanced features such as Intelligent Hot-Plugging, frame-rate independent input, controller maps, a full editor GUI, saving/loading data via XML, named controller elements, support for 32 axes and 128 buttons (on Windows and OSX), and much more.

     
  28. BlankMauser

    BlankMauser

    Joined:
    Dec 10, 2013
    Posts:
    138
    Hey! I still really love this asset and use it all the time. Its actually my favorite asset on the store and has been incredibly useful.

    I had a feature request that might just not be feasible, but figured I'd ask anyways. If we could use multiple sprites in the animation editor on each frame that would be amazing. Example, if I had a room full of spikes in a top-down Zelda game and I wanted to animate all the spikes at once so they would co-ordinate each other. I could place multiple versions of the same spike sprite in the animation editor and move them all frame by frame! Making sure each spike is exactly where I want it to be in relation to the others on each frame. That would be ridiculously useful.
     
  29. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,625
    @BlankMauser

    Thanks! I'm glad to hear that! :)

    Your idea is interesting, but as you say, isn't feasible. Sprite Factory's editor is wholly based around editing a single sprite and isn't an animation system for moving individual sprites around. That would have to be a whole new editor. You could actually do that now though in Unity using their animation tools if you want to independently animate a bunch of single spike sprites moving up and down in the scene. But more likely, you'd just animate your spike tiles consisting of multiple spikes as a single sprite in your paint program with all the animation tools it provides.
     
  30. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,625
    .....
     
    Last edited: Mar 9, 2015
  31. Kiori

    Kiori

    Joined:
    Jun 25, 2014
    Posts:
    161
    is this asset compatible with the unity 4.3 sprite system? it seems to use meshes instead.

    Also, in pratice which one is faster, the unity quad sprites, or the mesh system you developed?

    Thanks.
     
  32. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,625
    That depends on what you mean by compatible. Sprite Factory does not use Unity sprites. It uses 3D meshes, either rects or meshes shaped to your bitmaps. You can't use Unity sprites or Unity sprite sheets in Sprite factory, but you can certainly mix and match Unity sprites and Sprite Factory sprites together in a scene. Interaction between sprites is all done with 2D or 3D colliders which are the same for Unity sprites and Sprite Factory sprites, so there's no reason you can't have some sprites from Unity's system and some from Sprite Factory's. You can also mix it with other 2D packages out there, for example using a tiling package for background, etc.

    I have never benchmarked it against Unity's system, but it's highly unlikely any C# solution could be as fast as a C++ solution, which I'm going to assume Unity's is. However, Sprite Factory can do quite a few things that are difficult with Unity system and has an intuitive editor system designed for the needs of managing bitmapped sprite animation.

    EDIT: See this post for some benchmarks.
     
    Last edited: Mar 17, 2015
  33. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,625
    Sprite Factory 1.112 is now live on the Unity Asset Store!

    This update brings official Unity 5 support as well as some other important changes:

    1.112
    Changes:
    - Dropped support for Unity versions below 4.3.
    - Added support for Unity 5.0.
    - Optimized Auto Mesh animation code to eliminate memory allocations.

    Bug Fixes:
    - Fixed exception when setting a blank tag on a 3D collider.
    - 2D colliders now have tag set properly.
     
  34. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,625
    Here are some benchmarks showing how Sprite Factory performs against Unity sprites.

    Unity Version: 4.3
    System: Core i7 920 @ 3.6GHz, Geforce 460 GTX 768MB
    Screen Res: 1920x1200
    Mip Mapping: No
    Shader: Sprite/Default
    Test: High-resolution sprite animation. 12 frames looping. Updated at 12 fps.
    Sprite Used in Test:
    SpriteFactoryBenchmarkTestSprite.png

    (Unity 4.6.3 shows similar results, but both Unity and Sprite Factory are overall slower in 4.6.3 vs 4.3.)

    SpriteFactoryBenchmarks_Charts2.png

    Summary:
    When using Mesh sprites:
    Sprite Factory maintains a higher average frame rate than Unity, but Unity maintains a higher minimum average frame rate. Overall, Unity sprites are faster when using Mesh cutout sprites. This is likely because Unity's implementation is multi-threaded.

    When using Rect sprites:
    Sprite Factory runs faster overall in both average FPS and minimum average FPS. This is especially true as the number of sprites on-screen increases showing a significant advantage for Sprite Factory after about 2,000 sprites on-screen.

    Notes:
    • Mesh vs Rect sprites: If the GPU is the bottleneck, Mesh sprites are preferred because they reduce overdraw. However, they use more CPU time because the mesh contains more vertices which must be transformed each frame.
    • Sprite Factory defaults to Rect sprites. Auto Mesh is an optional setting.
    • Sprite Factory is not multi-threaded because Unity doesn't allow accessing any of the API from another thread.
    • Sprite Factory sprites support many more features than Unity sprites and are more suited to animated bitmap sprite games.
    • As always, benchmarks are not 100% reliable.
     
    Last edited: Mar 17, 2015
  35. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,625
    Sprite Factory 1.113 is now live on the Unity Asset Store!

    1.113
    Changes:
    - Optimized Auto Mesh animation code to improve performance.
    - Optimized animation code to reduce CPU usage when frame rate is low.
    - Generate Mip Maps option in Editor Properties now set to False by default.
    - DefaultSpriteMaterial shader changed to Sprites/Default.
    - Added SpriteCameraGUIHelper class to eliminate memory allocations caused by OnGUI in SpriteCamera in game builds.

    Bug Fixes:
    - Sprites now rebuild only Materials and/or Atlases as needed when changing global editor properties.
    - Fixed incorrect mesh normals on 2-sided Auto Mesh meshes.
    - Fixed incorrect mesh bounds on Auto Mesh sprites when first instantiated.
     
    Last edited: Mar 17, 2015
  36. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,625
    Sprite Factory 1.115 is now live on the Unity Asset Store!

    1.115

    Changes:
    - Added Sprite.shadowCastingMode property (Unity 5+)

    Bug Fixes:
    - Generated child meshes now scale properly when Use Batch Scaling = False.

    1.114


    Bug Fixes:
    - Fixed exception when using Auto Mesh on sprites with multiple atlases.
     
  37. billy-kahong-chan

    billy-kahong-chan

    Joined:
    May 23, 2014
    Posts:
    9
    Hi guavaman,

    Now I'm here get back to my work. And here is my status of the project want to sharing to you.


    And I have one more question:
    I want to get the collider data from the sprite for checking the attack range to the AI. But the animator need to play once to update the collider info. So I have make the animator play once when the AI is create. But the other problem is coming. The collider will be wrong when the animator has flip! The comparison should be like this:

    Here is the normal status


    When the AI has move to reverse direction, the collider cannot update:


    How can I to fix this problem and access the collider data in more flexible way ?
    Thanks for your help.

    Billy Chan.
     
  38. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,625
    Thanks for posting that! I'll take a look at it tomorrow.

    I can't quite understand what you're asking here. Can you rephrase that?

    How are you flipping your sprite? If you flip it with Sprite.Flip it will flip the colliders properly.
     
  39. billy-kahong-chan

    billy-kahong-chan

    Joined:
    May 23, 2014
    Posts:
    9
    I use the Sprite.FlipX() to flip the sprite. But the colliders does not update until the animation need to play once.

    Sorry for my poor english.

    Anyway, I need to do the following first to get the collider data.

    Code (CSharp):
    1.     public void Start() {
    2.         updateAttackRange ("attack1");
    3.     }
    4.  
    5.     public void updateAttackRange( string colliderName ) {
    6.    
    7.         GameObject tmpObj = transform.Find( colliderName ).gameObject;
    8.    
    9.         if (tmpObj != null) {
    10.  
    11.             atkRangeBox.transform.localScale                = tmpObj.transform.localScale;
    12.             atkRangeBox.transform.localPosition            = new Vector3( tmpObj.transform.localPosition.x,
    13.                                                                              tmpObj.transform.localPosition.y,
    14.                                                                              tmpObj.transform.localPosition.z );
    15.             atkRangeBox.GetComponent<BoxCollider>().size     = tmpObj.GetComponent<BoxCollider>().size;
    16.        
    17.         }
    18.     }
    19.  
    20.     public void getBaseAttackRange() {
    21.         getAttackRange("attack1");
    22.     }
    23.  
    24.     public void getAttackRange(string colliderName) {
    25.  
    26.         StartCoroutine( playToGetColliderData(colliderName) );
    27.     }
    28.  
    29.  
    30.     IEnumerator playToGetColliderData( string colliderName ) {
    31.         animator.Play( colliderName );
    32.         yield return StartCoroutine( waitAnimatorEnd(colliderName) );
    33.  
    34.         updateBaseAttackRange();
    35.     }
    36.  
    37.     IEnumerator waitAnimatorEnd( string colliderName ) {
    38.         while ( animator.IsAnimationPlaying(colliderName) ) {
    39.             yield return null;
    40.         }
    41.     }
    42.  
    If I get the collider data in runtime script like this

    Code (CSharp):
    1.     public void updateBaseAttackRange() {
    2.         updateAttackRange ("attack1");
    3.     }
    4.  
    5.     public void updateAttackRange( string colliderName ) {
    6.    
    7.         GameObject tmpObj = transform.Find( colliderName ).gameObject;         // This is the collider Name
    8.    
    9.         if (tmpObj != null) {
    10.  
    11.             atkRangeBox.transform.localScale                = tmpObj.transform.localScale;
    12.             atkRangeBox.transform.localPosition            = new Vector3( tmpObj.transform.localPosition.x,
    13.                                                                              tmpObj.transform.localPosition.y,
    14.                                                                              tmpObj.transform.localPosition.z );
    15.             atkRangeBox.GetComponent<BoxCollider>().size     = tmpObj.GetComponent<BoxCollider>().size;
    16.         }
    17.     }
    18.  
    The collider will be at the wrong side if I just doing the FlipX().

    Hope you can understand.

    Billy Chan
     
  40. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,625
    @billy.kahong.chan

    1) What version of Sprite Factory are you using?
    2) What version of Unity are you using?

    I have just tested again having a character with an animated collider while animation is stopped. Flipping works as expected.



    flip.png

    As you can see from the inspector, I'm testing with no animation playing. Animation does not have to be playing in order for Flip to flip the colliders generated by Sprite Factory.

    flipinspector.png

    When you say the collider is not flipping, is this the Sprite Factory collider or another collider you've attached to the Sprite?

    What is "atkRangeBox"? Is it an additional collider you've created, or is it a collider created by Sprite Factory? If it's created by Sprite Factory, you should never be changing any settings on it manually.

    A few other thoughts:
    To get the collider, doing a transform.Find is slow. Just use this method in Sprite:
    http://guavaman.com/projects/spritefactory/docs/pages/classes/Sprite-GetCollider.html

    I'm not sure what you're doing with the attack range data, but it seems to me you could use a trigger collision against your range collider to determine if something is in range instead of copying the collider settings.

    Probably the best thing would be for you to create project that shows this behavior, zip it, and upload it to a file sharing service so I can see what's happening. Or if you prefer email, please PM me and I'll send you the support email address.
     
  41. Ben-BearFish

    Ben-BearFish

    Joined:
    Sep 6, 2011
    Posts:
    1,204
    I was wondering is there a reason you still use the MeshRenderer component vs Unity's newer 2D SpriteRenderer component?

    Also, this is kind of a minor note, but one of the nice things about Unity's 2D sprites is the editor click and drag 2D handles to move sprites versus the 3D mesh's axis translate gizmo. Would it be possible for you to implement that in the editor and give us an option to choose between the two?
     
  42. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,625
    No, sorry, it's not possible. Sprite Factory creates its own meshes and animates them. This includes rect meshes and auto mesh cutout meshes. When you use the Sprite Renderer, you have to use Unity's Sprite system which handles it's own meshes, atlases, etc. Sprite Factory is completely independent from Unity's Sprite system and manages all this data on its own. To remake everything using Unity's Sprite system would take an enormous amount of time for frankly very little payoff.
     
  43. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,625
    Ben-BearFish likes this.
  44. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,625
  45. magique

    magique

    Joined:
    May 2, 2014
    Posts:
    4,030
    I'm having a strange issue suddenly in Unity 5 where I start getting the following error when trying to access the sprite's spriteMaterial property.

    Object reference not set to an instance of an object

    When I first got it, I rebuilt my prefab that had the sprite in it and it started working again. But then without any changes on my part it just started happening again. I tried rebuilding the master sprite also, but no luck. The sprite itself is valid because I am able to access it right before this error occurs. I'm on a tight deadline for the Indie Game Contest so hopefully you'll see this and can help.

    EDIT: Further testing is showing that this just randomly works once in a while and then fails again. It can work one time during the life of the program and then the very next time fails.
     
    Last edited: Aug 5, 2015
  46. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,625
    There's more information in the stack trace that would help here.

    It's obviously not the spriteMaterial object that's null because that's instantiated once on Awake and never destroyed.

    In what context is this happening?
     
    Last edited: Aug 5, 2015
  47. magique

    magique

    Joined:
    May 2, 2014
    Posts:
    4,030
    Not so obvious. I deliberately added code to check if spriteMaterial was null in this case and it is. Here is the code:

    Code (CSharp):
    1.         _auxSpriteAlpha = 0.0f;
    2.         auxSprite.enabled = false;
    3.         shockwave.enabled = false;
    4.         if (auxSprite.spriteMaterial == null)
    5.             Debug.Log ("spriteMaterial is null");
    6.         auxSprite.spriteMaterial.SetColor("_Color", new Color(auxSpriteColor.r,
    7.                                                               auxSpriteColor.g,
    8.                                                               auxSpriteColor.b,
    9.                                                               _auxSpriteAlpha));
    10.  
    Interesting to note is that I ran this 2 times in a row just now and it worked fine. Then without making a single change, I built the stand-alone version and tried it. It failed and the log file reports that it's null.

    Code (CSharp):
    1. (Filename: C:/buildslave/unity/build/artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65)
    2.  
    3. NullReferenceException: Object reference not set to an instance of an object
    4.   at Shockwave.Reset () [0x00000] in <filename unknown>:0
    5.  
    6.   at PlayerController.Update () [0x00000] in <filename unknown>:0
    7. (Filename:  Line: -1)
    8.  
    9. spriteMaterial is null
     
  48. magique

    magique

    Joined:
    May 2, 2014
    Posts:
    4,030
    And now, without a single change again, I tried to run the game in the editor and now it fails there too. I've also added code on the Awake function of the component that has the sprite attached. It reports even at that early stage that the spriteMaterial is null when it fails.
     
  49. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,625
    Based on your code and log output, the problem is not where you think it is:

    "spriteMaterial is null" is only logged after the exception occurs above it:

    "NullReferenceException: Object reference not set to an instance of an object at Shockwave.Reset () [0x00000] in <filename unknown>:0 at PlayerController.Update () [0x00000] in <filename unknown>:0 (Filename: Line: -1)"

    Yes, spriteMaterial is null, but it's a side effect of the exception above it, not the cause. The exception is stopping the thread from continuing so Sprite Factory is never able to instantiate its Sprite Material on Awake (if you're instantiating it here), then you check it with Debug.Log and it returns false. (Unity's logger does continue to log slightly past an exception or a Debug.Break at time.) Either that or the Sprite itself is destroyed before you're calling it. One way or another, spriteMaterial _cannot_ be null from a Sprite that ran through it's Awake method and hasn't been destroyed -- it is _never_ modified for the life of the Sprite. (You can check the SpriteFactory.Sprite code in the source folder you want.)

    I'm assuming Shockwave.Reset is the parent method of this bit of code? The null reference would be happening before the call to spriteMaterial, either in one of those lines above it or something you didn't post here. Please post the whole method as well as the parent method PlayerController.Update.

    Add more Debug logs above there to make sure shockwave isn't null. Anything above that in the function, I can't see, but do the same for any objects accessed there.

    Code (csharp):
    1. try {
    2.  
    3.   // Other code above should go in here too to catch the exception
    4.  
    5.   Debug.Log("auxSprite is " + (auxSprite == null ? "null" : "not null"));
    6.   Debug.Log("shockwave is " + (shockwave == null ? "null" : "not null"));
    7.  
    8.   _auxSpriteAlpha = 0.0f;
    9.   if(shockwave != null) shockwave.enabled = false;
    10.   if(auxSprite != null) {
    11.     auxSprite.enabled = false;
    12.     if (auxSprite.spriteMaterial == null) Debug.Log ("spriteMaterial is null");
    13.     auxSprite.spriteMaterial.SetColor("_Color",
    14.     new Color(auxSpriteColor.r,
    15.     auxSpriteColor.g,
    16.     auxSpriteColor.b,
    17.     _auxSpriteAlpha));
    18.   }
    19.  
    20. } catch (System.Exception ex) {
    21.   Debug.LogError("Caught an exception! " + ex);
    22.   return;
    23. }
     
    Last edited: Aug 5, 2015
  50. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,625
    Based on the intermittent nature of it, I'd wager there's some timing issue here going on with Object.Destroy or some other deferred function that you can't predict exactly when it will be run. Possibly an order of update issue as well between Fixed Update and Update or some callback like OnTriggerEnter/OnCollisionEnter. I need much more context to know.
     
    Last edited: Aug 5, 2015