Unity3D 根据GIS中的二维线坐标画墙
最近研究了一下GameObject的mesh和纹理,特地写了一个demo来实现根据线生成墙
代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class wasd : MonoBehaviour
{
public Material mater;
private GameObject gameObject;
private GameObject simpleMesh;
private float speed = 20f;
private float mousespeed = 200f;
Vector3 oldMousePosition;
Vector3 newMousePosition;
class GISPoint
{
public float x;
public float y;
public GISPoint(float x1,float y1)
{
x = x1;
y = y1;
}
}
void createWallByPoints(List<GISPoint> points,float wall_height, Mesh mesh)
{
float wall_height2 = 1.0f;
float wall_length2 = 1.0f;
int pntCount = points.Count;
int rectCount = pntCount - 1;
int vertCount = rectCount * 4;
Vector3[] verts= new Vector3[vertCount];
for (int i = 0; i < rectCount; i++)
{
verts[i*4] = new Vector3(points[i].x, 0, points[i].y);
verts[i*4+1]= new Vector3(points[i].x, wall_height, points[i].y);
verts[i*4+2] = new Vector3(points[i+1].x, wall_height, points[i+1].y);
verts[i*4+3] = new Vector3(points[i+1].x, 0, points[i+1].y);
}
mesh.vertices = verts;
int[] triangles = new int[rectCount * 2*3];
//n=ponitIndex; n(2n,2n+1)
//p (3P,3P+1,3p+2)
for (int i = 0; i < rectCount; i++)
{
//2n是第一个三角形,2n+1是第二个三角形
int firstIndex = i * 2;
int secondIndex = i *2 + 1;
triangles[firstIndex*3] = i*4;
triangles[firstIndex * 3 + 1] = i * 4+1;
triangles[firstIndex * 3 + 2] = i * 4+2;
triangles[secondIndex * 3] = i * 4;
triangles[secondIndex * 3 + 1] = i * 4 + 2;
triangles[secondIndex * 3 + 2] = i * 4+3;
}
mesh.triangles = triangles;
Vector2[] uvs = new Vector2[vertCount];
for(int i=0;i< pntCount - 1; i++)
{
uvs[4 * i] = new Vector2(0, 0);
uvs[4 * i+1] = new Vector2(0, wall_height2);
uvs[4 * i+2] = new Vector2(-1 * wall_length2, wall_height2);
uvs[4 * i+3] = new Vector2(-1 * wall_length2, 0);
}
mesh.uv = uvs;
/*
mesh.vertices = new Vector3[] {
new Vector3(1* wall_length, 0, 0), new Vector3(1* wall_length, wall_height, 0),new Vector3(0, wall_height, 0),new Vector3(0, 0, 0),
new Vector3(0, 0, 0), new Vector3(0, wall_height, 0), new Vector3(0, wall_height, 1* wall_length), new Vector3(0, 0, 1* wall_length),
new Vector3(0, 0, 1* wall_length),new Vector3(0, wall_height, 1* wall_length),new Vector3(1* wall_length*0.5f, wall_height,1* wall_length*0.5f+1* wall_length),new Vector3(1* wall_length*0.5f, 0,1* wall_length*0.5f+1* wall_length),
};
mesh.triangles = new int[]
{ 0, 1, 2,
0, 2, 3,
0+4, 1+4, 2+4,
0+4, 2+4, 3+4,
0+8, 1+8, 2+8,
0+8, 2+8, 3+8,
};
float wall_height2 = 1.0f;
float wall_length2 = 1.0f;
//这里的坐标一般都不会很大,最大不超过纹理本身的坐标范围(即0到1之间),所以转换的是把数据的范围经过缩放和平移,然后跟纹理能叠加在一起
//如果这里的坐标过大,就会出现纹理的repeat和变形,有时候repeat是对的,有时候是不行的
mesh.uv = new Vector2[] {
new Vector2(0, 0), new Vector2(0,wall_height2), new Vector2( -1* wall_length2,wall_height2), new Vector2(-1* wall_length2,0) ,
new Vector2(0, 0), new Vector2(0,wall_height2), new Vector2( -1* wall_length2,wall_height2), new Vector2(-1* wall_length2,0) ,
new Vector2(0, 0), new Vector2(0,wall_height2), new Vector2( -1* wall_length2,wall_height2), new Vector2(-1* wall_length2,0) ,
};*/
}
// Use this for initialization
void Start()
{
gameObject = GameObject.Find("Main Camera");
oldMousePosition = Input.mousePosition;
newMousePosition = Input.mousePosition;
//Application.targetFrameRate = 30;
// Cursor.visible = false;
simpleMesh = new GameObject();
// 定义对象名为 Start5
simpleMesh.name = "Start5";
simpleMesh.transform.position = new Vector3(14, 6, 13);
// 添加MeshFilter
simpleMesh.AddComponent<MeshFilter>();
// 添加MeshRenderer
simpleMesh.AddComponent<MeshRenderer>();
// 创建shader为Unlit/shader7的Material
//Material simpleMaterial = new Material(Shader.Find("Unlit/shader7"));
simpleMesh.GetComponent<MeshRenderer>().material = mater;
GameObject wallone = simpleMesh;
Mesh mesh = wallone.GetComponent<MeshFilter>().mesh;
mesh.Clear();
List<GISPoint> points = new List<GISPoint>();
points.Add(new GISPoint(0,0));
points.Add(new GISPoint(5,0));
points.Add(new GISPoint(5,5));
points.Add(new GISPoint(10,5));
points.Add(new GISPoint(10,0));
createWallByPoints(points,1.0f,mesh);
}
// Update is called once per frame
void Update()
{
float deltaTime = Time.deltaTime;
/*newMousePosition = Input.mousePosition;
if (newMousePosition != oldMousePosition)
{
float delta_speed = mousespeed * deltaTime;
transform.Rotate(Vector3.up, newMousePosition.x * delta_speed - oldMousePosition.x * delta_speed);
transform.Rotate(Vector3.right, -1 * (newMousePosition.y * delta_speed - oldMousePosition.y * delta_speed));
transform.eulerAngles = new Vector3(transform.eulerAngles.x, transform.eulerAngles.y, 0);
}
oldMousePosition = Input.mousePosition;*/
//Q 上
if (Input.GetKey(KeyCode.Q))
{
transform.position = new Vector3(transform.position.x, transform.position.y + speed * deltaTime, transform.position.z);
}
//E 下
if (Input.GetKey(KeyCode.E))
{
transform.position = new Vector3(transform.position.x, transform.position.y - speed * deltaTime, transform.position.z);
}
//w键前进
if (Input.GetKey(KeyCode.W))
{
this.gameObject.transform.Translate(new Vector3(0, 0, speed * deltaTime));
}
//s键后退
if (Input.GetKey(KeyCode.S))
{
this.gameObject.transform.Translate(new Vector3(0, 0, -speed * deltaTime));
}
//a键左
if (Input.GetKey(KeyCode.A))
{
this.gameObject.transform.Translate(new Vector3(-speed * deltaTime, 0, 0 * deltaTime));
}
//d键右
if (Input.GetKey(KeyCode.D))
{
this.gameObject.transform.Translate(new Vector3(speed * deltaTime, 0, 0 * deltaTime));
}
//左箭头
if (Input.GetKey(KeyCode.LeftArrow))
{
//transform.Rotate(Vector3.down * speed);
this.gameObject.transform.RotateAround(this.gameObject.transform.position, Vector3.down, 50 * Time.deltaTime);
}
//右箭头
if (Input.GetKey(KeyCode.RightArrow))
{
//transform.Rotate(Vector3.up * speed);
this.gameObject.transform.RotateAround(this.gameObject.transform.position, Vector3.up, 50 * Time.deltaTime);
}
/*
//上箭头
if (Input.GetKey(KeyCode.UpArrow))
{
//transform.Rotate(Vector3.left * speed);
this.gameObject.transform.RotateAround(this.gameObject.transform.position, Vector3.left, 30 * Time.deltaTime);
}
//下箭头
if (Input.GetKey(KeyCode.DownArrow))
{
//transform.Rotate(Vector3.right * speed);
this.gameObject.transform.RotateAround(this.gameObject.transform.position, Vector3.right, 30 * Time.deltaTime);
}*/
}
}
把这个C#脚本挂到主摄像机上就行