예제 #1
0
        private static void CreateGhostWorld()
        {
            var sceneparams = new CreateSceneParameters(LocalPhysicsMode.Physics3D)
            {
            };

            ghostScene   = SceneManager.CreateScene("_GhostWorld", sceneparams);
            ghostPhysics = PhysicsSceneExtensions.GetPhysicsScene(ghostScene);
        }
예제 #2
0
        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();
        }
예제 #3
0
        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;
        }
예제 #4
0
        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();
            }
        }