При создании собственных контролов в нативном UnityGUI зачастую используется метод GUIUtility.GetControlID(FocusType.Native), чтобы получить новый ID.
Однако данный способ имеет два существенных минуса
  1. Фактически метод просто выдает "следующее число" с некоторыми условиями. Поэтому ID четко привязан по порядку к предыдущим контролам. Если, например, убрать "кнопку" под условие, id всех следующих контролов после неё начнет "прыгать" в зависимости от отображения/сокрытия этой самой кнопки.
  2. Довольно сложно определить какой именно ID присвоен контролу. Для этого нужно вытащить этим же методом, ровно с теми же условиями число и вычесть из него N. Элементы часто могут содержать в себе другие элементы (и все с разными параметрами), потому точное выражение сложно вычислить без рефлектора.
Для решения этой проблемы можно использовать следующий метод для формирования ID:
	public static int GetHashID(params object[] fieldHashes)
    {
        if (fieldHashes == null || fieldHashes.Length < 1)
            return GUIUtility.GetControlID(FocusType.Native);
        int result = 17;
        for (int i = 0; i < fieldHashes.Length; ++i)
            result = result * 23 + fieldHashes[i].GetHashCode();
        return result;
    }
Где в качестве параметров подставлять более конкретную информацию (например, сам объект, название контрола, индекс). В результате мы имеем более стабильный ID, который легко достать по информации об объекте.
        var id = HandlesEx.GetHashID("HouseObject", "HoleNearPoint", obj, holeIndex);
`
ОЖИДАНИЕ РЕКЛАМЫ...
0
29
8 лет назад
0
Добавь в контрол поле ID и записывай туда GUID
0
27
8 лет назад
Отредактирован Devion
0
Добавь в контрол поле ID и записывай туда GUID
Извини алекс, но коммент не к теме. Это не винформс, нативный гуишник устроен иначе. Так делать не нужно.
Это к теме о GUILayout и подобном, в котором объектной модели нет вообще, все рисование зависит от "проходов". Классы ты там не строишь, и гуи отрисовываешь функционально.
Layout проход жует id в обязательном порядке чтобы автоматически рассчитывать макет.
Активность объектов жестко завязана на int'e
GUIUtility.hotControl
GUIUtility.keyboardControl
HandleUtility.nearestControl
HandleUtility.AddControl()
Event.current.GetTypeForControl()
и все такое.
Так же есть целый ряд методов, которые "жуют" ID для рисования, формирования новых эвентов и т.п.
В силу неконтролируемости данных и возможности изменять их извне налету об объектной модели даже нельзя заикаться, это будет неудачная попытка.
Потому все эти GUID'ы для этой системы - не подходят, они ж вообще стринговые и не информативные.
Вот скажем есть задача - нужно строго заставить редактор выделить третью точку в массиве меша - либо ты просто юзаешь так как сказал я, либо зачем-то заводишь служебный класс с гуидами и пытаешься синхронизировать его с объектами (и в результате все равно обламываешься, если юзер непредвиденно подменил меш).
Конечно проблему можно решить, начав запихивать эти данные в игровой билд, специальные классы делать для массивов и так далее, чтобы везде можно было поймать гуиды, под любым индексом, для любых данных, которые потом переводить в хеш. Но я считаю это дико некультурно и неправильно, тем более когда есть вот такое элегантное решение )
Чтобы оставить комментарий, пожалуйста, войдите на сайт.