Unity场景扩展,生成Mesh

1 篇文章 0 订阅
1 篇文章 0 订阅

场景扩展:

案例1: OnSceneGUI 实现如下效果

 

 代码:

[CustomEditor(typeof(Test))]  --函数作用是Test对象能在编辑器激活

public class MyEditor : Editor {

    private void OnSceneGUI()

    {

        Test test = (Test)target;  --选中的对象 需要CustomEditor

        Handles.Label(test.transform.position + Vector3.up * 2,

            test.transform.name + ":" + test.transform.position.ToString());

        //开始绘制GUI

        Handles.BeginGUI();

        GUILayout.BeginArea(new Rect(100, 200, 100, 100));

        if(GUILayout.Button("这是一个按钮!"))

        {

            Debug.Log("test");

        }

        GUILayout.Label("我在编辑Scene视图");

        GUILayout.EndArea();

        Handles.EndGUI();

    }

}

 

案例二:继承OnInspectorGUI

 

实现如下效果:

 

public class MyEditor : Editor {

    private void OnSceneGUI()

    {

       

    }

    public override void OnInspectorGUI()

    {

        GUILayout.Label("This is a Label");

        if(GUILayout.Button("Button"))

        {

            Debug.Log("cccc");

        }

    }

}

 

案例三:打开文件面板

 

string[] filters = {"region file", "region"};

            string defaultPath = Application.streamingAssetsPath + "/regions";

            string strPath = EditorUtility.OpenFilePanelWithFilters("加载区块文件", defaultPath, filters);

            if (!string.IsNullOrEmpty(strPath))

                regionEditor.Load(strPath);

 

2、Mesh生成

实现如下图形

 

!!!注意:绘制网格三角形顺序 需要严格按照顺时针或者逆时针绘制

  颜色最大值是255  m_colors[vertexIdx + 0] = new Color32(1, 1, 1, 255);

 

C#代码

protected Mesh _mesh;

    public Color color;

    public float xWidth = 100;

    public float yWidth = 100;

    private void Awake()

    {

        var meshFilter = GetComponent<MeshFilter>();

        if(meshFilter == null)

        {

            meshFilter = gameObject.AddComponent<MeshFilter>();

        }

        if(_mesh == null)

        {

            _mesh = new Mesh();

            meshFilter.mesh = _mesh;

        }

    }

    // Use this for initialization

    void Start () {

        Vector3[] vertices = new Vector3[8];

        vertices[0] = new Vector3(0, 0, 0);

        vertices[1] = new Vector3(500, 0, 0);

        vertices[2] = new Vector3(500, 500, 0);

        vertices[3] = new Vector3(0, 500, 0);

        vertices[4] = new Vector3(0 - xWidth, 0 - yWidth, 0);

        vertices[5] = new Vector3(500 + xWidth, 0 - yWidth, 0);

        vertices[6] = new Vector3(500 + xWidth, 500 + yWidth, 0);

        vertices[7] = new Vector3(0 - xWidth, 500 + yWidth, 0);

        int[] triangles = new int[24] { 0, 4, 7, 7,3,0,3,7,2,2,7,6,6,1,2,1,6,5,5,0,1,0,5,4 };

        _mesh.vertices = vertices;

        _mesh.triangles = triangles;

        UpdateColor();

        UpdateUVs(vertices);

       }

    protected void UpdateColor()

    {

        Color32[] colors32 = new Color32[_mesh.vertices.Length];

        for (int i = 0; i < colors32.Length; i++)

        {

            colors32[i] = color;

        }

        _mesh.colors32 = colors32;

    }

    protected void UpdateUVs(Vector3[] vertices)

    {

        Vector2[] uvs = new Vector2[vertices.Length];

        for (int i = 0; i < uvs.Length; i++)

        {

            float u = (vertices[i].x+xWidth) / (500+2*xWidth) ;

            float v = (vertices[i].y+yWidth) / (500+2*yWidth) ;

            u = Mathf.Clamp(u,0, 1);

            v = Mathf.Clamp(v,0, 1);

            uvs[i] = new Vector2(u, v);

        }

        _mesh.uv = uvs;

    }

 

材质Shader:

Shader "LOS/Basic" {

       SubShader{

              Tags{

              "IgnoreProjector" = "True"

              "Queue" = "Transparent+2"

              "RenderType" = "Transparent"

       }

              Pass{

              Blend SrcAlpha OneMinusSrcAlpha

              ZWrite Off

              Lighting Off

              Fog{ Mode Off }

              CGPROGRAM

#pragma vertex vert

#pragma fragment frag

#pragma target 3.0

              uniform sampler2D _MainTex;

       uniform float _intensity;

       struct vIn {

              float4 vertex : POSITION;

              float4 color : COLOR;

       };

       struct v2f {

              float4 pos : SV_POSITION;

              float4 color : COLOR;

       };

       v2f vert(vIn v) {

              v2f o;

              o.color = v.color;

              o.pos = UnityObjectToClipPos(v.vertex);

              return o;

       }

       fixed4 frag(v2f i) : COLOR{

              _intensity = 1;

       return fixed4(i.color.rgb * _intensity, i.color.a);

       }

              ENDCG

       }

       }

}

 

3、九宫格动态地图加载

玩家在移动的过程中,会加载周围共九个方向的动态地图,如图1:

              

                                 图1 九宫格 

                

  

                                 图2  向上移动

绿色框代表屏幕大小,因此每块地图的大小基于屏幕大小设定,宽度为屏幕宽度的一半,高度为屏幕高度的一半。

每块地图都有自己的逻辑坐标,如图1括号所示,在加载地图时根据玩家逻辑坐标的改变更新地图显示,如图2,向上移动后

Y轴坐标为-1地图删除,Y轴坐标为2加载出来。 

最终效果如图3所示

 

                                     图3  最终效果

实现

定义一个字典存放地图逻辑坐标和GameObject:

//存储玩家格子坐标及对应地图物体

private Dictionary<Vector2Int, GameObject> m_dynamicTileMapDict = new Dictionary<Vector2Int, GameObject>();

 

设定一个更新时间,根据玩家的位置动态更新玩家周围的地图

 

    /// <summary>

    /// 删除和加载动态地图

    /// </summary>

    /// <param name="pos"></param>

    private void UpdatePlayerTilePoint(Vector3 pos)

    {

        if(m_playerCurrentTilePoint!=m_playerPreviousTilePoint)

        {

            //位置发生改变  加载和删除动态地图

            m_playerPreviousTilePoint = m_playerCurrentTilePoint;

            m_tempPointList.Clear();

            for (int i = m_playerCurrentTilePoint.x - 1; i <= m_playerCurrentTilePoint.x + 1; i++)

            {

                for (int j = m_playerCurrentTilePoint.y - 1; j <= m_playerCurrentTilePoint.y + 1; j++)

                {

                    Vector2Int vector2 = new Vector2Int(i, j);

                    if (vector2 != m_playerCurrentTilePoint)

                    {

                        m_tempPointList.Add(vector2);

                        //字典没有改地图信息 加载

                        if (!m_dynamicTileMapDict.ContainsKey(vector2))

                        {

                            AddDynamicMap(vector2);

                        }

                    }

                }

            }

            // m_tempPointList 不包含字典key  删除

            foreach (var key in new List<Vector2Int>(m_dynamicTileMapDict.Keys))

            {

                if(!m_tempPointList.Contains(key) && key != m_playerCurrentTilePoint)

                {

                    RemoveDynamicMap(key);

                }

            }

        }

    }

 

 

目前加载地图方式,通过加载Prefab的名字实现

 

   /// <summary>

    /// 根据格子坐标动态加载物体

    /// </summary>

    /// <param name="point"></param>

    /// <returns></returns>

    public GameObject LoadMapPrefabByPointName(Vector2Int point)

    {

        //TODO 根据AssetBundle加载

        string name = string.Format("[{0},{1}]Grid", point.x, point.y);

        GameObject prefab =null;

        try

        {

            prefab = Instantiate(Resources.Load("MapPrefab/" + name)) as GameObject;

            prefab.transform.SetParent(this.transform);

        }

        catch(Exception e)

        {

            Debug.LogError("没有地图资源加载");

        }

        return prefab;

    }

 

 /// <summary>

    /// 根据格子坐标动态添加地图

    /// </summary>

    /// <param name="pos"></param>

    public void AddDynamicMap(Vector2Int point)

    {

        if(!m_dynamicTileMapDict.ContainsKey(point))

        {

            m_dynamicTileMapDict.Add(point, LoadMapPrefabByPointName(point));

        }

    }

    /// <summary>

    /// 根据格子坐标动态显示已加载地图

    /// </summary>

    /// <param name="pos"></param>

    public void ShowDynamicMap(Vector2Int point)

    {

        if (m_dynamicTileMapDict.ContainsKey(point))

        {

            m_dynamicTileMapDict[point].SetActive(true);

        }

    }

    /// <summary>

    /// 根据格子坐标动态删除地图

    /// </summary>

    /// <param name="pos"></param>

    public void RemoveDynamicMap(Vector2Int point)

    {

        if (m_dynamicTileMapDict.ContainsKey(point))

        {

            Destroy(m_dynamicTileMapDict[point]);

            m_dynamicTileMapDict.Remove(point);

        }

    }

    /// <summary>

    /// 根据格子坐标动态隐藏地图

    /// </summary>

    /// <param name="pos"></param>

    public void DisappearDynamicMap(Vector2Int point)

    {

        if (m_dynamicTileMapDict.ContainsKey(point))

        {

            m_dynamicTileMapDict[point].SetActive(false);

        }

    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

张乂卓

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值