Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
13 Jun 22 - 14 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
6
Question by deadgenre · Jan 19, 2014 at 07:20 AM · spritesorting layers

Sprite layer order determined by Y value

I'm working on a top-down sprite-based RPG in Unity and I've encountered somewhat of a problem: because of the 3/4 perspective I'm using, sometimes a player should be drawn above an object and other times, below. I've achieved this effect in MonoGame by simply sorting sprites by their Y position values and drawing in that order; however, in Unity this doesn't appear to be possible. Is there any way to achieve this effect?

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

4 Replies

· Add your reply
  • Sort: 
avatar image
16
Best Answer

Answer by deadgenre · Jan 23, 2014 at 03:18 AM

I ended up placing a function the following code in my update method:

 GetComponent<SpriteRenderer>().sortingOrder = Mathf.RoundToInt(transform.position.y * 100f) * -1;
 
Comment
Add comment · Show 3 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image dodongoo · May 04, 2014 at 03:35 PM 0
Share

Thanks man, that helped me!

avatar image SweatyChair · Feb 06, 2018 at 01:53 AM 0
Share

what if all characters are moving?! this need to be done in Update for all characters and it seems performance consu$$anonymous$$g!

avatar image sandbaydev · Mar 13, 2020 at 06:26 AM 2
Share

The best answer (in year 2020) is by $$anonymous$$uskar.

In Unity: Edit -> Project Settings -> Graphics -> Transparency Sort $$anonymous$$ode: Custom Axis + Transparency Sort Axis: X=0, Y=1, Z=0

Old thread, but since happened to not-read the whole thread I thought to add a comment here.

avatar image
11

Answer by Muskar · Nov 06, 2018 at 07:58 PM

An old question, but now the answer is either to pivot all your sprites to the bottom and then do the global Edit -> Project Settings -> Graphics -> Transparency Sort Mode: Custom Axis + Transparency Sort Axis: X=0, Y=1, Z=0

But I wanted to do it by script:

 using UnityEngine;
 
 public enum SortingOrigin
 {
     Pivot, Bottom, Top, Left, Right
 }
 public enum SortingAxis
 {
     X, Y
 }
 
 [RequireComponent(typeof(Renderer))]
 public class LayerSorter : MonoBehaviour {
 
     [SerializeField]
     private int _originOrder = 100;
     [SerializeField]
     private float _precision = 1f;
     [SerializeField]
     private int _offset = 0;
     [SerializeField]
     private bool _runOnlyOnce = false;
     [SerializeField]
     private SortingOrigin _sortingSelector;
     [SerializeField]
     private SortingAxis _sortingAxis = SortingAxis.Y;
 
     private Renderer _renderer;
     private float _timeLeft;
     private float _updateFrequency = .1f;
 
     private void Awake () {
         _renderer = GetComponent<Renderer>();
     }
     private void Start()
     {
         UpdateSortOrder();
         if (_runOnlyOnce)
         {
             enabled = false;
         }
     }
 
     private void LateUpdate ()
     {
         UpdateSortOrder();
     }
 
     private void UpdateSortOrder()
     {
         _timeLeft -= Time.deltaTime;
         if (_timeLeft <= 0)
         {
             _timeLeft = _updateFrequency;
             Vector2 pos = _renderer.bounds.center;
             float width = _renderer.bounds.size.x;
             float height = _renderer.bounds.size.y;
             switch (_sortingSelector)
             {
                 case SortingOrigin.Bottom:
                     pos += Vector2.down * height / 2;
                     break;
                 case SortingOrigin.Top:
                     pos += Vector2.up * height / 2;
                     break;
                 case SortingOrigin.Left:
                     pos += Vector2.left * width / 2;
                     break;
                 case SortingOrigin.Right:
                     pos += Vector2.right * width / 2;
                     break;
                 default:
                     pos = transform.position;
                     break;
             }
             float posFromAxis = _sortingAxis == SortingAxis.X ? pos.x : pos.y;
             _renderer.sortingOrder = (int)(_originOrder - posFromAxis / _precision + _offset);
         }
     }
 }

Here's where I started: https://unity3d.com/learn/tutorials/topics/2d-game-creation/sorting-groups-and-transparency-sort-axis

It also has some other good tips on sorting, like sorting groups.

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image shoopi · Feb 26, 2021 at 04:16 PM 0
Share

This should be the accepted answer. Why would you do it by script when unity has a built-in option though?

avatar image
1

Answer by CarterG81 · Jun 08, 2015 at 11:35 AM

Since this was one of the major results when googling a similar problem, I figure I'd link to my solution based on this answer.

http://forum.unity3d.com/threads/order-in-layer-16-bit-limit-huge-world-in-one-scene.331646/

Order In Layer is 16 bits, so OrderInLayer = Position.Z is limited to 32767,32767.

Unity gives a floating point limitation warning after 99999, which is a little more than 3x the OrderInLayer limitations.

The solution? Divide by 3!

If you change Order In Layer every 3 integers/position instead of every 1, it is really closer to the floating point limitation for positions (32767 * 3 = almost 99999). I tested this by changing Order In Layer every 5, and I didn't notice any difference in my game. (1 position = 1 pixel). It's a 3D world with 2D sprites and a perspective camera, so this was not easy after trying so many solutions. I tried other solutions as you can see in the thread (and more that I didn't mention in the thread.)

Anyway, here is the code:

 int pos = Mathf.RoundToInt(theParent.transform.position.z);
 pos /= 3;
 spriteRenderer.sortingOrder = (pos * -1) + OrderOffset;

Comment
Add comment · Show 4 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Orion390 · Nov 23, 2015 at 02:58 AM 1
Share

What are you refering to with OrderOffset?

avatar image CarterG81 · Feb 13, 2017 at 02:53 AM 0
Share

OrderOffset is not required. It's simply an integer which you can add to the equation so that you can offset the order by +/- any number.

I use OrderOffsets because my characters are multiple sprites, so their legs may be behind their bodies & their heads infront of their bodies. So Body's OrderOffset = 0, Legs = -1, Head = 1, etc.

avatar image Ahzuumaht CarterG81 · Jul 06, 2017 at 02:14 AM 0
Share

Hi there,

New to Unity and attempting this solution to render my 2D sprites based on y position. axi0n's answer above is enticing in its simplicity, but I intend to layer sprites atop one another similar to how you have described yours for my game. However, I'm unsure exactly what you mean by theParent in your code (or rather how to set it appropriately in this code, I understand the concept of parent and children objects). In short, I intend to layer equipped items over the base player sprite but want to ensure each of the equipped items still follow the player sprite's actions and order in layer so that they move behind objects when the y value is greater than the world object's and vice versa.

Thanks in advance for the help!

avatar image CarterG81 Ahzuumaht · Mar 25, 2018 at 11:41 PM 0
Share

Not sure why I was never notified of this comment. TheParent is just the root object for that game entity. The gameobject that all your child gameobjects are under.

"theParent" is the main gameobject, while I have child gameobjects which have other components. So "theParent" is just the gameobject that you want to actually move via Transform.

avatar image
0

Answer by d2clon · Feb 17 at 04:10 PM

As someone is trying to say this is already solved by Unity, but if you are as me and need to have a visual description of the configuration here you are:

Edit > Project Settings > Graphics > Transparency Sort Mode: Custom Axis Edit > Project Settings > Graphics > Transparency Sort Axis: X=0, Y=1, Z=0

alt text

If you are using Tiles I also recommend to configure:

Tilemap Renderer > Mode > Individual

alt text


screenshot-2022-02-17-at-170506.png (41.7 kB)
screenshot-2022-02-17-at-170156.png (26.3 kB)
Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Pinsukka · Mar 26 at 12:41 PM 0
Share

This isn't working for me with multipart characters. I have a base body sprite, then shirt and pants on top with +1 sorting order. When I have two of these characters standing close to one another, the character below will have their skin rendered below the clothes of character standing above.

Not sure how to solve this without manually setting the sorting orders based on Y-axis. :/

Edit: Ok the solution was quite simple when I just stopped to think for a moment. I made the Transparency Sort Axis X: 0, Y: 1 and Z: 1, then instead of having the body and clothes with different order in layer, I have the clothes Z-axis set to -0.0001 (just some small value to make sure they render on top of the body).

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

30 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

The PNG image used as sprite is turning into black on some of the devices like iPad1, iPhone4, Nexus7, Samsung Galaxy Tab2, Galaxy Nexus etc. 0 Answers

Performance tips on grid base game 1 Answer

Sorting Layer Logic Issue 0 Answers

Cut sprite for 2d Game 0 Answers

Create 2D animation from Editor 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges