2

Very odd problem, I have a Canvas object and I am trying to set the overrideSorting flag to true.

public void SetSortingLevel(string sortinglayerName)
{
    _canvas.overrideSorting = true;
    _canvas.sortingLayerName = sortinglayerName;
}

However, normally this works, however if I put a breakpoint and look at the code, even right after setting the override to true, it is false:

enter image description here

The api shows this is just a setter/getter. Any idea why this is happening?

I have used this code before and it normally works.

Note: This is a nested canvas so it should be allowed to have its sorting layer set.

Answer: As noted in the answer below, the activeInHierarchy check turns out to be false.

Aggressor
  • 13,323
  • 24
  • 103
  • 182

2 Answers2

7

This is by design. You can only change the value of Canvas.overrideSorting on nested canvas.

For example, if you have a Canvas which is root of other canvas or UI Objects, you won't be able to change the value of Canvas.overrideSorting.

If you have any Canvas which is a child of other Canvas, you will be able to change the value of Canvas.overrideSorting.

Requirements for changing Canvas.overrideSorting:

1.Canvas which is a child of other Canvas

  • Canvas //cannot change
    • Canvas //can change
      • Canvas //can change

2.The GameObject must be active in hierarchy and the Canvas component must be enabled in order to can change Canvas.overrideSorting.

Active in hierarchy means that all the parent Canvas GameObject of the Canvas you want to change its Canvas.overrideSorting must be active and the Canvas script itself must be enabled. This can be verified with the gameObject.activeInHierarchy property.

If Canvas.gameObject.activeInHierarchy is not true, you cannot set or change the Canvas.overrideSorting property. It is better to check those properties before attempting to change Canvas.overrideSorting.

if (_canvas.gameObject.activeInHierarchy && _canvas.enabled)
    _canvas.overrideSorting = true;
else
    Debug.Log("Cannot change Canvas overrideSorting");
Programmer
  • 121,791
  • 22
  • 236
  • 328
  • Yes something I did not make clear in my example, but this is a nested canvas. – Aggressor Aug 24 '18 at 20:59
  • That's fine. Was in the middle of an edit before your comment. See my edit. – Programmer Aug 24 '18 at 20:59
  • All good points but they checkout fine. I am basically ingratiating some prefabs, adding them to the parent (which has a parent canvas) and trying to set their override. If I go into the inspector and manually set the flags it works, it's just not working in the the code. – Aggressor Aug 24 '18 at 21:05
  • 1
    It doesn't matter if you can manually set them in the Editor. What I said in the answer applies to the code you're using. I noticed a ! typo in my answer and also didn't add the enable check. Check if `if (_canvas.gameObject.activeInHierarchy && _canvas.enabled)` is true . If this is not true, it won't work. I have verified this on my side. Just use `if (_canvas.gameObject.activeInHierarchy && _canvas.enabled)` to verify. Let me know. – Programmer Aug 24 '18 at 21:29
  • the activeInHierarchy was false. – Aggressor Aug 24 '18 at 21:35
  • @Aggressor Yup. Figured that or _canvas.enabled was the issue. Glad I was able to help – Programmer Aug 24 '18 at 21:36
  • I feel this is a silent error yes? Perhaps unity should add a flag? – Aggressor Aug 24 '18 at 21:36
  • 1
    They just need to update their doc to say what's in my answer. It doesn't throw error. I think they do some check for these two on the native side before changing that property. Sometimes, there doc i not up to date – Programmer Aug 24 '18 at 21:37
2

You need to wait for one frame.

private void Start()
{
    Canvas canvas = GetComponent<Canvas>();
    StartCoroutine(OneFrame(() => { canvas.overrideSorting = true; }));
}

private IEnumerator OneFrame(Action callback)
{
    yield return null;
    callback();
}