Пример #1
0
        /**
         *	\brief Draws a preview mesh with no collisions from a List<Vector2> of user points.
         *	This function accepts 2d points and converts them to world point vertices, triangulates, and draws a mesh.  It does not create collisions, and will be deleted on finalizing an object.  See also DestroyPreviewMesh(), CleanUp(), RefreshPreview().
         *	@param _points List of user points.  Assumed to be in world space (use ScreenToWorldPoint(screenPoint) where screenPoint is typically Input.mousePosition ).
         */
        public void DrawPreviewMesh(List <Vector2> _points)
        {
            if (_points.Count < 3)
            {
                return;
            }

            // Create the mesh
            if (previewGameObject == null)
            {
                previewGameObject = new GameObject();
                previewGameObject.AddComponent <MeshFilter>();
                previewGameObject.GetComponent <MeshFilter>();
                previewGameObject.AddComponent <MeshRenderer>();
            }

            Mesh        m, c;
            PolygonType convexity;

            DrawUtility.MeshWithPoints(_points, drawSettings, out m, out c, out convexity);

            previewGameObject.GetComponent <MeshFilter>().sharedMesh = m;

            Material[] mats = (drawSettings.generateSide) ?
                              new Material[2] {
                drawSettings.frontMaterial, drawSettings.sideMaterial
            } :
            new Material[1] {
                drawSettings.frontMaterial
            };

            previewGameObject.GetComponent <MeshRenderer>().sharedMaterials = mats;
        }
Пример #2
0
        /**
         *	\brief Draws planes around the edges of a mesh.
         *	@param _points The points to use as a guide.
         *	@param _modifier Multiply plane X and Y dimensions component wise.
         */
        public void DrawEdgePlanes(List <Vector2> _points, PolygonType convexity, Vector2 _modifier, float area)
        {
            Vector2[] points = _points.ToArray();

            if (convexity == PolygonType.ConcaveClockwise || convexity == PolygonType.ConvexClockwise)
            {
                Array.Reverse(points);
            }

            for (int i = 0; i < points.Length; i++)
            {
                float x1, x2, y1, y2;
                x1 = points[i].x;
                y1 = points[i].y;

                if (i > points.Length - 2)
                {
                    x2 = points[0].x;
                    y2 = points[0].y;
                }
                else
                {
                    x2 = points[i + 1].x;
                    y2 = points[i + 1].y;
                }

                float length = Vector2.Distance(new Vector2(x1, y1), new Vector2(x2, y2));
                length *= drawSettings.edgeLengthModifier;

                if (length < drawSettings.minLengthToDraw)
                {
                    continue;
                }

                float angle = Mathf.Atan2(y2 - y1, x2 - x1) * Mathf.Rad2Deg;

                if (Mathf.Abs(angle) > 180 - drawSettings.maxAngle && Mathf.Abs(angle) < 180 + drawSettings.maxAngle)
                {
                    ;
                }
                else
                {
                    continue;
                }

                GameObject boxColliderObj = new GameObject();

                boxColliderObj.AddComponent <MeshFilter>().sharedMesh = MeshPlane();
                boxColliderObj.AddComponent <MeshRenderer>();
                boxColliderObj.name = "EdgePlane " + angle;

                boxColliderObj.transform.position = new Vector3(((x1 + x2) / 2f), ((y1 + y2) / 2f), drawSettings.zPosition + drawSettings.edgeOffset);


                boxColliderObj.GetComponent <MeshRenderer>().sharedMaterial = drawSettings.edgeMaterial;
                Vector2[] uvs = boxColliderObj.GetComponent <MeshFilter>().sharedMesh.uv;

                float imgScale = 1f;
                if (drawSettings.edgeMaterial != null)
                {
                    imgScale = ((float)drawSettings.edgeMaterial.mainTexture.width / drawSettings.edgeMaterial.mainTexture.height);
                }

                boxColliderObj.GetComponent <MeshFilter>().sharedMesh.uv = DrawUtility.ArrayMultiply(uvs, new Vector2(length / imgScale, 1f)).ToArray();

                if (drawSettings.areaRelativeHeight)
                {
                    boxColliderObj.transform.localScale = new Vector3(
                        length,
                        Mathf.Clamp(Mathf.Abs(area) * drawSettings.edgeHeight,
                                    drawSettings.minEdgeHeight,
                                    drawSettings.maxEdgeHeight),
                        2f);
                }
                else
                {
                    boxColliderObj.transform.localScale = new Vector3(length, drawSettings.edgeHeight, 2f);
                }

                boxColliderObj.transform.rotation = Quaternion.Euler(new Vector3(0f, 0f, angle));

                boxColliderObj.transform.parent = LastDrawnObject.transform;
            }
        }
Пример #3
0
        /**
         *	\brief Creates a mesh and applies all collisions and physics components.
         *	This method accepts user points and creates a new gameObject with a mesh composed from point data.  As opposed to DrawPreviewMesh(), this function will check against all user specified rules.  If conditions are met, CheckMaxMeshes() is called, and the new gameObject is added to the internal cache of all PolyDraw created objects.
         *	@param _points List of user points.  Assumed to be in world space (use ScreenToWorldPoint(screenPoint) where screenPoint is typically Input.mousePosition ).
         */
        public void DrawFinalMesh(List <Vector2> _points)
        {
            DestroyPreviewMesh();

            if (_points.Count < 3)
            {
                CleanUp();
                        #if DEBUG
                Debug.LogWarning("Polydraw: Mesh generation failed on points < 3");
                        #endif
                OnCanceledObjectCreation();
                return;
            }

            if ((_points[0] - _points[_points.Count - 1]).sqrMagnitude > maxDistance && useDistanceCheck)
            {
                        #if DEBUG
                Debug.LogWarning("Mesh generation failed on distance check");
                        #endif
                CleanUp();
                OnCanceledObjectCreation();
                return;
            }

            // Calculate this here because the collision code needs it too
            float obj_area = Mathf.Abs(Triangulator.Area(_points));

            if (drawSettings.requireMinimumArea && obj_area < drawSettings.minimumAreaToDraw)
            {
                        #if DEBUG
                Debug.Log("Polydraw: Mesh generation failed on requireMinimumArea check.");
                        #endif
                CleanUp();
                return;
            }

            // graphics = any mesh that you can see, collision = the side mesh
            Mesh             graphics, collision;
            Draw.PolygonType convexity;

            // Since Draw doesn't expose special collision settings, just the side settings.
            drawSettings.colAnchor = drawSettings.anchor;
            drawSettings.colDepth  = drawSettings.sideLength > .01 ? drawSettings.sideLength : .01f;

            if (!DrawUtility.MeshWithPoints(_points, drawSettings, out graphics, out collision, out convexity))
            {
                if (graphics != null)
                {
                    DestroyImmediate(graphics);
                }
                if (collision != null)
                {
                    DestroyImmediate(collision);
                }

                CleanUp();

                return;
            }

            // If we're over max, delete the earliest drawn mesh
            CheckMaxMeshes();

            GameObject finalMeshGameObject = new GameObject();
            finalMeshGameObject.name = drawSettings.meshName;

            if (drawSettings.useTag)
            {
                finalMeshGameObject.tag = drawSettings.tagVal;
            }

            finalMeshGameObject.AddComponent <MeshFilter>();
            finalMeshGameObject.GetComponent <MeshFilter>().sharedMesh = graphics;
            finalMeshGameObject.AddComponent <MeshRenderer>();


            Material[] mats = (drawSettings.generateSide) ?
                              new Material[2] {
                drawSettings.frontMaterial, drawSettings.sideMaterial
            } :
            new Material[1] {
                drawSettings.frontMaterial
            };

            finalMeshGameObject.GetComponent <MeshRenderer>().sharedMaterials = mats;

            switch (drawSettings.colliderType)
            {
            case ColliderType.MeshCollider:
                finalMeshGameObject.AddComponent <MeshCollider>();

                finalMeshGameObject.GetComponent <MeshCollider>().sharedMesh = collision;

                if (drawSettings.applyRigidbody)
                {
                    Rigidbody rigidbody = finalMeshGameObject.AddComponent <Rigidbody>();

                    if ((convexity == PolygonType.ConcaveCounterClockwise || convexity == PolygonType.ConcaveClockwise) && drawSettings.forceConvex == false)
                    {
                        finalMeshGameObject.GetComponent <MeshCollider>().convex = false;
                    }
                    else
                    {
                        finalMeshGameObject.GetComponent <MeshCollider>().convex = true;
                    }

                    if (drawSettings.areaRelativeMass)
                    {
                        rigidbody.mass = obj_area * drawSettings.massModifier;
                    }
                    else
                    {
                        rigidbody.mass = drawSettings.mass;
                    }

                    rigidbody.constraints = RigidbodyConstraints.FreezeRotationX | RigidbodyConstraints.FreezeRotationY | RigidbodyConstraints.FreezePositionZ;

                    if (drawSettings.useGravity)
                    {
                        rigidbody.useGravity = true;
                    }
                    else
                    {
                        rigidbody.useGravity = false;
                    }

                    if (drawSettings.isKinematic)
                    {
                        rigidbody.isKinematic = true;
                    }
                    else
                    {
                        rigidbody.isKinematic = false;
                    }
                }
                break;

            case ColliderType.BoxCollider:
                if (drawSettings.applyRigidbody)
                {
                    BoxCollider parent_collider = finalMeshGameObject.AddComponent <BoxCollider>();

                    // the parent collider - don't allow it to be seen, just use it for
                    // mass and other settings
                    parent_collider.size = new Vector3(.01f, .01f, .01f);

                    Rigidbody rigidbody = finalMeshGameObject.AddComponent <Rigidbody>();

                    if (drawSettings.areaRelativeMass)
                    {
                        rigidbody.mass = obj_area * drawSettings.massModifier;
                    }
                    else
                    {
                        rigidbody.mass = drawSettings.mass;
                    }

                    rigidbody.constraints = RigidbodyConstraints.FreezeRotationX | RigidbodyConstraints.FreezeRotationY | RigidbodyConstraints.FreezePositionZ;

                    if (drawSettings.useGravity)
                    {
                        rigidbody.useGravity = true;
                    }
                    else
                    {
                        rigidbody.useGravity = false;
                    }

                    if (drawSettings.isKinematic)
                    {
                        rigidbody.isKinematic = true;
                    }
                    else
                    {
                        rigidbody.isKinematic = false;
                    }
                }

                if (!drawSettings.manualColliderDepth)
                {
                    drawSettings.colDepth = drawSettings.sideLength;
                }

                float zPos_collider = drawSettings.zPosition + drawSettings.faceOffset;

                switch (drawSettings.anchor)
                {
                case Anchor.Front:
                    zPos_collider += drawSettings.sideLength / 2f;
                    break;

                case Anchor.Back:
                    zPos_collider -= drawSettings.sideLength / 2f;
                    break;

                default:
                    break;
                }

                for (int i = 0; i < _points.Count; i++)
                {
                    float x1, x2, y1, y2;
                    x1 = _points[i].x;
                    y1 = _points[i].y;

                    if (i > _points.Count - 2)
                    {
                        x2 = _points[0].x;
                        y2 = _points[0].y;
                    }
                    else
                    {
                        x2 = _points[i + 1].x;
                        y2 = _points[i + 1].y;
                    }

                    GameObject boxColliderObj = new GameObject();
                    boxColliderObj.name = "BoxCollider" + i;
                    boxColliderObj.AddComponent <BoxCollider>();

                    boxColliderObj.transform.position = new Vector3(((x1 + x2) / 2f), ((y1 + y2) / 2f), zPos_collider);

                    Vector2 vectorLength = new Vector2(Mathf.Abs(x1 - x2), Mathf.Abs(y1 - y2));

                    float length = Mathf.Sqrt((Mathf.Pow((float)vectorLength.x, 2f) + Mathf.Pow(vectorLength.y, 2f)));
                    float angle  = Mathf.Atan2(y2 - y1, x2 - x1) * Mathf.Rad2Deg;

                    boxColliderObj.transform.localScale = new Vector3(length, boxColliderSize, drawSettings.colDepth);
                    boxColliderObj.transform.rotation   = Quaternion.Euler(new Vector3(0f, 0f, angle));

                    boxColliderObj.transform.parent = finalMeshGameObject.transform;
                }
                break;

            case ColliderType.PolygonCollider2d:
                PolygonCollider2D poly = finalMeshGameObject.AddComponent <PolygonCollider2D>();
                finalMeshGameObject.AddComponent <Rigidbody2D>();
                poly.points = _points.ToArray();
                break;

            default:
                break;
            }

            generatedMeshes.Add(finalMeshGameObject);

            if (drawSettings.drawEdgePlanes)
            {
                DrawEdgePlanes(_points, convexity, new Vector2(.4f, 1.2f), obj_area);
            }

            CleanUp();

            OnCreatedNewObject();
        }
Пример #4
0
        public void Refresh()
        {
            if (points.Count < 1)
            {
                return;
            }

            Mesh m, c;

            Draw.PolygonType convexity;

            if (!DrawUtility.MeshWithPoints(points, drawSettings, out m, out c, out convexity))
            {
                if (m)
                {
                    DestroyImmediate(m);
                }
                if (c)
                {
                    DestroyImmediate(c);
                }
                return;
            }

            gameObject.SetMesh(m);

            if (drawSettings.colliderType == Draw.ColliderType.MeshCollider)
            {
                if (GetComponent <PolygonCollider2D>())
                {
                    DestroyImmediate(GetComponent <PolygonCollider2D>());
                }

                gameObject.SetMeshCollider(c);
            }

            MeshRenderer mr = gameObject.GetComponent <MeshRenderer>();

            if (mr == null)
            {
                mr = gameObject.AddComponent <MeshRenderer>();
            }

            if (drawSettings.generateSide)
            {
                mr.sharedMaterials = new Material[] {
                    drawSettings.frontMaterial,
                    drawSettings.sideMaterial,
                };
            }
            else
            {
                mr.sharedMaterials = new Material[] { drawSettings.frontMaterial };
            }

#if UNITY_EDITOR
            UnityEditor.EditorApplication.delayCall += this.RefreshCollisions;
#else
            RefreshCollisions();
#endif
        }
Пример #5
0
        public void Refresh()
        {
            if (points.Count < 1)
            {
                return;
            }

            Mesh m, c;

            Draw.PolygonType convexity;

            if (!DrawUtility.MeshWithPoints(points, drawSettings, out m, out c, out convexity))
            {
                if (m)
                {
                    DestroyImmediate(m);
                }
                if (c)
                {
                    DestroyImmediate(c);
                }
                return;
            }

            gameObject.SetMesh(m);
            bool isTrigger = gameObject.GetComponent <Collider>() == null
                ? false
                : gameObject.GetComponent <Collider>().isTrigger;
            bool isConvex = gameObject.GetComponent <MeshCollider>() == null
                ? false
                : gameObject.GetComponent <MeshCollider>().convex;

            RemoveCollisions();

            Rigidbody oldRigidbody = gameObject.GetComponent <Rigidbody>();
            bool      hasRigidbody = (oldRigidbody != null);

            if (hasRigidbody)
            {
                CopyRigidbodySettings();
                DestroyImmediate(gameObject.GetComponent <Rigidbody>());
            }

            switch (drawSettings.colliderType)
            {
            case Draw.ColliderType.MeshCollider:
                gameObject.SetMeshCollider(c);
                break;

            case Draw.ColliderType.BoxCollider:
                BuildBoxCollisions();
                DestroyImmediate(c);
                break;

            default:
                DestroyImmediate(c);
                break;
            }

            MeshRenderer mr = gameObject.GetComponent <MeshRenderer>();

            if (mr == null)
            {
                mr = gameObject.AddComponent <MeshRenderer>();
            }

            mr.sharedMaterials = drawSettings.generateSide
                ? new Material[]
            {
                drawSettings.frontMaterial,
                drawSettings.sideMaterial
            }
                : new Material[]
            {
                drawSettings.frontMaterial
            };

            if (hasRigidbody)
            {
                if (!gameObject.GetComponent <Rigidbody>())
                {
                    gameObject.AddComponent <Rigidbody>();
                }
                PasteRigidbodySettings();
            }

            if (gameObject.GetComponent <Collider>())
            {
                gameObject.GetComponent <Collider>().isTrigger = isTrigger;
                if (gameObject.GetComponent <MeshCollider>())
                {
                    gameObject.GetComponent <MeshCollider>().convex = isConvex;
                }
            }
        }