Set a custom sorting point (without changing the pivot)? - unity3d

(Unity2D) Is there a way to set a custom sorting point for a spriterenderer without changing the pivot? I only see default and custom based on pivot as options, but I don't know if you can change them via script, has anyone done something like this?

This is a workaround that works for me, albeit a bit odd:
Make your game object child of an empty GameObject, and add a Sorting Group component to the empty GameObject. Move the empty GameObject to where you want your "pivot" to be.
This way, the empty parent with only the Sorting Group component will be used to sort. You'll have to add any movement code and colliders to the new parent, instead, so effectively you'll be moving the empty game object, and the child is just responsible for rendering the sprite with respect to the "pivot."

SpriteRenderer sort point
By default, a Sprite’s Sort Point is set to its Center, and Unity measures the distance between the camera’s Transform position and the Center of the Sprite to determine their render order.
To set to a different Sort Point from the Center, select the Pivot option. Edit the Sprite’s Pivot position in the Sprite Editor.
No, there is not a way to change the sorting point without changing the pivot. The sort point is the same as the sort point. What is your use case that you need to change the sorting point and cannot use sorting layers?

Related

Render order according to hierarchy in Unity

I am trying to understand how Unity decides what to draw first in a 2D game. I could just give everything an order in layer, but I have so many objects that it would be so much easier if it was just drawing in the order of the hierarchy. I could write a script that gives every object its index, but I also want to see it in editor.
So the question is, is there an option that I can check so that it uses the order in the hierarchy window as the default sorting order?
From your last screenshot I could see you are using SpriteRenderer.
The short answer to the question "is there an option that I can check so that it uses the order in the hierarchy window as the default sorting order?" would be no, there isn't by default*.
Sprite renderers calculates which object is in front of others in one of two ways:
By using the distance to the camera, this will draw the objects closest to the camera on top of the rest of the objects in that same order in layer, as per the docs:
Sprite Sort Point
This property is only available when the Sprite Renderer’s Draw Mode is set to Simple.
In a 2D project, the Main Camera is set to Orthographic Projection mode by default. In this mode, Unity renders Sprites in the order of their their distance to the camera, along the direction of the Camera’s view.
If you want to keep everything on the same sorting layer/order in layer you can change the order in which the objects appear by moving one of the two objects further away from the camera (this is probably further down the z axis). For example if your Cashew is on z = 0, and you place the walnut on z = 1 then the cashew will be drawn on top of the walnut. If Cashew is on z=0 and the walnut is on z = -1 then the walnut will be draw on top (Since negative is closer to the camera). If both of the objects are on z - 0 they are both equally as far away from the camera, so it becomes a coin toss for which object gets drawn in front, as it does not take into account the hierarchy.
The second way the order can be changed is by creating different sorting layers, and adjusting the order in layer in the sprite renderer component. But you already figured that out.
*However, that doesn't mean it cannot be done, technically...
If you feel adventurous there is nothing stopping you from making an editor script that automates setting the order in layer for you based on the position in the hierarchy. This script would loop through all the objects in your hierarchy, grab the index of the object in the hierarchy, and assign the index to the Order in Layer.
I don't think Unity has such feature (https://docs.unity3d.com/Manual/2DSorting.html).
Usually you shall define some Sorting Layers:
far background
background
foreground
and assign Sprite Renderer of each sprite to one of Sorting Layers

How can i draw an object before its parent object?

How can i change the sorting layer of objects in Unity 2D? Like force an object be rendered above (or under) another object even if it is a child of the other object.
I'm making a simple 2D humanoid animation, intuitively i'm using the torso as the root object, and the arms and legs be the child of it. But it results that my left arms is rendered after the torso, so it looks like my character have 2 right arms.
I tried to change the Z value of my arm, change the layer from UI to others, and tried to change some settings in my Canvas. But none of it worked.
I'm using RawImage to render my character, could that be the problem?
Have you tried using the sorting layers? Unity allows defining sorting layers for 2d sprites. You can select a sorting layer in the sprite renderer component,
You can create and order them under: Under "Tags and layers"
You can also order sprites on the same layer by changing the "order in layer" value in the sprite renderer component.

Unity all objects have same position

I have a 3d building model in my Unity project. It has many children like doors, walls etc. The problem is, all of the children points to same position in the Unity world (24.97, -2.08, 19.35). Their transforms show this position. And this position is far away from their actual one. How can i fix this?
I tried freeing all children from parent but this didn't change anything.
I want them to show their real position, which appears with move tool when we click upon them.
Here is the image link
It seems that this is simply their pivot point exported "wrongly" from the 3D editor your model was made with.
This won't change until you export it correctly from a 3D editor (Blender, Maya, etc).
Unity is not made for 3D mesh modeling and therefore in Unity itself you can't change the pivot points.
There is a very simple fix
Add a new empty GameObject
In the Inspector go to the Transform component, click on the context menu and hit Reset (you also simply set it to position 0,0,0 rotation 0,0,0 and scale 1,1,1) assuming the pivot should be at 0,0,0
Now drag and drop all objects into the empty GameObject
=> You have now one parent object with correct pivot.
By wrapping it in a parent object the childrens pivots don't matter anymore. You can simply do all translation, rotation and scaling on the parent object with the correct pivot and don't have to care about that "wrong" position at all.

unity5, box collider 2d size doesn't match platform

I created a 1x7 platform. then added a box collider 2D and set the size to 7. you can see in the picture. the platform and box collider are not matching. how can i get it fixed?
X Offset is the easy answer and definitely not a bad one, but maybe not the best one since it could make this problem show up in other areas.
BoxCollider2D by default has its origin at the center of the object ( where the translate tools are showing).
Since the translate tool is at the middle of the platform, the collider should be centered on it as well.
There are several possibilities that I can think of:
The sprites do not have their pivot at the center (If you want it
that way, use Offset to center the box)
The children of the selected object are offset (They should be
shifted over to line up with everything else, unless you need them
this way for some reason)
Create an empty Gameobject - add any sprite objects that you need in there - press the "GameObject" button in the menu and select "Centered on Children" in order for the empty object to be centered properly. This will have to be done each time you add a new object into the bulk. Hope this helps.

Unity3d Transform issues when trying to re-parent a Gameobject with sub-Gameobjects

I am trying to grab a Gameobject that's placed in the correct spot and re-parent it to different Gameobject transforms using code. I manage to do this by using ..transform.parent = parent.transform but the rotation and position get messed up. How can I keep it's rotation and position when re-parenting?
Thanks!
Always use gameObject.transform.SetParent(anotherGameObject), or you risk exactly the sort of phenomena you've described. See SetParent docs; there is a second parameter to consider.
The form mentioned in the question still works in many cases, but has been deprecated for a while.
Place all game object that you want to parent, to empty game object(example:"EMPTY\PARENT\EMPTY\CHILD") with scale 1:1:1(in editor)or re-scale your parent game object to 1:1:1