Forum rules - please read before posting.

Sprite sort order glitches after update to v1.63.2

(Unity 2017.3.1f1, and AC 1.63.2 (although, see below))

I'm back doing 2d stuff again, and I've picked up one of the old AC projects I was working on before my recent foray into 3d territory

The project hadn't been touched for a month or so, so when I reloaded it I upgraded it to AC 1.63.2, as I like to keep AC up-to-date, and I've never had any major problems upgrading in the past

This time all went smoothly - until I played the game through a couple of times, which was when I noticed that (on occasion, although not with any obvious pattern), some of the animated sprite actors weren't sorted correctly. In other words, animated sprites that should have appeared in front of other animated sprites were appearing behind them, and vice versa. That happened in both the editor, and also in the compiled version

All my animated sprites have a top level container object, with NPC or Player, and Paths scripts, and a child object containing the SpriteRenderer, Animator and the FollowSortingMap scripts

Well, after a day or so head-scratching, and trying out various possible solutions, I went back to an old version of the project. Loaded that up, ran it, and... no problems. The animated sprites were all sorted correctly

Hmmm... So, a bit more head-scratching, and then finally I tried going back to the latest, upgraded, version, but with a reverted version of FollowSortingMap.cs (from AC 1.62.6), and... lo and behold, again no problems. The sprites were all sorted correctly

So, a bit more digging, and... There seem to be two changes in the most recent version of the script, one of which is an editor-only thing, and as the problem occurs in the compiled version of the game as well as in the editor, that can't be the culprit

Which only leaves the change at line 207 in SetOriginalDepth

The version which works for me is:
originalDepth = transform.parent.position - transform.parent.position;
(which looks a little odd, but I guess would simply set originalDepth to Vector3.zero ?)

The latest version which caused me problems is:
originalDepth = transform.position - transform.parent.position;

Anyway, I've left a note to myself not to upgrade that particular script for any future upgrades for the time being, and, as I say, I can't give firm details on ways to reliably replicate the issue, all I can say is that for me it WAS an issue, and it seemed worth reporting anyway, in case it's something blindingly obvious



Comments

  • edited June 2018
    As a small p.s. I'd just add (because my original post may not have made it clear) that the problem is not related to any of the sprites' "Order in Layer" field. That is being correctly picked up from each Scene's default "Sorting Map"

    As far as I've been able to tell, the problem, when it occurs, is with the small adjustments that AC applies on the fly to each sprite's x and z transforms
  • Indeed the old code was odd, and was causing a bug elsewhere.  Despite my testing, it seems the fix has an unwanted knock-on effect.

    Could you elaborate on exactly how your characters hirerachy is set up?  You mention having a top-level container object.  If you can post images of your hierarchy, as well as show exactly where the FSM components are placed, that'll help me understand the issue better.
  • Ok, some screenshots of the characters' setups, as requested. I've also temporarily reverted my working version in order to grab some screenshots of the problem occurring in action, and I'm including those too, in case they throw any further light on the problem

    Some extra information which may (or may not) be helpful:

    > All NPCs have exactly the same structure as the one shown here. When I initially encountered the problem, I went through each Prefab and enforced that, even down to the order in which each Component appeared on each GameObject. Ditto for the Player characters (although, only the one shown here is actually used in this particular game)

    > The Marker GameObject that only appears on NPCs is used to Pathfind the Player to the NPC during Cutscene conversations. Probably irrelevant to the problem at hand but I'm including it for completeness

    > I only ever noticed the problem when a Player and an NPC were overlapping, i.e. not when two NPCs were overlapping. That may just be coincidence. I'm not sure that I've got any scenes in this game where multiple animated NPCs even appear in the same scene together

    > Although I have static NPCs that exist in some scenes when the scene loads (and which don't exhibit any problem behaviour anyway), animated NPCs are always spawned into a scene using an Object/Add Action

    > All Sprites used for animated characters are 256x256 and have their pivot point defined as Custom 0.5/0.1 - Because of the way they're created that more closely corresponds to the middle/bottom of their feet position than a simple "Bottom" would do

    > One thing I tried when the problem first manifested itself was to adjust the "Shared Layer Separation" value in the GameEngine Prefab from 0.001 to 0.01 (and I may possibly have tried larger values too). Needless to say, that didn't work

    > As I said originally, the problem was impossible to consistently replicate (although I'd guess that there must have been a pattern that I just wasn't seeing), but once it manifested in a scene, it seemed to persist no matter how far apart the player and the NPC were. It also always seemed to be that the NPC sprite incorrectly appeared in front of the player sprite (rather than vice versa), as in the example shown below

    The Player setup:

    The NPC setup:

    And, the problem occurring during gameplay:








  • I'm sorry, but those gameplay shots are far too small to gauge anything from - can you share the original screenshots?
  • Not actually tried doing this before using PostImage, but this should be a link to the Image Gallery of the above images, with the images clickable to display them at full size:

  • Thanks, I'll take a look.
  • The orders are the same, as are the Z-positions of the two root objects.  The display order is therefore determined by the Z-position of their respective sprite-childs.

    One of these should have a local position of (0,0,0), while the other should be (0,0,S) - where S is a small amount that makes the correction.  That both children have non-zero X and Z local position values looks to be the problem.
    1. Does it work if you uncheck Turn root object in 3D space? in their Player/NPC Inspectors?
    2. Are you controlling the sprite's position in the Animator?
    3. Let's try getting some debug information from the Console.  Above line 237 in FollowSortingMap.cs, paste the following:
    Debug.Log ("Set depth of " + transform.parent.name + " to " + depth + ", OriginalDepth: " + originalDepth);

    What does the Console say when the issue occurs?
  • One of the biggest problems with this is actually getting it to DO it consistently. I still haven't been able to figure out under exactly what conditions it occurs, so I usually have to run the game for a few minutes before it happens

    Anyhoo, I did manage to get it to happen again, and I grabbed some screenshots showing the state of the Player and the NPC involved - their main game objects and their child sprite objects, plus the output to the console

    In answer to the specific questions:

    1) Yes, the error still occurs with Turn root object in 3D space unchecked (as shown in the screenshots)

    2) No. Each Actor's Animator simply contains that Actor's set of Animations (idle_D, idle_U, etc). And each individual Animation simply cycles through the set of images for that particular animation. The Actors' positions shouldn't be affected

    3) The output to the console, when the problem occurs, can be found here:




    As a small p.s., because I've added my own comments to the version of FollowSortingMaps I'm currently using, the line numbers don't match those in the latest AC release, so, just to be 100% certain I've inserted the debug statement in the correct place, here's the altered script I used:

                    if (transform.parent)
                    {
                        Debug.Log("Set depth of " + transform.parent.name + " to " + depth + ", OriginalDepth: " + originalDepth);
                        transform.position = transform.parent.position + originalDepth + (transform.forward * depth);
                    }
                    else
                    {
                        transform.position = originalDepth + (Vector3.forward * depth);
                    }

  • In the code snippet you've just posted - try replacing "transform.forward" with "Vector3.forward".  Does that solve it?
  • edited June 2018
    Regrettably no, the error still occurs

    The only thing that works reliably for me is if originalDepth is always set to Vector3.zero. As soon as transform.position - transform.parent.position returns a non zero value for the Player Character (when setting originalDepth in SetOriginalDepth), that's when the overlap problem starts occurring
  • The Console appears to show that originalDepth is zero, but if the numbers are very small then it could be the case that it appears as (0,0,0) in the log.

    When you say it takes a few minutes for the error to occur, what are you doing during that time?  Moving the character(s) around, or just leaving it idle?
  • originalDepth is definitely Vector3.zero in the version that doesn't exhibit any problems, because I specifically set it so. My working version of FollowSortingMap's SetOriginalDepth looks like this:

            protected void SetOriginalDepth ()
            {
                if (KickStarter.settingsManager == null)
                {
                    return;
                }
                
                if (SceneSettings.IsTopDown ())
                {
                    depthAxis = DepthAxis.Y;
                }
                else
                {
                    depthAxis = DepthAxis.Z;
                }

                if (transform.parent)
                {
                    // From most recent version 1.63.2 of AC (this exhibits overlap problem)
                    //originalDepth = transform.position - transform.parent.position;

                    // From earlier version 1.62.6 of AC (this works)
                    //originalDepth = transform.parent.position - transform.parent.position;

                    // Current setting (this too works)
                    originalDepth = Vector3.zero;
                }
                else
                {
                    originalDepth = transform.position;
                }
            }

    As to when it happens, I actually have to run the game and do stuff for it to manifest itself (rather than just set it running then sit back and wait for it to occur). I need the player character to change scenes at least once, and then find an animated NPC who is moving around the screen

    That meant quite a lot of play time when I first encountered the problem, because animated NPCs are only meant to appear sporadically and at random in the game as designed

    However, I've just now sat down with a fresh project in an attempt to replicate the problem from scratch, using the 2D demo Brain character, and (rather to my surprise), I was able to do it without too much effort. I could send you that project if you want, or, to replicate:

    > In a fresh project with the latest version of AC loaded, create two Scenes, with a way to switch between the two by getting the player to e.g. walk into a Hotspot

    > Each Scene should contain a Polygon Collider Navmesh, and a DefaultSortingMap with at least one Area, and a variable scale (from, say, 50% to 100%)

    > In Scene1 create an NPC version of the Brain. For a proper demonstration I think it should be correctly animated, but in my version I simply gave it the Brain2D Animator Controller (although that will spam the Console with error messages)

    > Create a Path for the NPC to follow. It should have around four nodes, and a type of IsRandom. It should also have a Wait Time of, say, 3 seconds (because otherwise you'll have to chase around after the NPC hoping for the problem to mainfest)

    > Run the Game. Everything will look fine. Get the Player to go to Scene2, and then return to Scene1. Now, it may look as if everything is still fine, but eventually the Brain will be standing below the NPC, and yet the NPC will appear in front of the Brain, as so:

    image

  • Thank you for the detailed steps, and for your patience.  I'll go through them and see what I find.
  • I suspect that this occurs when the player switches scene while their sprite is offset to correct the display order.  Upon switching scene, the "originalOffset" is set again - meaning it then takes a non-zero magnitude.

    I'll PM you an update to FollowSortingMap.cs for you to test - please let me know if it resolves things.
  • Thanks for that. I've pm'd a reply
Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Welcome to the official forum for Adventure Creator.