Render order according to hierarchy in Unity - unity3d

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

Related

How to find the center in unity 2d?

I want to create 2d game. The game is similar to the Scale Puzzle. I've already created nearly all the functionality. Only the last remains.
.
This is example.
And that's how I draw shapes.
.
I click inside a white square, and after 1 seconds a square is drawn regardless of the position of the ball. (x,y).
Square is created programmatically, and it is added to the parent element "SquaresList" with name New Game Object.
How can i do, so that the violet field becomes larger, and in the middle of the screen.
I made it so that for every 3 clicks, "SquaresList" increases Scale by 0.25f, and get negative position of the ball. Example:
SquareList.transform.position = new Vector2(-ball.pos.x, -ball.pos.y)
This does not work correctly.
What options can be? (intersections, find the max/min point, math formulas) ?
Hi NoName :) Your method
SquareList.transform.position = new Vector2(-ball.pos.x, -ball.pos.y)
would work perfectly if your object does not inherit other objects and there positions. To fix this make sure that you reset the position of all other game objects that you use as containers.

Making multiple objects with the same shader fade at different times

I have a death transformation for one of my GameObjects which goes from a spherical ball to a bunch of small individual blocks. Each of these blocks I want to fade at different times but since they all use the same shader I cannot seem to figure out how to make all of them not fade out at the same time.
This first picture is the Spherical Ball in its first step for when it turns from a spherical ball to a Minecraft'ish looking block ball and to the right of it is one of the blocks that make up the Minecraft'ish looking ball shown by the red arrow.
Now this is my Inspector for one of the little blocks that make up the Minecraft'ish looking ball.
I have an arrow pointing to what makes the object fade but that is globally across all of the blocks since they use the same shader. Is it possible to have each block fade separately or am I stuck and need to find a new disappear act for the little block dudes?
You need to modify the material property by script at runtime, and you need to do it through the Renderer.material property. When you access Renderer.material, Unity will automatically create a copy of the material for you that is handled separately -- including getting its own draw call, if you care about performance. You can tell this has happened because the material name in the renderer will change to "Materialname (Instance)".
Set the material's fade property using Renderer.material.SetFloat() (or whatever the appropriate Set... function is). Unfortunately the property's name isn't "Fade Factor". You can find the property's name by looking at the shader script, or by switching the inspector to debug mode and digging through the Saved Properties array for one that looks right.

Transparent shader allows the objects below to show on top

In my scene, the smileys(Quad with png image) are placed at Y:0 and the dots(Quad with tiling 3X3) are placed at Y: -0.25.
The shader I need to use for the smileys is Transparent-Diffuse as I am using a circle png image.
But the dots I use below are showing up above the smiley. Using any other shader like Diffuse solves the issue but the smiley becomes a square.
Screenshot:
If you need any more clarifications please dont hesitate to ask.
Edit:
I have attached the shader details of both the smiley and the dots from the inspector panel.
link: http://postimg.org/image/cvws1os7d/
Edit 2:
I have found that the issue should be with the MainCamera and especially with distance & "Field Of View".
I need to use "Perspective" as projection type and 140 as Field of View.
If I change the projection type to Orthographic the issue is completely fixed.
The below screenshots show how the distance and Field of View controls the appearance of the dots over the smiley.
Screenshot 1:
Y position: 8.48
Field of View: 30
link: http://postimg.org/image/s31tttrkp/
Screenshot 2:
Y position: 9.7
Field of View: 30
link: http://postimg.org/image/f71sq0y4b/
Screenshot 3:
Y position: 11.41
Field of View: 30
link: http://postimg.org/image/3uk4az3d3/
Screenshot 4:
Y position: 1
Field of View: 140
link: http://postimg.org/image/bul9zwg7z/
Can this be a clue?
Just a couple of info, on how transparency is typically implemented (not only by Unity).
Meanwhile opaque objects can be drawn in any order (even if sorting them in front-to-back order can eventually improve some GPU performances relying on an early z-cull). Which pixels are visible can be deduced using the depth value stored into the z-buffer.
You can't rely on z-buffer for transparency.
For rendering translucent objects a typical approach is to draw them after all opaque objects, and sorting them in back-to-front order (transparent objects more distant from the camera are drawn first).
Now the question is: how do you sort objects? with a perspective camera and meshes of a generic shape, the solution is not obvious.
For quad meshes oriented parallel to a ortographic camera view plane, the z order is implicitly correct (that's why it always works for you).
You can also notice that camera position influences the drawing order, because with perspective camera the order is calculated as distance between object position and camera.
So what can you do with Unity3d, in your specific use case scenario?
A couple of tricks:
Explicitly set the render queue of the material
Explicitly set the render order inside the shader (similar of the above, but equals to every object with the same shader)
Fake the depth using Offset into the shader (not that useful in your case but worth to be known)
hope this helps
EDIT
I didn't know that, the camera transparency sorting mode appears to be customizable. So this is another solution, maybe the best for your case if you want to use a perspective camera.
If you are using Sprite Renderer component to render the images, you have to change the rendering order with Sorting Layer and Order in Layer parameters instead of changing the Y position.
Sorting layers can be added by clicking the "default" and choosing "Add Sorting Layer..". The order of the layers is changed by dragging them into different order. With Order in Layer lower numbers are rendered first. This means that higher numbers will be drawn on top of lower ones.

Best Z ordering method for tile-based, cocos2D-iPhone games?

I want to make isometric, tile-based, iPhone games with cocos2D.
Sprites need to be drawn on-top of other sprites that are "behind" it. I'm looking for the best way to do this.
I'd like to avoid the painter's algorithm because it involves sorting all the sprites every frame which is expensive.
The Z buffer algorithm is supported by the GPU and cocos2D so this is what I'd like to use, but there is a problem. Some sprites, like buildings for example, occupy multiple tiles. Assigning a Z value to such sprites is difficult.
These are the options I've thought of:
Comparing two buildings and determining which one is "in-front" is
easy. So buildings can be sorted then assigned a Z value based on
the sort order. This wouldn't be any different from the painter's
algorithm. The OpenGl ES Z buffer wouldn't be necessary.
Assign a Z value to each building based purely on its location on
the map (without knowledge of where other buildings are). I'm
finding this difficult. I think it is possible, but I haven't been
able to come up with a formula yet.
Use multiple sprites for images that occupy more than one tile, so
all sprites will be exactly the same size. Z orders can then be
easily assigned based on what tile the sprite is occupying. The
problem with this solution is that it makes the game logic much more
complicated. All operations on a single building will have to be
repeated for each sprite the building is made-up of. I'd like to
treat each object as a single entity.
Modify the cocos2D code to allow sprites to have multiple Z values
at different points. If a sprite can have multiple Z values based on
what tile a particular part of the sprite falls on, then calculating
a Z value for that section is easy. I won't need to compare the
sprite to any other sprites. I believe this is possible by using
multiple quads for each sprite. The problem with this is that it is
a bit complicated for me since I am new to OpenGL ES and cocos2D. I
don't completely understand how all of the internal data structures
work. Although it seems like the most elegant solution if a formula
cannot be found.
I will up-vote any suggestions or references to helpful resources.
For #2, you can compute the Manhattan distance of the center of the object and use this value as the z-value of that object. It will work as long as you avoid very long objects in your map like 5x1 object or worse. But if you really need a long object to be placed in a tiled map, managing the z-order of objects in the map by setting a z-value using a formula is impossible.
To prove this:
1.) Place two 2x2 objects in a map horizontally and leave a unit tile between them.
2.) Place a 3x1 object between them. Let's name the 2x2 objects to A and B, and the 3x1 object to C.
3.) If you just rotate C(not changing its position), z-order of A and B interchange.
-If B is now in front, some objects behind B will be in front of A because of just the rotation of C. And it's costly to know which objects in back of both A and B previously will become in front of A after C's rotation.

How to select objects in OpenGL on iPhone without using glUnProject or GL_SELECT?

I have 3 OpenGL objects which are shown at the same time. If the user touches any one of them, then that particular OpenGL object alone should display in screen.
Just use gluUnProject to convert your touch point to a point on your near clipping plane and a point on your far clipping plane. Use the ray between those two points in a ray-triangle intersection algorithm. Figure out which triangle was closest, and whatever object that triangle is part of is your object. Another approach is to give each object a unique ID color. Then, whenever the user touches the screen, render using your unique ID colors with no lighting, but don't present the render buffer. Now you can just check the color of the pixel where the user touched and compare it against your list of object color ID's. Quick and easy, and it supports up to 16,581,375 unique objects.
You would have to parse every object of your scene and check the possible collision of each one of them with the ray you computed thanks to gluUnProject.
Depending on whether you want to select a face or an object, you could test the collision of the ray with bounding volumes (e.g. bounding box) of your objects for efficiency purposes.