2D Toolkit Forum

2D Toolkit => Support => Topic started by: TekuStudios on February 04, 2014, 04:03:30 pm

Title: [How To] Mix sprites and other 3D elements in your 2D game without sorting issue
Post by: TekuStudios on February 04, 2014, 04:03:30 pm
Hi there! We're posting here a workaround for the new Unity layer-and-sorting system, just in case you need something similar for your games. We are developing a sidescrolling tk2dSprite-based game, but we also have some 3D elements in our scenes such us particle effects and dynamically generated meshes (faked 2D planes with deformation physics simulating water), and we are using a Perspective camera as well. This made us face a very uncomfortable problem: all our sprites were being rendered in front of every other non-sprite elements in the scenes. The new Layer and SortingOrder properties are public yet only exposed in the Editor for the new Unity sprites (or tk2d ones).

So, as some of you may be facing similar trouble, I'm sharing our solution with you. We use a modified version for the Mesh Renderer that allows you to set the Layer Name and Sorting Order for every mesh-based GameObjects:

Code: [Select]
using UnityEngine;
using UnityEditor;
using System.Collections;

[CustomEditor(typeof(MeshRenderer))]

public class MeshRendererSortingLayersEditor : Editor
{
public override void OnInspectorGUI()
{
base.OnInspectorGUI();

MeshRenderer renderer = target as MeshRenderer;

EditorGUILayout.BeginHorizontal();

EditorGUI.BeginChangeCheck();

string name = EditorGUILayout.TextField("Sorting Layer Name", renderer.sortingLayerName);

if(EditorGUI.EndChangeCheck())
{
renderer.sortingLayerName = name;
}

EditorGUILayout.EndHorizontal();

EditorGUILayout.BeginHorizontal();

EditorGUI.BeginChangeCheck();

int order = EditorGUILayout.IntField("Sorting Order", renderer.sortingOrder);

if(EditorGUI.EndChangeCheck())
{
renderer.sortingOrder = order;
}

EditorGUILayout.EndHorizontal();
}
}

You just have to create a new C# script, paste that code into it and place it inside the Editor folder of your project so everytime you add the Mesh Renderer component to an object it will allow you to set its layer and rendering priority. Unfortunately, you have to set the Layer as a string name, so make sure you don't throw any typos in that field.

Hope you guys find it useful!
Title: Re: [How To] Mix sprites and other 3D elements in your 2D game without sorting issue
Post by: vinnie035 on April 02, 2014, 12:33:00 pm
Thanks guys for sharing this script.

Here is an improved version.

Code: [Select]
using System;
using UnityEngine;
using UnityEditor;
using UnityEditorInternal;
using System.Reflection;

[CanEditMultipleObjects()]
[CustomEditor(typeof(MeshRenderer))]
public class MeshRendererSortingLayersEditor : Editor
{
    Renderer renderer;
    string[] sortingLayerNames;
    int selectedOption;

    void OnEnable()
    {
        sortingLayerNames = GetSortingLayerNames();
        renderer = (target as Renderer).gameObject.renderer;

        for (int i = 0; i<sortingLayerNames.Length;i++)
        {
            if (sortingLayerNames[i] == renderer.sortingLayerName)
                selectedOption = i;
        }
    }

    public override void OnInspectorGUI()
    {
        DrawDefaultInspector();

if (!renderer) return;

EditorGUILayout.BeginHorizontal();
        selectedOption = EditorGUILayout.Popup("Sorting Layer", selectedOption, sortingLayerNames);
        if (sortingLayerNames[selectedOption] != renderer.sortingLayerName)
        {
            Undo.RecordObject(renderer, "Sorting Layer");
renderer.sortingLayerName = sortingLayerNames[selectedOption];
            EditorUtility.SetDirty(renderer);
        }
  EditorGUILayout.LabelField("(Id:" + renderer.sortingLayerID.ToString() + ")", GUILayout.MaxWidth(40));
EditorGUILayout.EndHorizontal();

        int newSortingLayerOrder = EditorGUILayout.IntField("Order in Layer", renderer.sortingOrder);
        if (newSortingLayerOrder != renderer.sortingOrder)
        {
            Undo.RecordObject(renderer, "Edit Sorting Order");
            renderer.sortingOrder = newSortingLayerOrder;
            EditorUtility.SetDirty(renderer);
        }
    }

    // Get the sorting layer names
    public string[] GetSortingLayerNames()
    {
        Type internalEditorUtilityType = typeof(InternalEditorUtility);
        PropertyInfo sortingLayersProperty = internalEditorUtilityType.GetProperty("sortingLayerNames", BindingFlags.Static | BindingFlags.NonPublic);
        return (string[])sortingLayersProperty.GetValue(null, new object[0]);
    }
}
Title: Re: [How To] Mix sprites and other 3D elements in your 2D game without sorting issue
Post by: TekuStudios on October 31, 2014, 06:45:28 pm
I completely overlooked your answer, vinnie. Thanks a lot for sharing!