public void CreatePrefabStateForSelection(PrefabState state, bool forceNewState = false) { if (!selectedPrefab) { return; } for (int i = 0; i < prefabStates.Count; i++) { if (prefabStates[i].prefab == selectedPrefab) { prefabStates[i].states.Add(state); return; } } PrefabStateHolder stateHolder = new PrefabStateHolder(selectedPrefab); if (forceNewState) { stateHolder.states.Add(new PrefabState("default")); } stateHolder.states.Add(state); prefabStates.Add(stateHolder); selectedPrefabStates = stateHolder.states; }
// Draw GUI controllers to be able to tweak settings via Unity editor // (this function is called by OnGUI function) public void Draw() { bool tempBool; int tempInt; EditorGUI.BeginChangeCheck(); tempBool = EditorGUILayout.Toggle("Show Grids", showGrids); if (EditorGUI.EndChangeCheck()) { Undo.RecordObject(this, "Toggle Show Grids"); showGrids = tempBool; } EditorGUI.BeginChangeCheck(); tempBool = EditorGUILayout.Toggle("Enabled", isEnabled); if (EditorGUI.EndChangeCheck()) { Undo.RecordObject(this, "Toggle Enabled"); isEnabled = tempBool; } if (!isEnabled) { GUI.enabled = false; } EditorGUI.BeginChangeCheck(); tempBool = EditorGUILayout.Toggle("Snap To Grid", snapToGrid); if (EditorGUI.EndChangeCheck()) { Undo.RecordObject(this, "Toggle Snap To Grid"); snapToGrid = tempBool; } GUI.enabled = true; // Draw horizontal line // Credit: http://answers.unity3d.com/questions/216584/horizontal-line.html GUILayout.Box("", GUILayout.ExpandWidth(true), GUILayout.Height(1)); if (currentState >= states.Count) { currentState = states.Count - 1; } GUILayout.BeginHorizontal(); EditorGUI.BeginChangeCheck(); tempInt = EditorGUILayout.Popup("State", currentState, statesPopup); if (EditorGUI.EndChangeCheck()) { Undo.RecordObject(this, "Change State"); currentState = tempInt; } Color c = GUI.color; GUI.color = Color.yellow; if (GUILayout.Button("+", GUILayout.Width(25f), GUILayout.Height(14f))) { Undo.RecordObject(this, "Create State"); CreateState(); currentState = states.Count - 1; UpdateStatesPopupList(); } if (states.Count <= 1) { GUI.enabled = false; } GUI.color = new Color(1f, 0.5f, 0.5f); if (GUILayout.Button("X", GUILayout.Width(25f), GUILayout.Height(14f))) { Undo.RecordObject(this, "Delete State"); states.RemoveAt(currentState); if (currentState >= states.Count) { currentState = states.Count - 1; } UpdateStatesPopupList(); } GUI.color = c; GUI.enabled = true; GUILayout.EndHorizontal(); states[currentState].Draw(this); // Draw horizontal line GUILayout.Box("", GUILayout.ExpandWidth(true), GUILayout.Height(1)); if (selectedPrefab != null) { GUI.enabled = false; EditorGUILayout.ObjectField("Prefab", selectedPrefab, typeof(GameObject), false); GUI.enabled = true; GUILayout.BeginHorizontal(); PrefabState state; bool isDefaultState; if (selectedPrefabStates == null || selectedPrefabStates.Count == 0) { if (defaultPrefabState == null) { defaultPrefabState = new PrefabState("default"); } EditorGUILayout.Popup("Prefab State", 0, prefabStatesPopup); state = defaultPrefabState; isDefaultState = true; } else { if (currentPrefabState >= selectedPrefabStates.Count) { currentPrefabState = selectedPrefabStates.Count - 1; } EditorGUI.BeginChangeCheck(); tempInt = EditorGUILayout.Popup("Prefab State", currentPrefabState, prefabStatesPopup); if (EditorGUI.EndChangeCheck()) { Undo.RecordObject(this, "Change Prefab State"); currentPrefabState = tempInt; } state = selectedPrefabStates[currentPrefabState]; isDefaultState = false; } GUI.color = Color.yellow; if (GUILayout.Button("+", GUILayout.Width(25f), GUILayout.Height(14f))) { Undo.RecordObject(this, "Create Prefab State"); CreatePrefabStateForSelection(new PrefabState("unnamed"), true); currentPrefabState = selectedPrefabStates.Count - 1; UpdatePrefabStatesPopupList(); } if (selectedPrefabStates == null || selectedPrefabStates.Count <= 1) { GUI.enabled = false; } GUI.color = new Color(1f, 0.5f, 0.5f); if (GUILayout.Button("X", GUILayout.Width(25f), GUILayout.Height(14f))) { Undo.RecordObject(this, "Delete Prefab State"); selectedPrefabStates.RemoveAt(currentPrefabState); if (currentPrefabState >= selectedPrefabStates.Count) { currentPrefabState = selectedPrefabStates.Count - 1; } UpdatePrefabStatesPopupList(); } GUI.color = c; GUI.enabled = true; GUILayout.EndHorizontal(); state.Draw(this, isDefaultState); } else { EditorGUILayout.HelpBox("No prefab is selected", MessageType.Info); } }
public PrefabState(string name, PrefabState copyFrom) { this.name = name; this.rotation = copyFrom.rotation; this.shift = copyFrom.shift; }
// Called each time Scene View updates void SceneUpdate(SceneView scenePanel) { // Draw gridlines on screen if (settings.showGrids) { DrawGridlines(scenePanel); } // If the framework is enabled if (settings.isEnabled && settings.Prefab != null) { PrefabState prefabSettings = settings.PrefabState; Event e = Event.current; if (e.type == EventType.KeyDown) { if (!keyDown) { if (e.keyCode == KeyCode.Q) { if (!e.control) { settings.RotateSelectedPrefab(-45f); } else { settings.PreviousPrefabState(); } Repaint(); keyDown = true; } else if (e.keyCode == KeyCode.E) { if (!e.control) { settings.RotateSelectedPrefab(45f); } else { settings.NextPrefabState(); } Repaint(); keyDown = true; } } } else if (e.type == EventType.KeyUp) { if (e.keyCode == KeyCode.Q || e.keyCode == KeyCode.E) { keyDown = false; } } if (e.isMouse) { // Find the position to show the preview object at Plane plane = new Plane(Vector3.up, new Vector3(0, gridYPos, 0)); Camera sceneCam = scenePanel.camera; Vector2 mousePos = e.mousePosition; mousePos.y = sceneCam.pixelRect.height - mousePos.y; Ray ray = sceneCam.ScreenPointToRay(mousePos); float distance; // Calculate at where mouse collides with the gridlines if (plane.Raycast(ray, out distance)) { Vector3 rayPos = ray.GetPoint(distance); // Snap the point if snapToGrid is enabled if (settings.snapToGrid) { rayPos.x -= gridShiftX; rayPos.z -= gridShiftZ; if (rayPos.x > 0) { rayPos.x = rayPos.x - rayPos.x % gridSize + gridSize * 0.5f; } else { rayPos.x = rayPos.x - rayPos.x % gridSize - gridSize * 0.5f; } if (rayPos.z > 0) { rayPos.z = rayPos.z - rayPos.z % gridSize + gridSize * 0.5f; } else { rayPos.z = rayPos.z - rayPos.z % gridSize - gridSize * 0.5f; } rayPos.x += gridShiftX; rayPos.z += gridShiftZ; } prefabPreview.position = rayPos + prefabSettings.shift; if (e.type == EventType.MouseDown) { if (e.button != 0) { rightMouseButtonDown = true; } else if (!leftMouseButtonDown) { leftMouseButtonDown = true; // If it is a "click" for instantiating the prefab if (!e.alt && !rightMouseButtonDown) { GUIUtility.hotControl = GUIUtility.GetControlID(GetHashCode(), FocusType.Passive); mousePressValid = true; GameObject instance = (GameObject)PrefabUtility.InstantiatePrefab(settings.Prefab); instance.transform.position = prefabPreview.position; instance.transform.eulerAngles = prefabSettings.rotation; Undo.RegisterCreatedObjectUndo(instance, "Create " + instance.name); } else { mousePressValid = false; } } } else if (e.type == EventType.MouseUp) { if (e.button != 0) { rightMouseButtonDown = false; } else { leftMouseButtonDown = false; if (mousePressValid && !rightMouseButtonDown) { mousePressValid = false; GUIUtility.hotControl = 0; } } } } } } }
// Called each time Scene View updates private void SceneUpdate(SceneView scenePanel) { // Draw gridlines on screen if (settings.showGrids) { DrawGridlines(scenePanel); } // If the framework is enabled if (settings.isEnabled && settings.Prefab != null) { PrefabState prefabSettings = settings.PrefabState; Event e = Event.current; if (e.type == EventType.KeyDown) { if (!keyDown) { if (e.keyCode == KeyCode.Q) { if (!e.control) { settings.RotateSelectedPrefab(-45f); } else { settings.PreviousPrefabState(); } Repaint(); keyDown = true; } else if (e.keyCode == KeyCode.E) { if (!e.control) { settings.RotateSelectedPrefab(45f); } else { settings.NextPrefabState(); } Repaint(); keyDown = true; } } } else if (e.type == EventType.KeyUp) { if (e.keyCode == KeyCode.Q || e.keyCode == KeyCode.E) { keyDown = false; } } if (e.isMouse) { // Find the position to show the preview object at Ray ray = HandleUtility.GUIPointToWorldRay(e.mousePosition); float distance; Plane plane; if (gridAlignment == GridAlignment.XZ) { plane = new Plane(Vector3.up, new Vector3(0, gridPos, 0)); } else if (gridAlignment == GridAlignment.XY) { plane = new Plane(Vector3.forward, new Vector3(0, 0, gridPos)); } else { plane = new Plane(Vector3.right, new Vector3(gridPos, 0, 0)); } // Calculate cursor's collision point with the gridlines if (plane.Raycast(ray, out distance)) { Vector3 rayPos = ray.GetPoint(distance); // Snap the point if snapToGrid is enabled if (settings.snapToGrid) { if (gridAlignment == GridAlignment.XZ) { rayPos.x -= gridShiftAxis1; rayPos.z -= gridShiftAxis2; if (rayPos.x > 0) { rayPos.x = rayPos.x - rayPos.x % gridSize + gridSize * 0.5f; } else { rayPos.x = rayPos.x - rayPos.x % gridSize - gridSize * 0.5f; } if (rayPos.z > 0) { rayPos.z = rayPos.z - rayPos.z % gridSize + gridSize * 0.5f; } else { rayPos.z = rayPos.z - rayPos.z % gridSize - gridSize * 0.5f; } rayPos.x += gridShiftAxis1; rayPos.z += gridShiftAxis2; } else if (gridAlignment == GridAlignment.XY) { rayPos.x -= gridShiftAxis1; rayPos.y -= gridShiftAxis2; if (rayPos.x > 0) { rayPos.x = rayPos.x - rayPos.x % gridSize + gridSize * 0.5f; } else { rayPos.x = rayPos.x - rayPos.x % gridSize - gridSize * 0.5f; } if (rayPos.y > 0) { rayPos.y = rayPos.y - rayPos.y % gridSize + gridSize * 0.5f; } else { rayPos.y = rayPos.y - rayPos.y % gridSize - gridSize * 0.5f; } rayPos.x += gridShiftAxis1; rayPos.y += gridShiftAxis2; } else { rayPos.y -= gridShiftAxis1; rayPos.z -= gridShiftAxis2; if (rayPos.y > 0) { rayPos.y = rayPos.y - rayPos.y % gridSize + gridSize * 0.5f; } else { rayPos.y = rayPos.y - rayPos.y % gridSize - gridSize * 0.5f; } if (rayPos.z > 0) { rayPos.z = rayPos.z - rayPos.z % gridSize + gridSize * 0.5f; } else { rayPos.z = rayPos.z - rayPos.z % gridSize - gridSize * 0.5f; } rayPos.y += gridShiftAxis1; rayPos.z += gridShiftAxis2; } } prefabPreview.position = rayPos + prefabSettings.shift; if (e.type == EventType.MouseDown) { if (e.button != 0) { rightMouseButtonDown = true; } else if (!leftMouseButtonDown) { leftMouseButtonDown = true; // If it is a "click" for instantiating the prefab if (!e.alt && !rightMouseButtonDown) { GUIUtility.hotControl = GUIUtility.GetControlID(GetHashCode(), FocusType.Passive); mousePressValid = true; GameObject instance; if (settings.Prefab.transform.root == settings.Prefab.transform) { instance = (GameObject)PrefabUtility.InstantiatePrefab(settings.Prefab); } else { instance = (GameObject)Instantiate(settings.Prefab); } instance.transform.position = prefabPreview.position; instance.transform.eulerAngles = prefabSettings.rotation; Undo.RegisterCreatedObjectUndo(instance, "Create " + instance.name); } else { mousePressValid = false; } } } else if (e.type == EventType.MouseUp) { if (e.button != 0) { rightMouseButtonDown = false; } else { leftMouseButtonDown = false; if (mousePressValid && !rightMouseButtonDown) { mousePressValid = false; GUIUtility.hotControl = 0; } } } } } } }
// Called each time Scene View updates private void SceneUpdate(SceneView scenePanel) { // Draw gridlines on screen if (showGrids) { DrawGridlines(scenePanel); } // If the framework is enabled if (!isEnabled || !settings.Prefab) { return; } PrefabState prefabSettings = settings.PrefabState; Event e = Event.current; if (e.type == EventType.KeyDown) { if (!rightMouseButtonDown && !keyDown) { if (e.keyCode == KeyCode.Q) { if (!e.control) { settings.RotateSelectedPrefab(-45f); } else { settings.PreviousPrefabState(); } Repaint(); keyDown = true; } else if (e.keyCode == KeyCode.E) { if (!e.control) { settings.RotateSelectedPrefab(45f); } else { settings.NextPrefabState(); } Repaint(); keyDown = true; } } } else if (e.type == EventType.KeyUp) { if (e.keyCode == KeyCode.Q || e.keyCode == KeyCode.E) { keyDown = false; } } if (e.isMouse) { // Find the position to show the preview object at Ray ray = HandleUtility.GUIPointToWorldRay(e.mousePosition); float distance; Plane plane; if (gridAlignment == GridAlignment.XZ) { plane = new Plane(Vector3.up, new Vector3(0, gridPos, 0)); } else if (gridAlignment == GridAlignment.XY) { plane = new Plane(Vector3.forward, new Vector3(0, 0, gridPos)); } else { plane = new Plane(Vector3.right, new Vector3(gridPos, 0, 0)); } // Calculate cursor's collision point with the gridlines if (!plane.Raycast(ray, out distance)) { return; } Vector3 rayPos = ray.GetPoint(distance); // Snap the point if snapToGrid is enabled if (snapToGrid) { if (gridAlignment == GridAlignment.XZ) { rayPos.x -= gridShiftAxis1; rayPos.z -= gridShiftAxis2; if (rayPos.x > 0) { rayPos.x = rayPos.x - rayPos.x % gridSize + gridSize * 0.5f; } else { rayPos.x = rayPos.x - rayPos.x % gridSize - gridSize * 0.5f; } if (rayPos.z > 0) { rayPos.z = rayPos.z - rayPos.z % gridSize + gridSize * 0.5f; } else { rayPos.z = rayPos.z - rayPos.z % gridSize - gridSize * 0.5f; } rayPos.x += gridShiftAxis1; rayPos.z += gridShiftAxis2; } else if (gridAlignment == GridAlignment.XY) { rayPos.x -= gridShiftAxis1; rayPos.y -= gridShiftAxis2; if (rayPos.x > 0) { rayPos.x = rayPos.x - rayPos.x % gridSize + gridSize * 0.5f; } else { rayPos.x = rayPos.x - rayPos.x % gridSize - gridSize * 0.5f; } if (rayPos.y > 0) { rayPos.y = rayPos.y - rayPos.y % gridSize + gridSize * 0.5f; } else { rayPos.y = rayPos.y - rayPos.y % gridSize - gridSize * 0.5f; } rayPos.x += gridShiftAxis1; rayPos.y += gridShiftAxis2; } else { rayPos.y -= gridShiftAxis1; rayPos.z -= gridShiftAxis2; if (rayPos.y > 0) { rayPos.y = rayPos.y - rayPos.y % gridSize + gridSize * 0.5f; } else { rayPos.y = rayPos.y - rayPos.y % gridSize - gridSize * 0.5f; } if (rayPos.z > 0) { rayPos.z = rayPos.z - rayPos.z % gridSize + gridSize * 0.5f; } else { rayPos.z = rayPos.z - rayPos.z % gridSize - gridSize * 0.5f; } rayPos.y += gridShiftAxis1; rayPos.z += gridShiftAxis2; } } prefabPreview.localPosition = rayPos + prefabSettings.shift; if (e.type == EventType.MouseDown) { if (e.button != 0) { rightMouseButtonDown = true; } else if (!leftMouseButtonDown) { leftMouseButtonDown = true; if (e.alt || rightMouseButtonDown) { mousePressValid = false; } else { GUIUtility.hotControl = GUIUtility.GetControlID(GetHashCode(), FocusType.Passive); mousePressValid = true; areaSpawnStartPos = prefabPreview.localPosition; areaSpawnLength1 = 0; areaSpawnLength2 = 0; } } } else if (e.type == EventType.MouseDrag) { Vector3 deltaPos = prefabPreview.localPosition - areaSpawnStartPos; if (gridAlignment == GridAlignment.XZ) { areaSpawnLength1 = Mathf.RoundToInt(deltaPos.x / gridSize); areaSpawnLength2 = Mathf.RoundToInt(deltaPos.z / gridSize); } else if (gridAlignment == GridAlignment.XY) { areaSpawnLength1 = Mathf.RoundToInt(deltaPos.x / gridSize); areaSpawnLength2 = Mathf.RoundToInt(deltaPos.y / gridSize); } else { areaSpawnLength1 = Mathf.RoundToInt(deltaPos.y / gridSize); areaSpawnLength2 = Mathf.RoundToInt(deltaPos.z / gridSize); } } else if (e.type == EventType.MouseUp) { if (e.button != 0) { rightMouseButtonDown = false; } else { leftMouseButtonDown = false; if (mousePressValid && !rightMouseButtonDown) { mousePressValid = false; GUIUtility.hotControl = 0; Vector3 spawnPosChange1, spawnPosChange2; if (gridAlignment == GridAlignment.XZ) { spawnPosChange1 = new Vector3(gridSize, 0f, 0f); spawnPosChange2 = new Vector3(0f, 0f, gridSize); } else if (gridAlignment == GridAlignment.XY) { spawnPosChange1 = new Vector3(gridSize, 0f, 0f); spawnPosChange2 = new Vector3(0f, gridSize, 0f); } else { spawnPosChange1 = new Vector3(0f, gridSize, 0f); spawnPosChange2 = new Vector3(0f, 0f, gridSize); } if (areaSpawnLength1 < 0) { spawnPosChange1 = -spawnPosChange1; areaSpawnLength1 = -areaSpawnLength1; } if (areaSpawnLength2 < 0) { spawnPosChange2 = -spawnPosChange2; areaSpawnLength2 = -areaSpawnLength2; } for (int i = 0; i <= areaSpawnLength1; i++) { for (int j = 0; j <= areaSpawnLength2; j++) { GameObject instance; if (settings.Prefab.transform.root == settings.Prefab.transform) { instance = (GameObject)PrefabUtility.InstantiatePrefab(settings.Prefab); } else { instance = (GameObject)Instantiate(settings.Prefab); } instance.transform.position = areaSpawnStartPos + spawnPosChange1 * i + spawnPosChange2 * j; instance.transform.eulerAngles = prefabSettings.rotation; Undo.RegisterCreatedObjectUndo(instance, "Create Object"); } } } } } } // Draw area spawn preview if (mousePressValid && leftMouseButtonDown && !rightMouseButtonDown) { Color c = Handles.color; Handles.color = Color.green; if (gridAlignment == GridAlignment.XZ) { Handles.DrawWireCube(areaSpawnStartPos + new Vector3(areaSpawnLength1, 0, areaSpawnLength2) * gridSize * 0.5f, new Vector3(Mathf.Abs(areaSpawnLength1) + 1, 0.1f, Mathf.Abs(areaSpawnLength2) + 1) * gridSize); } else if (gridAlignment == GridAlignment.XY) { Handles.DrawWireCube(areaSpawnStartPos + new Vector3(areaSpawnLength1, areaSpawnLength2, 0) * gridSize * 0.5f, new Vector3(Mathf.Abs(areaSpawnLength1) + 1, Mathf.Abs(areaSpawnLength2) + 1, 0.1f) * gridSize); } else { Handles.DrawWireCube(areaSpawnStartPos + new Vector3(0, areaSpawnLength1, areaSpawnLength2) * gridSize * 0.5f, new Vector3(0.1f, Mathf.Abs(areaSpawnLength1) + 1, Mathf.Abs(areaSpawnLength2) + 1) * gridSize); } Handles.color = c; } }