/** * Go through all the data value arrays for each DieSide, resizing it when necessary. */ private void ensureDataValueCountPerSide() { DieSides dieSides = target as DieSides; for (int i = 0; i < _dieSides.arraySize; i++) { SerializedProperty dieSide = _dieSides.GetArrayElementAtIndex(i); SerializedProperty dieSideData = dieSide.FindPropertyRelative(_dieSideValuesPropertyName); //if no resizing is needed, skip if (_valueCountPerSide.intValue == dieSideData.arraySize) continue; //if it is less, just set array size this will delete the superfluous values if (_valueCountPerSide.intValue < dieSideData.arraySize) { dieSideData.arraySize = _valueCountPerSide.intValue; } else { //if required number of values is bigger than what we got, //insert empty elements at the end while (_valueCountPerSide.intValue > dieSideData.arraySize) { dieSideData.InsertArrayElementAtIndex(dieSideData.arraySize); dieSideData.GetArrayElementAtIndex(dieSideData.arraySize - 1).intValue = i; } } //data can be missing until serialized object is applied, so we need to check //whether the side is actually already there to update if (i < dieSides.dieSideCount) dieSides.GetDieSide(i).DirtyStringCache(); } }
/** * Draws debug info about the selected die: normals & values. */ void OnSceneGUI() { if (Selection.gameObjects.Length > 1 || !_debugViewOn) return; DieSides dieSides = target as DieSides; if (dieSides != null && dieSides.dieSideCount > 0) { //get the closest side match for the current orientation so we //can apply pretty colors DieSideMatchInfo dieSideMatchInfo = dieSides.GetDieSideMatchInfo(); DieSide current = dieSideMatchInfo.closestMatch; for (int i = 0; i < dieSides.dieSideCount; i++) { if (_highlightedIndex != -1 && _highlightedIndex != i) continue; DieSide dieSide = dieSides.GetDieSide(i); Vector3 worldPos = dieSides.transform.TransformPoint(dieSide.centerPoint); Vector3 worldNormal = dieSides.transform.TransformDirection(dieSide.normal); Vector3 endPos = worldPos + worldNormal * _labelDrawDistance; Color color = Color.green; Color labelColor = _labelDrawColor; //should we apply our regular red/green color scheme or should we make this //element blink because we selected it? if (_highlightedIndex == i && Math.Floor(Time.realtimeSinceStartup * 5) % 2 == 0) { color = Color.yellow; labelColor = Color.yellow; } else { color = dieSide == current ? Color.green : Color.red; } GUIStyle guiStyle = new GUIStyle(); guiStyle.fontSize = 20; guiStyle.normal.textColor = labelColor; Handles.zTest = UnityEngine.Rendering.CompareFunction.LessEqual; Handles.color = color; Handles.DrawLine(worldPos, endPos); Handles.Label(endPos, "[" + i + "]=" + dieSide.ValuesAsString(), guiStyle); } } SceneView.RepaintAll(); }
/** * For each side, show its data manipulation UI. */ private void showDataSideManipulationUI(int pSideIndex, DieSideMatchInfo pDieSideMatchInfo) { DieSides dieSides = target as DieSides; Color defaultColor = GUI.backgroundColor; EditorGUILayout.BeginHorizontal(); if (_highlightedIndex == pSideIndex) GUI.backgroundColor = Color.yellow; string sideLabel = "Side " + pSideIndex + " = "; _sideLabelStyle.normal.textColor = Color.black; if (pDieSideMatchInfo != null && pDieSideMatchInfo.closestMatch == dieSides.GetDieSide(pSideIndex)) { _sideLabelStyle.normal.textColor = pDieSideMatchInfo.isExactMatch ? darkGreen : darkBlue; } EditorGUILayout.LabelField(sideLabel, _sideLabelStyle, _sideLabelOptions); //show entry fields for all entries in the data array SerializedProperty dieSide = _dieSides.GetArrayElementAtIndex(pSideIndex); SerializedProperty dataArray = dieSide.FindPropertyRelative(_dieSideValuesPropertyName); EditorGUI.BeginChangeCheck(); SerializedProperty element; for (int i = 0; i < dataArray.arraySize; i++) { element = dataArray.GetArrayElementAtIndex(i); //set the next controlname to sideLabel so we can focus on it GUI.SetNextControlName(pSideIndex+"_"+i); //we have to do it like this unfortunately becauses the focus mechanism doesn't //work well with EditorGUILayout.IntField //string value = GUILayout.TextField("" + element.intValue, _dataValueOptions); //int intValue; //int.TryParse(value, out intValue); //element.intValue = intValue; element.intValue = EditorGUILayout.IntField(element.intValue, _dataValueOptions); } if (EditorGUI.EndChangeCheck()) { dieSides.GetDieSide(pSideIndex).DirtyStringCache(); } //show a toggle button for rotating and highlight //and update our highlight index accordingly if pressed bool currentHighLight = _highlightedIndex == pSideIndex; bool newHighLight = GUILayout.Toggle(_highlightedIndex == pSideIndex, _rotateButtonContent, "Button", _smallEditorButtonOptions); if (currentHighLight != newHighLight) { _highlightedIndex = (_highlightedIndex == pSideIndex) ? -1 : pSideIndex; if (_highlightedIndex != -1) { EditorGUI.FocusTextInControl(_highlightedIndex + "_0"); //GUI.FocusControl(_highlightedIndex + "_0"); } //rotate our die so that this value/side becomes activated dieSides.transform.rotation = dieSides.GetWorldRotationFor(pSideIndex); if (!Application.isPlaying) EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene()); } EditorGUILayout.EndHorizontal(); GUI.backgroundColor = defaultColor; }