生成地图(CreatTerrtin)

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class CreatTerrtin : MonoBehaviour
{
Action<Texture2D> action;

public void SetAction(Action<Texture2D> action)
{
this.action = action;
}
public Texture cao;
public Texture tu;
public float hh = 5;
public float line = 2;//水平线

public Material waterMat;//水的材质球
public Material terrainMat;//水面配套的材质球

//public Image map;//小地图
public Texture2D texture;//纹理

int w = 128;//宽
int h = 128;//高

int wNum;//宽分块
int hNum;//高分块

public Color high = Color.white;
public Color low = Color.black;
public Color waterCol = Color.blue;
// Start is called before the first frame update
void Start()
{
//wNum = texture.width / w;
//hNum = texture.height / h;
//顶点个数限制 最多 65000个
//纹理尽量取2的次方 方便优化
wNum = 3;
hNum = 3;
//创建一个图片
texture = new Texture2D(wNum * w, hNum * h);
//补缝
int w2 = w + 2;
int h2 = h + 2;
for (int i = 0; i < wNum; i++)
{
for(int j = 0; j < hNum; j++)
{
GameObject terr = new GameObject();
terr.transform.parent = transform;
//顶点助手
VertexHelper vh = new VertexHelper();
for (int x = 0; x < w2; x++)
{
for (int z = 0; z < h2; z++)
{
//Color color = texture.GetPixel(w * i + x, h * j + z);
//float y = color.grayscale * 5;
//柏林噪声算法 ,传入两个坐标返回一个0-1的值(传入两个相同的值,返回结果一定相同)
float y = Mathf.PerlinNoise((i * w + x) * 0.02f, (j * h + z) * 0.02f);
//计算uv坐标
float uvx = (float)(w * j + x) / (float)(texture.width - 1);
float uvy = (float)(h * j + x) / (float)(texture.height - 1);

vh.AddVert(new Vector3(w * i + x- texture.width/2, y* hh, h * j + z-texture.height/2 ), Color.white, new Vector2(uvx, uvy));

if(x<w2-1 && z<h2-1)
{
vh.AddTriangle(x * h2 + z, x * h2 +z+ 1, (x + 1) * h2 + z + 1);
vh.AddTriangle(x * h2 + z, (x+1) * h2 +z+ 1, (x + 1) * h2 + z);
}
//设置像素颜色
if (y * hh < line)
{
//低于水平线绘制水面颜色
texture.SetPixel(i * w + x, j * h + z, Color.Lerp(waterCol,Color.Lerp(low,high,y),y*hh/line));
}
else
{
//柏林噪声算法正好返回0-1的值,使用该值作为颜色现行差值
texture.SetPixel(i * w + x, j * h + z, Color.Lerp(low, high, y));
}

//创建树 树不能在水中 要高于水平面
if (UnityEngine.Random.Range(0, 100) >= 99 && y * hh > line)
{
GameObject cube = Instantiate(Resources.Load<GameObject>("Terrain/ter_" + UnityEngine.Random.Range(0, 7)));
cube.transform.parent = transform;
cube.transform.localPosition = new Vector3(w * i + x - texture.width / 2, y * hh, h * j + z - texture.height / 2);
}
}
}
Mesh mesh = new Mesh();
vh.FillMesh(mesh);

terr.AddComponent<MeshFilter>().mesh = mesh;

//设置自定义shader
Material material = new Material(Shader.Find("Unlit/Terrain"));
material.SetTexture("_CaoTex", cao);
material.SetTexture("_TuTex", tu);
material.SetFloat("_H", hh);

List<Material> materials = new List<Material>();
materials.Add(material);
materials.Add(terrainMat);

terr.AddComponent<MeshRenderer>().materials = materials.ToArray();

terr.AddComponent<MeshCollider>().sharedMesh = mesh;

//创建水面
GameObject water = GameObject.CreatePrimitive(PrimitiveType.Plane);

water.transform.parent = terr.transform;
water.transform.localScale = new Vector3((float)w / 10f, 1, (float)h / 10f);
water.transform.position = new Vector3(w * i - texture.width / 2+65, line, h * j - texture.height / 2+65);
water.GetComponent<MeshRenderer>().material = waterMat;
Destroy(water.GetComponent<MeshCollider>());//去掉水的网格碰撞
}
}
//保存纹理修改
texture.Apply();
//在Apply之前纹理是没值的,给image賦值一定要在这之后
//注意:不要直接修改image的材质,否则会修改掉所有image的默认材质
//错误示例: map. material. mainTexture = texture;

if (action != null )
{
action(texture);
}
//Material material1 = new Material(Shader.Find("UI/Default"));
//material1.mainTexture = texture;
//map.material = material1;
//静态批处理
StaticBatchingUtility.Combine(gameObject);

}

// Update is called once per frame
void Update()
{

}
}

posted @ 2022-12-22 14:00  old_Host  阅读(56)  评论(0编辑  收藏  举报