private static void CreateGhostWorld() { var sceneparams = new CreateSceneParameters(LocalPhysicsMode.Physics3D) { }; ghostScene = SceneManager.CreateScene("_GhostWorld", sceneparams); ghostPhysics = PhysicsSceneExtensions.GetPhysicsScene(ghostScene); }
private void OnValidate() { // https://forum.unity.com/threads/raycast-in-the-prefab-scene.647548/#post-4339375 var s = gameObject.scene; if (s.IsValid() && PhysicsSceneExtensions.GetPhysicsScene(s).IsValid()) { m_PhysicsScene = PhysicsSceneExtensions.GetPhysicsScene(s); } Shape.OnValidate(); }
protected virtual void HandleValidate() { // https://forum.unity.com/threads/raycast-in-the-prefab-scene.647548/#post-4339375 var scene = gameObject.scene; m_PhysicsScene = scene.IsValid() && PhysicsSceneExtensions.GetPhysicsScene(scene).IsValid() ? PhysicsSceneExtensions.GetPhysicsScene(scene) : Physics.defaultPhysicsScene; m_Shape.RequireScanEvent -= ScanShape; m_Shape.RequireScanEvent += ScanShape; }
void RendererPreview() { using (new EditorGUILayout.VerticalScope()) { var rect = GUILayoutUtility.GetRect(512f, 512f); previewRender.BeginPreview(rect, GUIStyle.none); var previewCam = previewRender.camera; if (rect.Contains(Event.current.mousePosition)) { if (Event.current.type == EventType.MouseDrag && Event.current.button == 1) { ResetRange(); var drag = Event.current.delta; if (drag != Vector2.zero) { previewCam.transform.RotateAround(centerPos, previewCam.transform.rotation * Vector3.up, drag.x); previewCam.transform.RotateAround(centerPos, previewCam.transform.rotation * Vector3.right, drag.y); Repaint(); } } else if (Event.current.type == EventType.MouseDrag && Event.current.button == 2) { ResetRange(); var drag = Event.current.delta; if (drag != Vector2.zero) { drag.x *= -1f; var limit = Mathf.Max(new float[] { bounds.extents.x, bounds.extents.y, bounds.extents.z }); var deltaPos = previewCam.transform.rotation * drag * 0.002f; deltaPos.x = Mathf.Clamp(deltaPos.x + centerPos.x, -limit, limit) - centerPos.x; deltaPos.y = Mathf.Clamp(deltaPos.y + centerPos.y, -limit, limit) - centerPos.y; deltaPos.z = Mathf.Clamp(deltaPos.z + centerPos.z, -limit, limit) - centerPos.z; centerPos += deltaPos; previewCam.transform.position += deltaPos; Repaint(); } } else if (Event.current.type == EventType.ScrollWheel) { var scroll = Event.current.delta.y; if (scroll != 0) { var cameraPos = previewCam.transform.position - centerPos; var farLimit = bounds.size.magnitude * 4f; previewCam.transform.position = centerPos + cameraPos.normalized * Mathf.Clamp(cameraPos.magnitude + scroll * 0.1f, 0.01f, farLimit); Repaint(); } } else if (Event.current.type == EventType.MouseDrag && Event.current.button == 0) { dragEndPosition = Event.current.mousePosition; if (dragBeginPosition == Vector2.zero) { dragBeginPosition = dragEndPosition; } Repaint(); } else if (Event.current.type == EventType.MouseDown && Event.current.button == 0) { ResetRange(); dragBeginPosition = Event.current.mousePosition; dragEndPosition = dragBeginPosition; } else if (Event.current.type == EventType.MouseUp && Event.current.button == 0) { var endRay = MouseToRay(Event.current.mousePosition, rect, previewCam); var beginRay = MouseToRay(dragBeginPosition, rect, previewCam); var physicsScene = PhysicsSceneExtensions.GetPhysicsScene(previewCam.scene); try { Physics.queriesHitBackfaces = true; if (dragBeginPosition == dragEndPosition) { RaycastHit hit; physicsScene.Raycast(endRay.origin, endRay.direction, out hit, 10f); if (hit.collider) { PushInactiveGO(new HashSet <GameObject>() { hit.collider.gameObject }); } } else { var position = (endRay.origin + beginRay.origin) * 0.5f + 5f * endRay.direction; var rotation = Quaternion.LookRotation(endRay.direction, previewCam.transform.up); var size = previewCam.transform.InverseTransformPoint(endRay.origin) - previewCam.transform.InverseTransformPoint(beginRay.origin); size.x = Math.Abs(size.x * 0.5f); size.y = Math.Abs(size.y * 0.5f); size.z = 10f; var cols = s_OverlapBoxMethodInfo.Invoke(null, new object[] { physicsScene, position, size, rotation, Physics.AllLayers, QueryTriggerInteraction.UseGlobal }) as Collider[]; if (cols.Length > 0) { PushInactiveGO(cols.Select(c => c.gameObject)); } } } catch { throw; } finally { Physics.queriesHitBackfaces = false; } Repaint(); ResetRange(); } } else if (Event.current.type != EventType.Layout) { ResetRange(); } previewCam.nearClipPlane = Mathf.Sqrt(bounds.SqrDistance(previewCam.transform.position)) + 0.001f; previewCam.farClipPlane = bounds.size.magnitude + previewCam.nearClipPlane; previewCam.Render(); previewRender.EndAndDrawPreview(rect); EditorGUI.DrawRect(new Rect(dragBeginPosition, dragEndPosition - dragBeginPosition), s_RangeColor); using (new EditorGUILayout.HorizontalScope()) { EditorGUI.BeginChangeCheck(); backgroundColor = EditorGUILayout.ColorField("Background Color", backgroundColor); if (EditorGUI.EndChangeCheck()) { previewCam.backgroundColor = backgroundColor; Repaint(); } GUILayout.FlexibleSpace(); using (new EditorGUI.DisabledGroupScope(inactiveGOs.Count == 0)) { if (GUILayout.Button("Undo")) { UndoInactiveGO(); } if (GUILayout.Button("Reset")) { while (inactiveGOs.Count > 0) { UndoInactiveGO(); } } } GUILayout.FlexibleSpace(); } } }
private void OnGUI() { // Find max label width. var maxLabelWidth = 110.0f; for (int i = 0; i < lxfml.groups.Length; i++) { var size = EditorStyles.boldLabel.CalcSize(new GUIContent(lxfml.groups[i].name)); maxLabelWidth = Mathf.Max(maxLabelWidth, size.x); } minSize = new Vector2(leftMargin + maxLabelWidth + 360, 226); maxSize = new Vector2(leftMargin + maxLabelWidth + 360, 2000); scrollPosition = GUILayout.BeginScrollView(scrollPosition, false, false); GUI.Box(new Rect(20, 20, 100, 100), logoTexture); CreateHeaderUI(new Vector2(leftMargin + maxLabelWidth + 20.0f, 100.0f), "Colliders", "Add colliders to bricks."); CreateHeaderUI(new Vector2(leftMargin + maxLabelWidth + 50.0f, 100.0f), "Connectivity", "Add connectivity to bricks. Connectivity requires colliders."); CreateHeaderUI(new Vector2(leftMargin + maxLabelWidth + 100.0f, 100.0f), "Static", "Make bricks static."); CreateHeaderUI(new Vector2(leftMargin + maxLabelWidth + 130.0f, 100.0f), "Lightmapped", "Add lightmap UVs to bricks. Bricks must be static to be lightmapped."); CreateHeaderUI(new Vector2(leftMargin + maxLabelWidth + 180.0f, 100.0f), "Randomize Rotation", "Slightly rotate bricks to improve realism."); CreateHeaderUI(new Vector2(leftMargin + maxLabelWidth + 230.0f, 100.0f), "Prefer Legacy", "Prefer legacy geometry over new geometry."); CreateHeaderUI(new Vector2(leftMargin + maxLabelWidth + 280.0f, 100.0f), "LOD", "LOD 0 includes chamfered edges.\nLOD 1 does not.\nLOD 2 simplifies knobs."); // Reserve the space for the GUILayout scroll view. GUILayout.Space(135.0f); var nextY = 135.0f; var showAllBoolsUI = model == null && group == null && lxfml.groups.Length > 1; // When importing a new model, just check if there is more than one lxfml group. showAllBoolsUI |= model != null && importSettings.Count > 1; // When reimporting an entire model, check if the existing model has more than one group. if (showAllBoolsUI) { CreateAllBoolsUI(new Vector2(leftMargin + maxLabelWidth + 15.0f, nextY), importSettings, "colliders", "connectivity", null); CreateAllBoolsUI(new Vector2(leftMargin + maxLabelWidth + 45.0f, nextY), importSettings, "connectivity", null, "colliders"); CreateAllBoolsUI(new Vector2(leftMargin + maxLabelWidth + 95.0f, nextY), importSettings, "isStatic", "lightmapped", null); CreateAllBoolsUI(new Vector2(leftMargin + maxLabelWidth + 125.0f, nextY), importSettings, "lightmapped", null, "isStatic"); CreateAllBoolsUI(new Vector2(leftMargin + maxLabelWidth + 175.0f, nextY), importSettings, "randomizeRotation"); CreateAllBoolsUI(new Vector2(leftMargin + maxLabelWidth + 225.0f, nextY), importSettings, "preferLegacy"); CreateAllLODsUI(new Vector2(leftMargin + maxLabelWidth + 275.0f, nextY), importSettings); // Reserve the space for the GUILayout scroll view. GUILayout.Space(25.0f); nextY += 25.0f; } var collidersOrConnectivityWhilePreferringLegacy = false; for (int i = 0; i < lxfml.groups.Length; i++) { var showGroup = group == null && model == null; // When importing a new model, show all groups. showGroup |= model != null && importSettings.ContainsKey(i); // When reimporting an entire model, only show groups already in the existing model. showGroup |= group != null && i == group.number; // When reimporting a model group, only show that group. if (showGroup) { GUI.Label(new Rect(leftMargin, nextY, maxLabelWidth, 20.0f), lxfml.groups[i].name); CreateBoolUI(new Vector2(leftMargin + maxLabelWidth + 15.0f, nextY), importSettings, "colliders", i, "connectivity", null); CreateBoolUI(new Vector2(leftMargin + maxLabelWidth + 45.0f, nextY), importSettings, "connectivity", i, null, "colliders"); CreateBoolUI(new Vector2(leftMargin + maxLabelWidth + 95.0f, nextY), importSettings, "isStatic", i, "lightmapped", null); CreateBoolUI(new Vector2(leftMargin + maxLabelWidth + 125.0f, nextY), importSettings, "lightmapped", i, null, "isStatic"); CreateBoolUI(new Vector2(leftMargin + maxLabelWidth + 175.0f, nextY), importSettings, "randomizeRotation", i); CreateBoolUI(new Vector2(leftMargin + maxLabelWidth + 225.0f, nextY), importSettings, "preferLegacy", i); CreateLODUI(new Vector2(leftMargin + maxLabelWidth + 275.0f, nextY), importSettings, i); if ((importSettings[i].colliders || importSettings[i].connectivity) && importSettings[i].preferLegacy) { collidersOrConnectivityWhilePreferringLegacy = true; } // Reserve the space for the GUILayout scroll view. GUILayout.Space(20.0f); nextY += 20.0f; } } if (collidersOrConnectivityWhilePreferringLegacy) { EditorGUI.HelpBox(new Rect(leftMargin, nextY, position.width - leftMargin - 20.0f, 38.0f), "Legacy parts might not contain colliders or connectivity information.", MessageType.Warning); // Reserve the space for the GUILayout scroll view. GUILayout.Space(42.0f); nextY += 42.0f; } // Reserve the space for the GUILayout scroll view. GUILayout.Space(5.0f); nextY += 5.0f; // Only show pivot option when not reimporting. if (group == null && model == null) { GUI.Label(new Rect(leftMargin, nextY, maxLabelWidth, 20.0f), "Pivot"); pivot = (Model.Pivot)EditorGUI.EnumPopup(new Rect(leftMargin + maxLabelWidth + 15.0f, nextY, 126.0f, 16.0f), pivot); // Reserve the space for the GUILayout scroll view. GUILayout.Space(25.0f); nextY += 25.0f; } // Create the right import/reimport button and handle the import/reimport based on the three cases: // - Reimport model // - Reimport model group // - Import model bool importPressed; if (model) { // ---------------------- // Reimport entire model. // ---------------------- importPressed = GUI.Button(new Rect(leftMargin, nextY, maxLabelWidth + 15.0f + 126.0f, 32.0f), "Reimport Model"); if (importPressed) { // Register undo. Undo.RegisterFullObjectHierarchyUndo(model.gameObject, "Reimport"); model.pivot = pivot; // Update the path if it is new. if (filePath != null) { model.absoluteFilePath = filePath; model.relativeFilePath = PathUtils.GetRelativePath(Directory.GetCurrentDirectory(), filePath); } ModelImporter.ReimportModel(lxfml, model, importSettings); var prefabStage = PrefabStageUtility.GetCurrentPrefabStage(); if (prefabStage != null) { EditorSceneManager.MarkSceneDirty(prefabStage.scene); } SceneBrickBuilder.MarkSceneDirty(); } } else if (group) { // --------------------- // Reimport model group. // --------------------- importPressed = GUI.Button(new Rect(leftMargin, nextY, maxLabelWidth + 15.0f + 126.0f, 32.0f), "Reimport Model Group"); if (importPressed) { // Register undo. Undo.RegisterFullObjectHierarchyUndo(group.gameObject, "Reimport"); ModelImporter.ReimportModelGroup(lxfml, group, importSettings[group.number], true); var prefabStage = PrefabStageUtility.GetCurrentPrefabStage(); if (prefabStage != null) { EditorSceneManager.MarkSceneDirty(prefabStage.scene); } SceneBrickBuilder.MarkSceneDirty(); } } else { // ---------------------- // Import model. // ---------------------- importPressed = GUI.Button(new Rect(leftMargin, nextY, maxLabelWidth + 15.0f + 126.0f, 32.0f), "Import Model"); if (importPressed) { model = ModelImporter.InstantiateModel(lxfml, filePath, pivot, importSettings).GetComponent <Model>(); } var camera = SceneView.lastActiveSceneView.camera; if (camera && model) { var cameraRay = new Ray(camera.transform.position, camera.transform.forward); PhysicsScene physicsScene; if (PrefabStageUtility.GetCurrentPrefabStage() != null) { physicsScene = PrefabStageUtility.GetCurrentPrefabStage().scene.GetPhysicsScene(); } else { physicsScene = PhysicsSceneExtensions.GetPhysicsScene(EditorSceneManager.GetActiveScene()); } var bricksInModel = model.GetComponentsInChildren <Brick>(); var bricks = new HashSet <Brick>(bricksInModel); var sourceBrick = bricks.First(); BrickBuildingUtility.AlignBricks(sourceBrick, bricks, BrickBuildingUtility.ComputeBounds(bricks), sourceBrick.transform.position, Vector3.zero, cameraRay, new Plane(Vector3.up, Vector3.zero), 100.0f, out Vector3 offset, out Vector3 alignedOffset, out _, out _); var offsetPosition = model.transform.position + alignedOffset; model.transform.position = offsetPosition; Selection.activeGameObject = model.gameObject; Physics.SyncTransforms(); } SceneBrickBuilder.MarkSceneDirty(); } // Reserve the space for the GUILayout scroll view. GUILayout.Space(36.0f); nextY += 36.0f; // List tracked errors. foreach (var trackedError in trackedErrors) { EditorGUI.HelpBox(new Rect(leftMargin, nextY, maxLabelWidth + 340.0f, 38.0f), trackedError.Key, MessageType.Warning); // Reserve the space for the GUILayout scroll view. GUILayout.Space(42.0f); nextY += 42.0f; foreach (var id in trackedError.Value) { GUI.Label(new Rect(leftMargin, nextY, maxLabelWidth + 340.0f, 16.0f), id); // Reserve the space for the GUILayout scroll view. GUILayout.Space(20.0f); nextY += 20.0f; } } GUILayout.EndScrollView(); if (importPressed) { this.Close(); } }