Last active
October 31, 2018 04:02
-
-
Save jordyhenry/ca2823705cb39c0c965fdf1cd3b3c19d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Read the article about this script on : https://medium.com/return-of-the-jordy/dealing-with-unity-ui-hierarchy-db2ff05e01b0 | |
*/ | |
using UnityEngine; | |
using UnityEditor; | |
[ExecuteInEditMode] | |
public class UIFocusMode : MonoBehaviour | |
{ | |
#if UNITY_EDITOR | |
private Transform container; | |
[Header("ENABLE ALL CONTAINERS")] | |
public bool OnSelectNothing = false; | |
public bool OnSelectOnAnotherRoot = false; | |
public bool OnSelectItself = false; | |
public bool OnSelectOwnRoot = false; | |
public bool OnSelectOnSibling = false; | |
private void Awake() | |
{ | |
if(transform == transform.root) | |
{ | |
Debug.LogError("Dont work in root objects !"); | |
return; | |
} | |
container = transform; | |
Selection.selectionChanged += OnSelectionChange; | |
} | |
private void OnDestroy() | |
{ | |
if (container == null) return; | |
ToggleAll(true); | |
Selection.selectionChanged -= OnSelectionChange; | |
} | |
private void OnSelectionChange() | |
{ | |
Transform selectedTransform = Selection.activeTransform; | |
if(ShouldReturn(selectedTransform)) return; | |
int stepsFromContainer = CalculateStepsFromContainer(selectedTransform); | |
ActivateSelectedContainer(stepsFromContainer, selectedTransform); | |
} | |
private bool ShouldReturn(Transform t) | |
{ | |
if (t == null) { | |
if (OnSelectNothing) | |
ToggleAll(true); | |
return true; | |
} | |
if (t.root != container.root) | |
{ | |
if(OnSelectOnAnotherRoot) | |
ToggleAll(true); | |
return true; | |
} | |
if(t == container) | |
{ | |
if (OnSelectItself) | |
ToggleAll(true); | |
return true; | |
} | |
if(t == container.root) | |
{ | |
if (OnSelectOwnRoot) | |
ToggleAll(true); | |
return true; | |
} | |
if(!IsInsideOfContainer(t)) | |
{ | |
if (OnSelectOnSibling) | |
ToggleAll(true); | |
return true; | |
} | |
return false; | |
} | |
private bool IsInsideOfContainer(Transform t) | |
{ | |
bool isInside = false; | |
while (t.parent != null) | |
{ | |
if(t == container) | |
{ | |
isInside = true; | |
break; | |
} | |
t = t.parent; | |
} | |
return isInside; | |
} | |
private int CalculateStepsFromContainer(Transform t) | |
{ | |
int _stepsFromContainer = 0; | |
while (t != container) | |
{ | |
_stepsFromContainer++; | |
t = t.parent; | |
//Lets say that Im little paranoic about 'while' loops | |
if (_stepsFromContainer > 100) | |
break; | |
} | |
return _stepsFromContainer; | |
} | |
private void ToggleAll(bool option) | |
{ | |
for (int i = 0; i < container.childCount; i++) | |
{ | |
container.GetChild(i).gameObject.SetActive(option); | |
} | |
} | |
private void ActivateSelectedContainer(int levels, Transform t) | |
{ | |
Transform selectedContainer = t; | |
for (int i = 0; i < levels - 1; i++) | |
{ | |
selectedContainer = selectedContainer.parent; | |
} | |
ToggleAll(false); | |
selectedContainer.gameObject.SetActive(true); | |
} | |
#endif | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment