Unity场景扩展,生成Mesh
Posted 雨尘无痕
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity场景扩展,生成Mesh相关的知识,希望对你有一定的参考价值。
场景扩展:
案例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);
以上是关于Unity场景扩展,生成Mesh的主要内容,如果未能解决你的问题,请参考以下文章
[Unity 学习] - 进阶篇 - Mesh基础系列1:生成网格
Unity3D网格 Mesh ( 网格概念 | 网格示例 | Unity 中 3D 物体渲染模式 | 着色模式 | 线框模式 | 线框着色模式 )