示例#1
0
    public static Rect AtlasField(IFerr2DTMaterial aMat, Rect aRect, Texture aTexture)
    {
        EditorGUILayout.BeginHorizontal(GUILayout.Height(64));
        GUILayout.Space(5);
        GUILayout.Space(64);

        Rect  r   = GUILayoutUtility.GetLastRect();
        float max = Mathf.Max(1, Mathf.Max(aRect.width, aRect.height));

        r.width  = Mathf.Max(1, (aRect.width / max) * 64);
        r.height = Mathf.Max(1, (aRect.height / max) * 64);

        GUI.DrawTexture(new Rect(r.x - 1, r.y - 1, r.width + 2, 1), EditorGUIUtility.whiteTexture);
        GUI.DrawTexture(new Rect(r.x - 1, r.yMax + 1, r.width + 2, 1), EditorGUIUtility.whiteTexture);
        GUI.DrawTexture(new Rect(r.x - 1, r.y - 1, 1, r.height + 2), EditorGUIUtility.whiteTexture);
        GUI.DrawTexture(new Rect(r.xMax, r.y - 1, 1, r.height + 2), EditorGUIUtility.whiteTexture);
        GUI.DrawTextureWithTexCoords(r, aTexture, aMat.ToUV(aRect));
        GUILayout.Space(10);

        Rect result = aMat.ToNative(EditorGUILayout.RectField(aMat.ToPixels(aRect)));

        EditorGUILayout.EndHorizontal();

        return(result);
    }
    static void AddLegacyTerrain(IFerr2DTMaterial aMaterial)
    {
        GameObject obj = CreateLegacyBaseTerrain(aMaterial, true);

        Selection.activeGameObject = obj;
        EditorGUIUtility.PingObject(obj);
    }
    private void ShowMaterialSelector()
    {
        EditorGUILayout.LabelField("TERRAIN MATERIAL");

        Ferr.EditorTools.Box(4, () => {
            EditorGUILayout.BeginHorizontal();
            IFerr2DTMaterial material = terrain.TerrainMaterial;
            GUIContent button         = material != null && material.edgeMaterial != null && material.edgeMaterial.mainTexture != null ? new GUIContent(material.edgeMaterial.mainTexture) : new GUIContent("Pick");
            if (GUILayout.Button(button, GUILayout.Width(64f), GUILayout.Height(64f)))
            {
                Ferr2DT_MaterialSelector.Show((mat) => {
                    if (mat != terrain.TerrainMaterial)
                    {
                        SelectMaterial((UnityEngine.Object)mat);
                    }
                    materialChanged = true;
                });
            }

            UnityEngine.Object obj = EditorGUILayout.ObjectField((UnityEngine.Object)terrain.TerrainMaterial, typeof(Ferr2DT_Material), false, GUILayout.Height(64f));
            if (obj != (UnityEngine.Object)terrain.TerrainMaterial)
            {
                SelectMaterial(obj);
                materialChanged = true;
            }
            EditorGUILayout.EndHorizontal();
        });
    }
    static void AddDecoTerrain(IFerr2DTMaterial aMaterial)
    {
        GameObject obj = CreateBaseTerrain(aMaterial, false);

        Selection.activeGameObject = obj;
        EditorGUIUtility.PingObject(obj);
    }
    void ShowDirection(IFerr2DTMaterial aMat, int aDir)
    {
        Ferr2DT_SegmentDescription desc = aMat.GetDescriptor((Ferr2DT_TerrainDirection)aDir);

        settingsScroll = EditorGUILayout.BeginScrollView(settingsScroll);
        EditorGUILayout.LabelField("Edge Placement", EditorStyles.boldLabel);
        EditorGUI.indentLevel = 1;
        desc.zOffset          = EditorGUILayout.IntField("Draw Order", Mathf.RoundToInt(desc.zOffset * 1000)) / 1000f;
        desc.YOffsetPercent   = EditorGUILayout.Slider("Y Offset", desc.YOffsetPercent, -.5f, .5f);
        desc.yOffset          = EditorGUILayout.FloatField("[Legacy] Y Offset", desc.yOffset);
        desc.capOffset        = EditorGUILayout.FloatField("[Legacy] Cap Offset", desc.capOffset);
        EditorGUI.indentLevel = 0;

        Ferr2DT_TerrainMaterialUtility.EditColliders(desc);

        EditorGUILayout.Space();
        EditorGUILayout.LabelField("Edge Segments", EditorStyles.boldLabel);
        simpleUVs = EditorGUILayout.Toggle("Simple Mode", simpleUVs);
        if (simpleUVs)
        {
            Ferr2DT_TerrainMaterialUtility.EditUVsSimple(aMat, desc);
        }
        else
        {
            Ferr2DT_TerrainMaterialUtility.EditUVsComplex(aMat, desc, width, ref currBody);
        }
        EditorGUILayout.EndScrollView();
    }
    bool DrawObject(IFerr2DTMaterial mb)
    {
        if (mb == null)
        {
            return(false);
        }

        bool retVal = false;

        GUILayout.BeginHorizontal();
        {
            if (mb.edgeMaterial != null && mb.edgeMaterial.mainTexture != null)
            {
                retVal = GUILayout.Button(mb.edgeMaterial.mainTexture, GUILayout.Width(48), GUILayout.Height(48));
            }
            else
            {
                retVal = GUILayout.Button("Select", GUILayout.Width(48), GUILayout.Height(48));
            }
            GUILayout.Label(mb.name, GUILayout.Height(48), GUILayout.Width(160f));

            GUI.color = Color.white;
        }
        GUILayout.EndHorizontal();
        return(retVal);
    }
示例#7
0
    public static void EditUVsSimple(IFerr2DTMaterial aMat, Ferr2DT_SegmentDescription desc)
    {
        Rect cap  = aMat.ToPixels(desc.leftCap);
        Rect body = aMat.ToPixels(desc.body[0]);

        float   height    = body.height;
        float   capWidth  = cap.width;
        float   bodyWidth = body.width;
        int     bodyCount = desc.body.Length;
        Vector2 pos       = new Vector2(cap.x, cap.y);

        if (cap.width == 0 && cap.height == 0)
        {
            pos = new Vector2(body.x, body.y);
        }

        pos       = EditorGUILayout.Vector2Field("Position", pos);
        height    = EditorGUILayout.FloatField("Height", height);
        capWidth  = EditorGUILayout.FloatField("Cap Width", capWidth);
        bodyWidth = EditorGUILayout.FloatField("Body Width", bodyWidth);
        bodyCount = Mathf.Max(1, EditorGUILayout.IntField("Body slices", bodyCount));

        if (bodyCount != desc.body.Length)
        {
            Array.Resize <Rect>(ref desc.body, bodyCount);
        }

        float currX = pos.x;

        desc.leftCap.x      = currX;
        desc.leftCap.y      = pos.y;
        desc.leftCap.width  = capWidth;
        desc.leftCap.height = capWidth == 0 ? 0 : height;
        desc.leftCap        = aMat.ToNative(desc.leftCap);
        currX += capWidth;

        for (int i = 0; i < desc.body.Length; i++)
        {
            desc.body[i].x      = currX;
            desc.body[i].y      = pos.y;
            desc.body[i].width  = bodyWidth;
            desc.body[i].height = height;
            desc.body[i]        = aMat.ToNative(desc.body[i]);
            currX += bodyWidth;
        }

        desc.rightCap.x      = currX;
        desc.rightCap.y      = pos.y;
        desc.rightCap.width  = capWidth;
        desc.rightCap.height = capWidth == 0 ? 0 : height;
        desc.rightCap        = aMat.ToNative(desc.rightCap);
    }
示例#8
0
    static GameObject CreateBaseTerrain(IFerr2DTMaterial aMaterial, bool aCreateColliders)
    {
        GameObject          obj     = new GameObject("New Terrain");
        Ferr2D_Path         path    = obj.AddComponent <Ferr2D_Path>();
        Ferr2DT_PathTerrain terrain = obj.AddComponent <Ferr2DT_PathTerrain>();

        bool hasEdges = aMaterial.Has(Ferr2DT_TerrainDirection.Bottom) ||
                        aMaterial.Has(Ferr2DT_TerrainDirection.Left) ||
                        aMaterial.Has(Ferr2DT_TerrainDirection.Right);

        if (hasEdges)
        {
            path.Add(new Vector2(-6, -3));
            path.Add(new Vector2(-6, 3));
            path.Add(new Vector2(6, 3));
            path.Add(new Vector2(6, -3));
            path.closed = true;
        }
        else
        {
            path.Add(new Vector2(-6, 6));
            path.Add(new Vector2(6, 6));
            terrain.splitCorners = false;
            path.closed          = false;
        }

        if (aMaterial.fillMaterial != null)
        {
            if (hasEdges)
            {
                terrain.fill = Ferr2DT_FillMode.Closed;
            }
            else
            {
                terrain.fill         = Ferr2DT_FillMode.Skirt;
                terrain.splitCorners = true;
            }
        }
        else
        {
            terrain.fill = Ferr2DT_FillMode.None;
        }
        terrain.smoothPath     = SmoothTerrain;
        terrain.pixelsPerUnit  = PPU;
        terrain.createCollider = aCreateColliders;
        terrain.SetMaterial(aMaterial);
        terrain.Build(true);

        obj.transform.position = GetSpawnPos();

        return(obj);
    }
示例#9
0
    public override void OnInspectorGUI()
    {
        Undo.RecordObject(target, "Modified Terrain Material");

        IFerr2DTMaterial mat = target as IFerr2DTMaterial;
        Material         newMat;

        newMat = mat.edgeMaterial = (Material)EditorGUILayout.ObjectField("Edge Material", mat.edgeMaterial, typeof(Material), true);
        if (mat.edgeMaterial != newMat)
        {
            mat.edgeMaterial = newMat;
            CheckMaterialMode(mat.edgeMaterial, TextureWrapMode.Clamp);
        }

        newMat = (Material)EditorGUILayout.ObjectField("Fill Material", mat.fillMaterial, typeof(Material), true);
        if (mat.fillMaterial != newMat)
        {
            mat.fillMaterial = newMat;
            CheckMaterialMode(mat.fillMaterial, TextureWrapMode.Repeat);
        }

        Type window = Type.GetType("Ferr2DT_TerrainMaterialWindow");

        if (window == null)
        {
            EditorGUILayout.HelpBox("Ferr2D was not detected in the project! You must have Ferr2D installed to edit or use this material.", MessageType.Error);
            if (GUILayout.Button("Get Ferr2D"))
            {
                Application.OpenURL("https://www.assetstore.unity3d.com/en/#!/content/11653");
            }
        }
        else
        {
            if (mat.edgeMaterial == null)
            {
                EditorGUILayout.HelpBox("Please add an edge material to enable the material editor!", MessageType.Warning);
            }
            else if (window != null)
            {
                MethodInfo show = window.GetMethod("Show", BindingFlags.Static | BindingFlags.Public);
                if (show == null)
                {
                    EditorGUILayout.HelpBox("No window show method found!", MessageType.Error);
                }
                else if (GUILayout.Button("Open Material Editor"))
                {
                    show.Invoke(null, new object[] { mat });
                }
            }
        }
    }
    public override void OnInspectorGUI()
    {
        Undo.RecordObject(target, "Modified Terrain Material");

        IFerr2DTMaterial mat = target as IFerr2DTMaterial;
        Material         newMat;

        newMat = mat.edgeMaterial = (Material)EditorGUILayout.ObjectField("Edge Material", mat.edgeMaterial, typeof(Material), true);
        if (mat.edgeMaterial != newMat)
        {
            mat.edgeMaterial = newMat;
            Ferr2DT_TerrainMaterialUtility.CheckMaterialMode(mat.edgeMaterial, TextureWrapMode.Clamp);
        }

        newMat = (Material)EditorGUILayout.ObjectField("Fill Material", mat.fillMaterial, typeof(Material), true);
        if (mat.fillMaterial != newMat)
        {
            mat.fillMaterial = newMat;
            Ferr2DT_TerrainMaterialUtility.CheckMaterialMode(mat.fillMaterial, TextureWrapMode.Repeat);
        }

        if (mat.edgeMaterial == null)
        {
            EditorGUILayout.HelpBox("Please add an edge material to enable the material editor!", MessageType.Warning);
        }
        else
        {
            if (GUILayout.Button("Open Material Editor"))
            {
                Ferr2DT_TerrainMaterialWindow.Show(mat);
            }
        }

        DrawUpdateUI();

        if (GUI.changed)
        {
            EditorUtility.SetDirty(target);

            Ferr2DT_PathTerrain[] terrain = GameObject.FindObjectsOfType(typeof(Ferr2DT_PathTerrain)) as Ferr2DT_PathTerrain[];
            for (int i = 0; i < terrain.Length; i++)
            {
                if (terrain[i].TerrainMaterial == mat)
                {
                    terrain[i].Build(true);
                }
            }
        }
    }
示例#11
0
    public static void ShowPreview(IFerr2DTMaterial aMat, Ferr2DT_TerrainDirection aDir, bool aSimpleUVs, bool aEditable, float aWidth)
    {
        if (aMat.edgeMaterial == null || aMat.edgeMaterial.mainTexture == null)
        {
            return;
        }

        GUILayout.Label(aMat.edgeMaterial.mainTexture);

        Rect texRect = GUILayoutUtility.GetLastRect();

        texRect.width  = Mathf.Min(Screen.width - aWidth, aMat.edgeMaterial.mainTexture.width);
        texRect.height = (texRect.width / aMat.edgeMaterial.mainTexture.width) * aMat.edgeMaterial.mainTexture.height;

        ShowPreviewDirection(aMat, aDir, texRect, aSimpleUVs, aEditable);
    }
    void OnGUI()
    {
        EditorGUILayout.BeginVertical();

        EditorGUILayout.Space();
        EditorGUILayout.LabelField("Select a Material \u25BC", EditorStyles.boldLabel);
        EditorGUILayout.BeginHorizontal();
        if (_selectedObject != null)
        {
            IFerr2DTMaterial mat = _selectedObject as IFerr2DTMaterial;
            if (mat != null && mat.edgeMaterial != null && mat.edgeMaterial.mainTexture != null)
            {
                GUILayout.Label(mat.edgeMaterial.mainTexture, GUILayout.Width(32), GUILayout.Height(32));
            }
        }
        _selectedObject = EditorGUILayout.ObjectField(_selectedObject, typeof(Ferr2DT_Material), false, GUILayout.Height(32));
        EditorGUILayout.EndHorizontal();
        EditorGUILayout.EndVertical();

        EditorGUILayout.Space();
        EditorGUILayout.LabelField("Or Pick From Recent Materials", EditorStyles.boldLabel);
        _scroll = EditorGUILayout.BeginScrollView(_scroll, EditorStyles.helpBox);
        List <UnityEngine.Object> history = GetRecentList();

        for (int i = 0; i < history.Count; i++)
        {
            if (DrawObject(history[i] as IFerr2DTMaterial))
            {
                _selectedObject = history[i];
            }
        }
        EditorGUILayout.EndScrollView();

        IFerr2DTMaterial obj = _selectedObject as IFerr2DTMaterial;

        if (GUILayout.Button("Confirm") && obj != null)
        {
            AddToRecentList(_selectedObject);
            if (_onPickMaterial != null)
            {
                _onPickMaterial(obj);
            }
            Close();
        }
        return;
    }
示例#13
0
    void ShowDirection(IFerr2DTMaterial aMat, Ferr2DT_TerrainDirection aDir)
    {
        Ferr2DT_SegmentDescription desc = aMat.GetDescriptor(aDir);

        desc.zOffset   = EditorGUILayout.FloatField("Z Offset", desc.zOffset);
        desc.yOffset   = EditorGUILayout.FloatField("Y Offset", desc.yOffset);
        desc.capOffset = EditorGUILayout.FloatField("Cap Offset", desc.capOffset);

        simpleUVs = EditorGUILayout.Toggle("Simple", simpleUVs);
        if (simpleUVs)
        {
            Ferr2DT_TerrainMaterialUtility.EditUVsSimple(aMat, desc);
        }
        else
        {
            Ferr2DT_TerrainMaterialUtility.EditUVsComplex(aMat, desc, width, ref currBody);
        }
    }
    private void LegacyAddFill(bool aSkirt, bool aFullBuild)
    {
        IFerr2DTMaterial mat       = TerrainMaterial;
        float            texWidth  = mat.edgeMaterial ? 256 : mat.edgeMaterial.mainTexture.width;
        float            fillDist  = (mat.ToUV(mat.GetBody((Ferr2DT_TerrainDirection)0, 0)).width *(texWidth / pixelsPerUnit)) / (Mathf.Max(1, splitCount)) * splitDist;
        List <Vector2>   fillVerts = GetSegmentsCombined(fillDist);
        Vector2          scale     = Vector2.one;

        // scale is different for the fill texture
        if (mat.fillMaterial != null && mat.fillMaterial.mainTexture != null)
        {
            scale = new Vector2(
                mat.fillMaterial.mainTexture.width / pixelsPerUnit,
                mat.fillMaterial.mainTexture.height / pixelsPerUnit);
        }

        if (aSkirt)
        {
            Vector2 start = fillVerts[0];
            Vector2 end   = fillVerts[fillVerts.Count - 1];

            fillVerts.Add(new Vector2(end.x, fillY));
            fillVerts.Add(new Vector2(Mathf.Lerp(end.x, start.x, 0.33f), fillY));
            fillVerts.Add(new Vector2(Mathf.Lerp(end.x, start.x, 0.66f), fillY));
            fillVerts.Add(new Vector2(start.x, fillY));
        }

        int        offset  = DMesh.VertCount;
        List <int> indices = Ferr2D_Triangulator.GetIndices(ref fillVerts, true, fill == Ferr2DT_FillMode.InvertedClosed, invertFillBorder, fillSplit && aFullBuild ? fillSplitDistance : 0);

        for (int i = 0; i < fillVerts.Count; i++)
        {
            DMesh.AddVertex(fillVerts[i].x, fillVerts[i].y, fillZ, (fillVerts[i].x + uvOffset.x + transform.position.x) / scale.x, (fillVerts[i].y + uvOffset.y + transform.position.y) / scale.y);
        }
        for (int i = 0; i < indices.Count; i += 3)
        {
            try {
                DMesh.AddFace(indices[i] + offset,
                              indices[i + 1] + offset,
                              indices[i + 2] + offset);
            } catch {
            }
        }
    }
    /// <summary>
    /// [Legacy] This will allow you to set the terrain material regardless of whether it's marked as the current material already or not. Also calls RecreatePath when finished.
    /// </summary>
    /// <param name="aMaterial">The terrain material! Usually from a terrain material prefab.</param>
    /// <param name="aForceUpdate">Force it to set the material, even if it's already the set material, or no?</param>
    /// <param name="aRecreate">Should we recreate the mesh? Usually, this is what you want (only happens if the material changes, or is forced to change)</param>
    public void                        ForceMaterial(IFerr2DTMaterial aMaterial, bool aForceUpdate, bool aRecreate = true)
    {
        if (terrainMaterialInterface != (UnityEngine.Object)aMaterial || aForceUpdate)
        {
            terrainMaterialInterface = (UnityEngine.Object)aMaterial;

            // copy the materials into the renderer
            Material[] newMaterials = null;
            if (fill == Ferr2DT_FillMode.Closed || fill == Ferr2DT_FillMode.InvertedClosed || fill == Ferr2DT_FillMode.Skirt)
            {
                newMaterials = new Material[] {
                    aMaterial.fillMaterial,
                    aMaterial.edgeMaterial
                };
            }
            else if (fill == Ferr2DT_FillMode.None)
            {
                newMaterials = new Material[] {
                    aMaterial.edgeMaterial
                };
            }
            else if (fill == Ferr2DT_FillMode.FillOnlyClosed || fill == Ferr2DT_FillMode.FillOnlySkirt)
            {
                newMaterials = new Material[] {
                    aMaterial.fillMaterial
                };
            }
            GetComponent <Renderer>().sharedMaterials = newMaterials;

            // make sure we update the units per UV
            Material edgeMat = TerrainMaterial.edgeMaterial;
            if (edgeMat != null && edgeMat.mainTexture != null)
            {
                unitsPerUV.x = edgeMat.mainTexture.width / pixelsPerUnit;
                unitsPerUV.y = edgeMat.mainTexture.height / pixelsPerUnit;
            }

            if (aRecreate)
            {
                Build(true);
            }
        }
    }
    static GameObject CreateBaseTerrain(IFerr2DTMaterial aMaterial, bool aCreateColliders)
    {
        GameObject          obj     = new GameObject("New Terrain");
        Ferr2DT_PathTerrain terrain = obj.AddComponent <Ferr2DT_PathTerrain>();

        obj.transform.position = GetSpawnPos();

        bool hasEdges = aMaterial.Has(Ferr2DT_TerrainDirection.Bottom) ||
                        aMaterial.Has(Ferr2DT_TerrainDirection.Left) ||
                        aMaterial.Has(Ferr2DT_TerrainDirection.Right);

        if (hasEdges)
        {
            terrain.PathData.Add(new Vector2(5, -5), new Ferr2D_PointData(1), Ferr.PointType.Sharp);
            terrain.PathData.Add(new Vector2(5, 5), new Ferr2D_PointData(1), Ferr.PointType.Sharp);
            terrain.PathData.Add(new Vector2(-5, 5), new Ferr2D_PointData(1), Ferr.PointType.Sharp);
            terrain.PathData.Add(new Vector2(-5, -5), new Ferr2D_PointData(1), Ferr.PointType.Sharp);
            terrain.PathData.Closed = true;
        }
        else
        {
            terrain.PathData.Add(new Vector2(5, 5), new Ferr2D_PointData(1), Ferr.PointType.Auto);
            terrain.PathData.Add(new Vector2(-5, 5), new Ferr2D_PointData(1), Ferr.PointType.Auto);
            terrain.splitCorners    = false;
            terrain.PathData.Closed = false;
        }

        if (aMaterial.fillMaterial == null)
        {
            terrain.FillMode = Ferr2D_SectionMode.None;
        }
        if (aMaterial.edgeMaterial == null)
        {
            terrain.EdgeMode = Ferr2D_SectionMode.None;
        }
        terrain.pixelsPerUnit = PPU;
        terrain.ColliderMode  = aCreateColliders ? Ferr2D_ColliderMode.Polygon2D : Ferr2D_ColliderMode.None;
        terrain.SetMaterial(aMaterial);
        terrain.Build(true);

        return(obj);
    }
示例#17
0
    public static void Show(IFerr2DTMaterial aMaterial)
    {
        Ferr2DT_TerrainMaterialWindow window = EditorWindow.GetWindow <Ferr2DT_TerrainMaterialWindow>();

        window.material       = aMaterial;
        window.wantsMouseMove = true;
        #if UNITY_5_4_OR_NEWER
        window.titleContent = new GUIContent("Ferr2DT Editor");
        #else
        window.title = "Ferr2DT Editor";
        #endif
        if (aMaterial != null && aMaterial.edgeMaterial != null)
        {
            window.minSize = new Vector2(400, 400);
        }
        window.foldoutStyle           = EditorStyles.foldout;
        window.foldoutStyle.fontStyle = FontStyle.Bold;
        window.currDir = Ferr2DT_TerrainDirection.None;
        window.prevDir = Ferr2DT_TerrainDirection.None;
    }
    public static void ShowSample(IFerr2DTMaterial aMat, Ferr2DT_TerrainDirection aDir, float aWidth)
    {
        if (aMat.edgeMaterial == null || aMat.edgeMaterial.mainTexture == null)
        {
            return;
        }

        Ferr2DT_SegmentDescription desc = aMat.GetDescriptor(aDir);
        float   totalWidth   = desc.leftCap.width + desc.rightCap.width + (Mathf.Max(0, desc.body[0].width) * 3);
        float   sourceHeight = MaxHeight(desc);
        Texture tex          = aMat.edgeMaterial != null ? aMat.edgeMaterial.mainTexture : EditorGUIUtility.whiteTexture;

        float scale  = Mathf.Min(aWidth / totalWidth, 64 / sourceHeight);
        float aspect = tex.height / tex.width;

        GUILayout.Space(sourceHeight * scale * aspect);
        float x = GUILayoutUtility.GetLastRect().x;
        float y = GUILayoutUtility.GetLastRect().y;

        if (desc.leftCap.width != 0)
        {
            float yOff = ((sourceHeight - desc.leftCap.height) / 2) * scale;
            GUI.DrawTextureWithTexCoords(new Rect(x, y + yOff, desc.leftCap.width * scale, desc.leftCap.height * scale * aspect), tex, aMat.ToUV(desc.leftCap));
            x += desc.leftCap.width * scale;
        }
        for (int i = 0; i < 3; i++)
        {
            int   id   = (2 - i) % desc.body.Length;
            float yOff = ((sourceHeight - desc.body[id].height) / 2) * scale;
            GUI.DrawTextureWithTexCoords(new Rect(x, y + yOff, desc.body[id].width * scale, desc.body[id].height * scale * aspect), tex, aMat.ToUV(desc.body[id]));
            x += desc.body[id].width * scale;
        }
        if (desc.leftCap.width != 0)
        {
            float yOff = ((sourceHeight - desc.rightCap.height) / 2) * scale;
            GUI.DrawTextureWithTexCoords(new Rect(x, y + yOff, desc.rightCap.width * scale, desc.rightCap.height * scale * aspect), tex, aMat.ToUV(desc.rightCap));
        }
    }
    public override void OnInspectorGUI()
    {
        Undo.RecordObject(target, "Modified Path Terrain");

        Ferr2DT_PathTerrain sprite = (Ferr2DT_PathTerrain)target;

        multiSelect = targets.Length > 1;

        // render the material selector!
        Ferr.EditorTools.Box(4, () => {
            IFerr2DTMaterial material = sprite.TerrainMaterial;

            EditorGUILayout.BeginHorizontal();
            GUIContent button = material != null && material.edgeMaterial != null && material.edgeMaterial.mainTexture != null ? new GUIContent(material.edgeMaterial.mainTexture) : new GUIContent("Pick");
            if (GUILayout.Button(button, GUILayout.Width(48f), GUILayout.Height(48f)))
            {
                Action <IFerr2DTMaterial> callback = null;
                for (int i = 0; i < targets.Length; i += 1)
                {
                    Ferr2DT_PathTerrain curr = (Ferr2DT_PathTerrain)targets[i];
                    callback += (mat) => {
                        Undo.RecordObject(curr, "Changed Terrain Material");
                        curr.SetMaterial(mat);
                        EditorUtility.SetDirty(curr);
                    };
                }
                Ferr2DT_MaterialSelector.Show(callback);
            }

            EditorGUILayout.BeginVertical();
            EditorGUILayout.LabelField("Terrain Material:");
            EditorGUI.indentLevel = 2;
            EditorGUILayout.LabelField(sprite.TerrainMaterial == null ? "None" : sprite.TerrainMaterial.name);
            EditorGUI.indentLevel = 0;
            EditorGUILayout.EndVertical();
            EditorGUILayout.EndHorizontal();
        });


        showVisuals = EditorGUILayout.Foldout(showVisuals, "VISUALS");

        if (showVisuals)
        {
            EditorGUI.indentLevel = 2;
            Ferr.EditorTools.Box(4, () => {
                // other visual data
                EditorGUILayout.PropertyField(vertexColorType);
                EditorGUI.indentLevel = 3;
                if (!vertexColorType.hasMultipleDifferentValues && vertexColorType.enumValueIndex == (int)Ferr2DT_ColorType.SolidColor)
                {
                    EditorGUILayout.PropertyField(vertexColor);
                }
                else if (!vertexColorType.hasMultipleDifferentValues && vertexColorType.enumValueIndex == (int)Ferr2DT_ColorType.Gradient)
                {
                    EditorGUILayout.PropertyField(vertexGradientAngle);
                    EditorGUILayout.PropertyField(vertexGradient);
                }
                else if (!vertexColorType.hasMultipleDifferentValues && vertexColorType.enumValueIndex == (int)Ferr2DT_ColorType.DistanceGradient)
                {
                    EditorGUILayout.PropertyField(vertexGradientDistance);
                    EditorGUILayout.PropertyField(vertexGradient);
                }
                EditorGUI.indentLevel = 2;

                EditorGUILayout.PropertyField(pixelsPerUnit);
                EditorGUILayout.PropertyField(slantAmount);
                EditorGUILayout.PropertyField(splitMiddle);
                EditorGUILayout.PropertyField(createTangents);
                EditorGUILayout.PropertyField(randomByWorldCoordinates, new GUIContent("Randomize Edge by World Coordinates"));
                EditorGUILayout.PropertyField(uvOffset, new GUIContent("Fill UV Offset"));

                if (!serializedObject.isEditingMultipleObjects)
                {
                    Renderer renderCom     = sprite.GetComponent <Renderer>();
                    string[] sortingLayers = Ferr.LayerUtil.GetSortingLayerNames();
                    if (sortingLayers != null)
                    {
                        string currName = renderCom.sortingLayerName == "" ? "Default" : renderCom.sortingLayerName;
                        int nameID      = EditorGUILayout.Popup("Sorting Layer", Array.IndexOf(sortingLayers, currName), sortingLayers);

                        renderCom.sortingLayerName = sortingLayers[nameID];
                    }
                    else
                    {
                        renderCom.sortingLayerID = EditorGUILayout.IntField("Sorting Layer", renderCom.sortingLayerID);
                    }
                    renderCom.sortingOrder = EditorGUILayout.IntField("Order in Layer", renderCom.sortingOrder);

                    // warn if the shader's aren't likely to work with the settings provided!
                    if (renderCom.sortingOrder != 0 || (renderCom.sortingLayerName != "Default" && renderCom.sortingLayerName != ""))
                    {
                        bool opaque = false;
                        for (int i = 0; i < renderCom.sharedMaterials.Length; ++i)
                        {
                            Material mat = renderCom.sharedMaterials[i];
                            if (mat != null && mat.GetTag("RenderType", false, "") == "Opaque")
                            {
                                opaque = true;
                            }
                        }
                        if (opaque)
                        {
                            EditorGUILayout.HelpBox("Layer properties won't work properly unless your shaders are all 'transparent'!", MessageType.Warning);
                        }
                    }
                }
            });
        }
        EditorGUI.indentLevel = 0;

        showTerrainType = EditorGUILayout.Foldout(showTerrainType, "TERRAIN TYPE");
        if (showTerrainType)
        {
            EditorGUI.indentLevel = 2;
            Ferr.EditorTools.Box(4, () => {
                EditorGUILayout.PropertyField(fill, new GUIContent("Fill Type"));
                if (fill.enumValueIndex == (int)Ferr2DT_FillMode.Closed || fill.enumValueIndex == (int)Ferr2DT_FillMode.InvertedClosed || fill.enumValueIndex == (int)Ferr2DT_FillMode.FillOnlyClosed && sprite.GetComponent <Ferr2D_Path>() != null)
                {
                    sprite.GetComponent <Ferr2D_Path>().closed = true;
                }
                if (fill.enumValueIndex != (int)Ferr2DT_FillMode.None && (sprite.TerrainMaterial != null && sprite.TerrainMaterial.fillMaterial == null))
                {
                    fill.enumValueIndex = (int)Ferr2DT_FillMode.None;
                }
                if (fill.enumValueIndex != (int)Ferr2DT_FillMode.None)
                {
                    EditorGUILayout.PropertyField(fillZ, new GUIContent("Fill Z Offset"));
                }
                if (fill.enumValueIndex == (int)Ferr2DT_FillMode.Skirt)
                {
                    EditorGUILayout.PropertyField(fillY, new GUIContent("Skirt Y Value"));
                }

                EditorGUILayout.PropertyField(splitCorners);
                EditorGUILayout.PropertyField(smoothPath);
                EditorGUI.indentLevel = 3;
                if (smoothPath.boolValue)
                {
                    EditorGUILayout.PropertyField(splitCount, new GUIContent("Edge Splits"));
                    EditorGUILayout.PropertyField(splitDist, new GUIContent("Fill Split"));
                    if (splitCount.intValue < 1)
                    {
                        splitCount.intValue = 2;
                    }
                }
                else
                {
                    splitCount.intValue  = 0;
                    splitDist.floatValue = 1;
                }
                EditorGUI.indentLevel = 2;

                EditorGUILayout.PropertyField(fillSplit, new GUIContent("Split fill mesh"));
                if (fillSplit.boolValue)
                {
                    EditorGUI.indentLevel = 3;
                    EditorGUILayout.PropertyField(fillSplitDistance, new GUIContent("Split Distance"));
                    EditorGUI.indentLevel = 2;
                }
            });
        }
        EditorGUI.indentLevel = 0;


        showCollider = EditorGUILayout.Foldout(showCollider, "COLLIDER");
        // render collider options
        if (showCollider)
        {
            EditorGUI.indentLevel = 2;
            Ferr.EditorTools.Box(4, () => {
                EditorGUILayout.PropertyField(createCollider);
                if (createCollider.boolValue)
                {
                    EditorGUILayout.PropertyField(sharpCorners);
                    if (sharpCorners.boolValue)
                    {
                        EditorGUI.indentLevel = 3;
                        EditorGUILayout.PropertyField(sharpCornerDistance, new GUIContent("Corner Distance"));
                        EditorGUI.indentLevel = 2;
                    }

                    EditorGUILayout.PropertyField(create3DCollider, new GUIContent("Use 3D Collider"));
                    if (sprite.create3DCollider)
                    {
                        EditorGUI.indentLevel = 3;
                        EditorGUILayout.PropertyField(depth, new GUIContent("Collider Width"));
                        EditorGUILayout.PropertyField(smoothSphereCollisions);
                        EditorGUI.indentLevel = 2;
                        EditorGUILayout.PropertyField(isTrigger);
                        EditorGUILayout.PropertyField(physicsMaterial);
                    }
                    else
                    {
                        EditorGUILayout.PropertyField(useEdgeCollider);
                        EditorGUILayout.PropertyField(usedByEffector);
                        EditorGUILayout.PropertyField(isTrigger);
                        EditorGUILayout.PropertyField(physicsMaterial2D);
                    }

                    if (sprite.fill == Ferr2DT_FillMode.None)
                    {
                        EditorGUILayout.PropertyField(surfaceOffset.GetArrayElementAtIndex((int)Ferr2DT_TerrainDirection.Top), new GUIContent("Thickness Top"));
                        EditorGUILayout.PropertyField(surfaceOffset.GetArrayElementAtIndex((int)Ferr2DT_TerrainDirection.Bottom), new GUIContent("Thickness Bottom"));
                    }
                    else
                    {
                        EditorGUILayout.PropertyField(surfaceOffset.GetArrayElementAtIndex((int)Ferr2DT_TerrainDirection.Top), new GUIContent("Offset Top"));
                        EditorGUILayout.PropertyField(surfaceOffset.GetArrayElementAtIndex((int)Ferr2DT_TerrainDirection.Left), new GUIContent("Offset Left"));
                        EditorGUILayout.PropertyField(surfaceOffset.GetArrayElementAtIndex((int)Ferr2DT_TerrainDirection.Right), new GUIContent("Offset Right"));
                        EditorGUILayout.PropertyField(surfaceOffset.GetArrayElementAtIndex((int)Ferr2DT_TerrainDirection.Bottom), new GUIContent("Offset Bottom"));
                    }

                    //EditorGUI.indentLevel = 0;
                    EditorGUILayout.LabelField("Generate colliders along:");
                    EditorGUILayout.PropertyField(collidersTop, new GUIContent("Top"));
                    EditorGUILayout.PropertyField(collidersLeft, new GUIContent("Left"));
                    EditorGUILayout.PropertyField(collidersRight, new GUIContent("Right"));
                    EditorGUILayout.PropertyField(collidersBottom, new GUIContent("Bottom"));

                    if (!collidersBottom.boolValue || !collidersLeft.boolValue || !collidersRight.boolValue || !collidersTop.boolValue)
                    {
                        EditorGUI.indentLevel = 2;
                        EditorGUILayout.PropertyField(colliderThickness);
                        EditorGUI.indentLevel = 0;
                    }
                }
            });
        }
        EditorGUI.indentLevel = 0;

        if (serializedObject.ApplyModifiedProperties() || GUI.changed)
        {
            for (int i = 0; i < targets.Length; i++)
            {
                EditorUtility.SetDirty(targets[i]);
                ((Ferr2DT_PathTerrain)targets[i]).Build(true);
            }

            cachedColliders = sprite.GetColliderVerts();
        }
        if (Event.current.type == EventType.ValidateCommand)
        {
            switch (Event.current.commandName)
            {
            case "UndoRedoPerformed":
                sprite.ForceMaterial(sprite.TerrainMaterial, true);
                sprite.Build(true);
                cachedColliders = sprite.GetColliderVerts();
                break;
            }
        }
    }
    public static void Show(IFerr2DTMaterial aMaterial)
    {
        Ferr2DT_TerrainMaterialWindow window = EditorWindow.GetWindow <Ferr2DT_TerrainMaterialWindow>();

        window.material = aMaterial;
    }
    public static void EditUVsSimple(IFerr2DTMaterial aMat, Ferr2DT_SegmentDescription desc)
    {
        Rect cap  = aMat.ToPixels(desc.leftCap);
        Rect body = aMat.ToPixels(desc.body[0]);

        float   height    = body.height;
        float   capWidth  = cap.width;
        float   bodyWidth = body.width;
        int     bodyCount = desc.body.Length;
        Vector2 pos       = new Vector2(cap.x, cap.y);

        if (cap.width == 0 && cap.height == 0)
        {
            pos = new Vector2(body.x, body.y);
        }

        Ferr.EditorTools.Box(2, () => {
            pos      = EditorGUILayout.Vector2Field("Position", pos);
            height   = EditorGUILayout.FloatField("Height", height);
            capWidth = EditorGUILayout.FloatField("Cap Width", capWidth);
            desc.SingleColliderCapOffset = EditorGUILayout.Slider("Cap Offset", desc.SingleColliderCapOffset, -1, 1);
            bodyWidth = Mathf.Max(1, EditorGUILayout.FloatField("Body Width", bodyWidth));
            bodyCount = Mathf.Max(1, EditorGUILayout.IntField("Body slices", bodyCount));

            EditorGUILayout.Space();
            EditorGUILayout.LabelField("Colliders", EditorStyles.boldLabel);

            desc.SingleColliderCapType = (Ferr2D_CapColliderType)EditorGUILayout.EnumPopup("Collider Type", desc.SingleColliderCapType);
            desc.SingleColliderCapSize = EditorGUILayout.Slider("Collider Size", desc.SingleColliderCapSize, -1, 2);

            if (bodyCount != desc.body.Length)
            {
                Rect[] bodies = desc.body;
                Array.Resize <Rect>(ref bodies, bodyCount);
                desc.body = bodies;
            }

            float currX    = pos.x;
            Rect leftCap   = desc.leftCap;
            leftCap.x      = currX;
            leftCap.y      = pos.y;
            leftCap.width  = capWidth;
            leftCap.height = capWidth == 0 ? 0 : height;
            desc.leftCap   = aMat.ToNative(leftCap);
            currX         += capWidth;

            for (int i = 0; i < desc.body.Length; i++)
            {
                desc.body[i].x      = currX;
                desc.body[i].y      = pos.y;
                desc.body[i].width  = bodyWidth;
                desc.body[i].height = height;
                desc.body[i]        = aMat.ToNative(desc.body[i]);
                currX += bodyWidth;
            }

            Rect rightCap   = desc.rightCap;
            rightCap.x      = currX;
            rightCap.y      = pos.y;
            rightCap.width  = capWidth;
            rightCap.height = capWidth == 0 ? 0 : height;
            desc.rightCap   = aMat.ToNative(rightCap);
        });
    }
    private void LegacyAddCap(List <Vector2> aSegment, Ferr2DT_SegmentDescription aDesc, bool aInner, float aDir, float aScale, bool aSmooth)
    {
        IFerr2DTMaterial   mat  = TerrainMaterial;
        Ferr2D_DynamicMesh mesh = DMesh;
        int     index           = 0;
        Vector2 dir             = Vector2.zero;

        if (aDir < 0)
        {
            index = 0;
            dir   = aSegment[0] - aSegment[1];
        }
        else
        {
            index = aSegment.Count - 1;
            dir   = aSegment[aSegment.Count - 1] - aSegment[aSegment.Count - 2];
        }
        dir.Normalize();
        Vector2 norm = aSmooth ? Ferr2D_Path.HermiteGetNormal(aSegment, index, 0, false): Ferr2D_Path.GetNormal(aSegment, index, false);
        Vector2 pos  = aSegment[index];
        float   yOff = fill == Ferr2DT_FillMode.InvertedClosed ? -aDesc.yOffset : aDesc.yOffset;
        Rect    cap;

        if (aDir < 0)
        {
            if (fill == Ferr2DT_FillMode.InvertedClosed)
            {
                cap = (!aInner && aDesc.innerRightCap.width > 0) ? mat.ToUV(aDesc.innerRightCap) : mat.ToUV(aDesc.rightCap);
            }
            else
            {
                cap = (aInner && aDesc.innerLeftCap.width > 0) ? mat.ToUV(aDesc.innerLeftCap) : mat.ToUV(aDesc.leftCap);
            }
        }
        else
        {
            if (fill == Ferr2DT_FillMode.InvertedClosed)
            {
                cap = (!aInner && aDesc.innerLeftCap.width > 0) ? mat.ToUV(aDesc.innerLeftCap) : mat.ToUV(aDesc.leftCap);
            }
            else
            {
                cap = (aInner && aDesc.innerRightCap.width > 0) ? mat.ToUV(aDesc.innerRightCap) : mat.ToUV(aDesc.rightCap);
            }
        }

        float width = cap.width * unitsPerUV.x;
        float scale = (cap.height / 2) * unitsPerUV.y * aScale;

        float minU = fill == Ferr2DT_FillMode.InvertedClosed ? cap.xMax : cap.x;
        float maxU = fill == Ferr2DT_FillMode.InvertedClosed ? cap.x    : cap.xMax;
        float minV = fill == Ferr2DT_FillMode.InvertedClosed ? cap.yMax : cap.y;
        float maxV = fill == Ferr2DT_FillMode.InvertedClosed ? cap.y    : cap.yMax;

        if (aDir >= 0)
        {
            float t = minU;
            minU = maxU;
            maxU = t;
        }

        int v1 = mesh.AddVertex(pos + dir * width + norm * (scale + yOff), -slantAmount + aDesc.zOffset, new Vector2(minU, minV));
        int v2 = mesh.AddVertex(pos + norm * (scale + yOff), -slantAmount + aDesc.zOffset, new Vector2(maxU, minV));

        int v15 = splitMiddle ? mesh.AddVertex(pos + dir * width + (norm * yOff), aDesc.zOffset, new Vector2(minU, cap.y + (cap.height / 2))) : -1;
        int v25 = splitMiddle ? mesh.AddVertex(pos + (norm * yOff), aDesc.zOffset, new Vector2(maxU, cap.y + (cap.height / 2))) : -1;

        int v3 = mesh.AddVertex(pos - norm * (scale - yOff), slantAmount + aDesc.zOffset, new Vector2(maxU, maxV));
        int v4 = mesh.AddVertex(pos + dir * width - norm * (scale - yOff), slantAmount + aDesc.zOffset, new Vector2(minU, maxV));

        if (splitMiddle && aDir < 0)
        {
            mesh.AddFace(v1, v2, v25, v15);
            mesh.AddFace(v15, v25, v3, v4);
        }
        else if (splitMiddle && aDir >= 0)
        {
            mesh.AddFace(v2, v1, v15, v25);
            mesh.AddFace(v25, v15, v4, v3);
        }
        else if (aDir < 0)
        {
            mesh.AddFace(v1, v2, v3, v4);
        }
        else
        {
            mesh.AddFace(v2, v1, v4, v3);
        }
    }
    static void UpdateTerrainAssets(bool aCreateNewAssets)
    {
        Ferr2DT_PathTerrain[] terrain          = GameObject.FindObjectsOfType <Ferr2DT_PathTerrain>();
        List <string>         missing          = new List <string>();
        List <string>         updatedMaterials = new List <string>();
        int updated = 0;
        int created = 0;
        int skipped = 0;
        int good    = 0;

        for (int i = 0; i < terrain.Length; i++)
        {
            IFerr2DTMaterial mat = terrain[i].TerrainMaterial;
            if (mat is Ferr2DT_TerrainMaterial)
            {
                string path           = AssetDatabase.GetAssetPath(mat as UnityEngine.Object);
                bool   newAssetExists = true;

                path = Path.ChangeExtension(path, "asset");
                if (!File.Exists(path))
                {
                    string name = Path.GetFileNameWithoutExtension(path);

                    if (aCreateNewAssets)
                    {
                        updatedMaterials.Add(name + ".prefab");
                        ScriptableObject newAsset = ((Ferr2DT_TerrainMaterial)mat).CreateNewFormatMaterial();
                        AssetDatabase.CreateAsset(newAsset, path);
                        AssetDatabase.SaveAssets();
                        created += 1;
                    }
                    else
                    {
                        if (!missing.Contains(name))
                        {
                            missing.Add(name);
                        }
                        skipped       += 1;
                        newAssetExists = false;
                    }
                }

                if (newAssetExists)
                {
                    Ferr2DT_Material newMat = AssetDatabase.LoadAssetAtPath <Ferr2DT_Material>(path);
                    if (newMat == null)
                    {
                        Debug.Log("Error attempting to load asset: " + path);
                    }
                    else
                    {
                        Undo.RecordObject(terrain[i], "Updating terrain material");
                        updated += 1;
                        terrain[i].TerrainMaterial = newMat;
                        terrain[i].Build(true);
                    }
                }
            }
            else
            {
                good += 1;
            }
        }
        Debug.LogFormat("Ferr2D scene update done - {0} materials created, {1} objs updated, {2} already good, {3} objs skipped.", created, updated, good, skipped);
        if (missing.Count > 0)
        {
            Debug.LogFormat("Missing updated assets for these materials: {0}", string.Join(", ", missing.ToArray()));
        }
        if (updatedMaterials.Count > 0)
        {
            Debug.LogFormat("Consider deleting these old materials once all scenes have been upgraded: {0}", string.Join(", ", updatedMaterials.ToArray()));
        }

        if (updated > 0 || created > 0)
        {
            EditorSceneManager.MarkAllScenesDirty();
        }
    }
    public static void EditUVsComplex(IFerr2DTMaterial aMat, Ferr2DT_SegmentDescription desc, float aWidth, ref int aCurrBody)
    {
        int currBody = aCurrBody;
        int bodyID   = 0;

        Ferr.EditorTools.Box(2, () => {
            if (desc.leftCap.width == 0 && desc.leftCap.height == 0 &&
                desc.rightCap.width == 0 && desc.rightCap.height == 0)
            {
                desc.EditorLeftCapOffset  = EditorGUILayout.Slider("Left Offset", desc.EditorLeftCapOffset, -1, 1);
                desc.EditorRightCapOffset = EditorGUILayout.Slider("Right Offset", desc.EditorRightCapOffset, -1, 1);
            }

            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField("Body", GUILayout.Width(40f));

            bodyID = Mathf.Clamp(currBody, 0, desc.body.Length);
            if (GUILayout.Button("<", GUILayout.Width(20f)))
            {
                currBody = Mathf.Clamp(currBody - 1, 0, desc.body.Length - 1);
            }
            EditorGUILayout.LabelField("" + (bodyID + 1), GUILayout.Width(12f));
            if (GUILayout.Button(">", GUILayout.Width(20f)))
            {
                currBody = Mathf.Clamp(currBody + 1, 0, desc.body.Length - 1);
            }
            bodyID     = Mathf.Clamp(currBody, 0, desc.body.Length - 1);
            int length = Math.Max(1, EditorGUILayout.IntField(desc.body.Length, GUILayout.Width(32f)));
            EditorGUILayout.LabelField("Total", GUILayout.Width(40f));
            if (length != desc.body.Length)
            {
                Rect[] bodies = desc.body;
                Array.Resize <Rect>(ref bodies, length);
                desc.body = bodies;
            }

            EditorGUILayout.EndHorizontal();
            EditorGUILayout.Space();
            desc.body[bodyID] = AtlasField(aMat, desc.body[bodyID], aMat.edgeMaterial != null ? aMat.edgeMaterial.mainTexture : EditorGUIUtility.whiteTexture);

            float pixelWidth = aMat.edgeMaterial == null || aMat.edgeMaterial.mainTexture == null ? 1f / 256 : 1f / aMat.edgeMaterial.mainTexture.width;
            if (desc.body[bodyID].width < pixelWidth)
            {
                desc.body[bodyID].width = pixelWidth;
            }
        });
        aCurrBody = currBody;

        EditorGUILayout.Space();
        Ferr.EditorTools.Box(2, () => {
            if (desc.leftCap.width == 0 && desc.leftCap.height == 0)
            {
                if (EditorGUILayout.Toggle("Left Cap", false))
                {
                    desc.leftCap = aMat.ToNative(new Rect(0, 0, 50, 50));
                }
            }
            else
            {
                if (EditorGUILayout.Toggle("Left Cap", true))
                {
                    desc.EditorLeftCapOffset = EditorGUILayout.Slider("Cap Offset", desc.EditorLeftCapOffset, -1, 1);
                    desc.leftCap             = AtlasField(aMat, desc.leftCap, aMat.edgeMaterial != null ? aMat.edgeMaterial.mainTexture : EditorGUIUtility.whiteTexture);
                }
                else
                {
                    desc.leftCap = new Rect(0, 0, 0, 0);
                }
            }
            EditorGUI.indentLevel         += 1;
            desc.EditorLeftCapType         = Convert.ToInt32(EditorGUILayout.EnumPopup("Collider Type", (Ferr2D_CapColliderType)desc.EditorLeftCapType));
            desc.EditorLeftCapColliderSize = EditorGUILayout.Slider("Collider Size", desc.EditorLeftCapColliderSize, -1, 2);
            EditorGUI.indentLevel         -= 1;
        });

        EditorGUILayout.Space();
        Ferr.EditorTools.Box(2, () => {
            if (desc.innerLeftCap.width == 0 && desc.innerLeftCap.height == 0)
            {
                if (EditorGUILayout.Toggle("Inner Left Cap", false))
                {
                    desc.innerLeftCap = aMat.ToNative(new Rect(0, 0, 50, 50));
                }
            }
            else
            {
                if (EditorGUILayout.Toggle("Inner Left Cap", true))
                {
                    Ferr.EditorTools.Box(2, () => {
                        desc.EditorInnerLeftCapOffset = EditorGUILayout.Slider("Cap Offset", desc.EditorInnerLeftCapOffset, -1, 1);
                        desc.innerLeftCap             = AtlasField(aMat, desc.innerLeftCap, aMat.edgeMaterial != null ? aMat.edgeMaterial.mainTexture : EditorGUIUtility.whiteTexture);
                    });
                }
                else
                {
                    desc.innerLeftCap = new Rect(0, 0, 0, 0);
                }
            }
            EditorGUI.indentLevel              += 1;
            desc.EditorInnerLeftCapType         = Convert.ToInt32(EditorGUILayout.EnumPopup("Collider Type", (Ferr2D_CapColliderType)desc.EditorInnerLeftCapType));
            desc.EditorInnerLeftCapColliderSize = EditorGUILayout.Slider("Collider Size", desc.EditorInnerLeftCapColliderSize, -1, 2);
            EditorGUI.indentLevel              -= 1;
        });

        EditorGUILayout.Space();
        Ferr.EditorTools.Box(2, () => {
            if (desc.rightCap.width == 0 && desc.rightCap.height == 0)
            {
                if (EditorGUILayout.Toggle("Right Cap", false))
                {
                    desc.rightCap = aMat.ToNative(new Rect(0, 0, 50, 50));
                }
            }
            else
            {
                if (EditorGUILayout.Toggle("Right Cap", true))
                {
                    Ferr.EditorTools.Box(2, () => {
                        desc.EditorRightCapOffset = EditorGUILayout.Slider("Cap Offset", desc.EditorRightCapOffset, -1, 1);
                        desc.rightCap             = AtlasField(aMat, desc.rightCap, aMat.edgeMaterial != null ? aMat.edgeMaterial.mainTexture : EditorGUIUtility.whiteTexture);
                    });
                }
                else
                {
                    desc.rightCap = new Rect(0, 0, 0, 0);
                }
            }
            EditorGUI.indentLevel          += 1;
            desc.EditorRightCapType         = Convert.ToInt32(EditorGUILayout.EnumPopup("Collider Type", (Ferr2D_CapColliderType)desc.EditorRightCapType));
            desc.EditorRightCapColliderSize = EditorGUILayout.Slider("Collider Size", desc.EditorRightCapColliderSize, -1, 2);
            EditorGUI.indentLevel          -= 1;
        });

        EditorGUILayout.Space();
        Ferr.EditorTools.Box(2, () => {
            if (desc.innerRightCap.width == 0 && desc.innerRightCap.height == 0)
            {
                if (EditorGUILayout.Toggle("Inner Right Cap", false))
                {
                    desc.innerRightCap = aMat.ToNative(new Rect(0, 0, 50, 50));
                }
            }
            else
            {
                if (EditorGUILayout.Toggle("Inner Right Cap", true))
                {
                    Ferr.EditorTools.Box(2, () => {
                        desc.EditorInnerRightCapOffset = EditorGUILayout.Slider("Cap Offset", desc.EditorInnerRightCapOffset, -1, 1);
                        desc.innerRightCap             = AtlasField(aMat, desc.innerRightCap, aMat.edgeMaterial != null ? aMat.edgeMaterial.mainTexture : EditorGUIUtility.whiteTexture);
                    });
                }
                else
                {
                    desc.innerRightCap = new Rect(0, 0, 0, 0);
                }
            }
            EditorGUI.indentLevel               += 1;
            desc.EditorInnerRightCapType         = Convert.ToInt32(EditorGUILayout.EnumPopup("Collider Type", (Ferr2D_CapColliderType)desc.EditorInnerRightCapType));
            desc.EditorInnerRightCapColliderSize = EditorGUILayout.Slider("Collider Size", desc.EditorInnerRightCapColliderSize, -1, 2);
            EditorGUI.indentLevel               -= 1;
        });
    }
示例#25
0
    public static void EditUVsComplex(IFerr2DTMaterial aMat, Ferr2DT_SegmentDescription desc, float aWidth, ref int aCurrBody)
    {
        EditorGUILayout.BeginHorizontal();
        EditorGUILayout.LabelField("Body", GUILayout.Width(40f));

        int bodyID = Mathf.Clamp(aCurrBody, 0, desc.body.Length);

        if (GUILayout.Button("<", GUILayout.Width(20f)))
        {
            aCurrBody = Mathf.Clamp(aCurrBody - 1, 0, desc.body.Length - 1);
        }
        EditorGUILayout.LabelField("" + (bodyID + 1), GUILayout.Width(12f));
        if (GUILayout.Button(">", GUILayout.Width(20f)))
        {
            aCurrBody = Mathf.Clamp(aCurrBody + 1, 0, desc.body.Length - 1);
        }
        bodyID = Mathf.Clamp(aCurrBody, 0, desc.body.Length - 1);
        int length = Math.Max(1, EditorGUILayout.IntField(desc.body.Length, GUILayout.Width(32f)));

        EditorGUILayout.LabelField("Total", GUILayout.Width(40f));
        if (length != desc.body.Length)
        {
            Array.Resize <Rect>(ref desc.body, length);
        }

        EditorGUILayout.EndHorizontal();

        EditorGUILayout.Space();
        desc.body[bodyID] = AtlasField(aMat, desc.body[bodyID], aMat.edgeMaterial != null ? aMat.edgeMaterial.mainTexture : EditorGUIUtility.whiteTexture);
        if (desc.leftCap.width == 0 && desc.leftCap.height == 0)
        {
            if (EditorGUILayout.Toggle("Left Cap", false))
            {
                desc.leftCap = new Rect(0, 0, 30, 30);
            }
        }
        else
        {
            if (EditorGUILayout.Toggle("Left Cap", true))
            {
                desc.leftCap = AtlasField(aMat, desc.leftCap, aMat.edgeMaterial != null ? aMat.edgeMaterial.mainTexture : EditorGUIUtility.whiteTexture);
            }
            else
            {
                desc.leftCap = new Rect(0, 0, 0, 0);
            }
        }
        if (desc.innerLeftCap.width == 0 && desc.innerLeftCap.height == 0)
        {
            if (EditorGUILayout.Toggle("Inner Left Cap", false))
            {
                desc.innerLeftCap = new Rect(0, 0, 30, 30);
            }
        }
        else
        {
            if (EditorGUILayout.Toggle("Inner Left Cap", true))
            {
                desc.innerLeftCap = AtlasField(aMat, desc.innerLeftCap, aMat.edgeMaterial != null ? aMat.edgeMaterial.mainTexture : EditorGUIUtility.whiteTexture);
            }
            else
            {
                desc.innerLeftCap = new Rect(0, 0, 0, 0);
            }
        }

        if (desc.rightCap.width == 0 && desc.rightCap.height == 0)
        {
            if (EditorGUILayout.Toggle("Right Cap", false))
            {
                desc.rightCap = new Rect(0, 0, 30, 30);
            }
        }
        else
        {
            if (EditorGUILayout.Toggle("Right Cap", true))
            {
                desc.rightCap = AtlasField(aMat, desc.rightCap, aMat.edgeMaterial != null ? aMat.edgeMaterial.mainTexture : EditorGUIUtility.whiteTexture);
            }
            else
            {
                desc.rightCap = new Rect(0, 0, 0, 0);
            }
        }
        if (desc.innerRightCap.width == 0 && desc.innerRightCap.height == 0)
        {
            if (EditorGUILayout.Toggle("Inner Right Cap", false))
            {
                desc.innerRightCap = new Rect(0, 0, 30, 30);
            }
        }
        else
        {
            if (EditorGUILayout.Toggle("Inner Right Cap", true))
            {
                desc.innerRightCap = AtlasField(aMat, desc.innerRightCap, aMat.edgeMaterial != null ? aMat.edgeMaterial.mainTexture : EditorGUIUtility.whiteTexture);
            }
            else
            {
                desc.innerRightCap = new Rect(0, 0, 0, 0);
            }
        }
    }
示例#26
0
    public static void ShowPreviewDirection(IFerr2DTMaterial aMat, Ferr2DT_TerrainDirection aDir, Rect aBounds, bool aSimpleUVs, bool aEditable)
    {
        Ferr2DT_SegmentDescription desc = aMat.GetDescriptor(aDir);

        if (!aMat.Has(aDir))
        {
            return;
        }

        if (!aEditable)
        {
            for (int i = 0; i < desc.body.Length; i++)
            {
                Ferr.EditorTools.DrawRect(aMat.ToScreen(desc.body[i]), aBounds);
            }
            Ferr.EditorTools.DrawRect(aMat.ToScreen(desc.leftCap), aBounds);
            Ferr.EditorTools.DrawRect(aMat.ToScreen(desc.rightCap), aBounds);
            Ferr.EditorTools.DrawRect(aMat.ToScreen(desc.innerLeftCap), aBounds);
            Ferr.EditorTools.DrawRect(aMat.ToScreen(desc.innerRightCap), aBounds);
        }
        else if (aSimpleUVs)
        {
            float   height    = MaxHeight(desc);
            float   capWidth  = Mathf.Max(desc.leftCap.width, desc.rightCap.width);
            float   bodyWidth = desc.body[0].width;
            int     bodyCount = desc.body.Length;
            float   texWidth  = aMat.edgeMaterial.mainTexture != null ? aMat.edgeMaterial.mainTexture.width  : 1;
            float   texHeight = aMat.edgeMaterial.mainTexture != null ? aMat.edgeMaterial.mainTexture.height : 1;
            Vector2 pos       = new Vector2(desc.leftCap.x, desc.leftCap.y);
            if (desc.leftCap.width == 0 && desc.leftCap.height == 0)
            {
                pos = new Vector2(desc.body[0].x, desc.body[0].y);
            }

            Rect bounds = new Rect(pos.x, pos.y, capWidth * 2 + bodyWidth * bodyCount, height);
            bounds = aMat.ToNative(Ferr.EditorTools.UVRegionRect(aMat.ToPixels(bounds), aBounds));
            bounds = ClampRect(bounds, (Texture2D)aMat.edgeMaterial.mainTexture);

            Ferr.EditorTools.DrawVLine(new Vector2((pos.x + capWidth) * texWidth + aBounds.x, (pos.y * texHeight) + 2), height * texHeight);
            for (int i = 1; i <= desc.body.Length; i++)
            {
                Ferr.EditorTools.DrawVLine(new Vector2((pos.x + capWidth + bodyWidth * i) * texWidth + aBounds.x, (pos.y * texHeight) + 2), height * texHeight);
            }

            height    = bounds.height;
            bodyWidth = (bounds.width - capWidth * 2) / bodyCount;
            pos.x     = bounds.x;
            pos.y     = bounds.y;

            float currX = pos.x;
            desc.leftCap.x      = currX;
            desc.leftCap.y      = pos.y;
            desc.leftCap.width  = capWidth;
            desc.leftCap.height = capWidth == 0 ? 0 : height;
            currX += capWidth;

            for (int i = 0; i < desc.body.Length; i++)
            {
                desc.body[i].x      = currX;
                desc.body[i].y      = pos.y;
                desc.body[i].width  = bodyWidth;
                desc.body[i].height = height;
                currX += bodyWidth;
            }

            desc.rightCap.x      = currX;
            desc.rightCap.y      = pos.y;
            desc.rightCap.width  = capWidth;
            desc.rightCap.height = capWidth == 0 ? 0 : height;
        }
        else
        {
            for (int i = 0; i < desc.body.Length; i++)
            {
                desc.body[i] = ClampRect(aMat.ToNative(Ferr.EditorTools.UVRegionRect(aMat.ToPixels(desc.body[i]), aBounds)), (Texture2D)aMat.edgeMaterial.mainTexture);
            }
            if (desc.leftCap.width != 0 && desc.leftCap.height != 0)
            {
                desc.leftCap = ClampRect(aMat.ToNative(Ferr.EditorTools.UVRegionRect(aMat.ToPixels(desc.leftCap), aBounds)), (Texture2D)aMat.edgeMaterial.mainTexture);
            }
            if (desc.rightCap.width != 0 && desc.rightCap.height != 0)
            {
                desc.rightCap = ClampRect(aMat.ToNative(Ferr.EditorTools.UVRegionRect(aMat.ToPixels(desc.rightCap), aBounds)), (Texture2D)aMat.edgeMaterial.mainTexture);
            }

            if (desc.innerLeftCap.width != 0 && desc.innerLeftCap.height != 0)
            {
                desc.innerLeftCap = ClampRect(aMat.ToNative(Ferr.EditorTools.UVRegionRect(aMat.ToPixels(desc.innerLeftCap), aBounds)), (Texture2D)aMat.edgeMaterial.mainTexture);
            }
            if (desc.innerRightCap.width != 0 && desc.innerRightCap.height != 0)
            {
                desc.innerRightCap = ClampRect(aMat.ToNative(Ferr.EditorTools.UVRegionRect(aMat.ToPixels(desc.innerRightCap), aBounds)), (Texture2D)aMat.edgeMaterial.mainTexture);
            }
        }
    }