最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

Unity 隨機(jī)地形生成(Terrain 組件)

2023-02-26 20:45 作者:丿Ares丶-傾城  | 我要投稿

效果圖:


噪聲生成

創(chuàng)建 Noise.cs 腳本


using System.Collections;

using System.Collections.Generic;

using UnityEngine;


public static class Noise

{

? ? public static float[,] GenerateNoiseMap(int mapWidth, int mapHeight, int seed, float scale, int octaves, float persistance, float lacunarity, Vector2 offset)

? ? {

? ? ? ? float[,] noiseMap = new float[mapWidth, mapHeight];


? ? ? ? System.Random prng = new System.Random(seed);

? ? ? ? Vector2[] octavesOffset = new Vector2[octaves];

? ? ? ? for (int i = 0; i < octaves; i++)

? ? ? ? {

? ? ? ? ? ? float offsetX = prng.Next(-100000, 100000) + offset.x;

? ? ? ? ? ? float offsetY = prng.Next(-100000, 100000) + offset.y;

? ? ? ? ? ? octavesOffset[i] = new Vector2(offsetX, offsetY);

? ? ? ? }


? ? ? ? if (scale <= 0)

? ? ? ? {

? ? ? ? ? ? scale = 0.0001f;

? ? ? ? }


? ? ? ? float maxNoiseHeight = float.MinValue;

? ? ? ? float minNoiseHeight = float.MaxValue;


? ? ? ? for (int y = 0; y < mapHeight; y++)

? ? ? ? {

? ? ? ? ? ? for (int x = 0; x < mapWidth; x++)

? ? ? ? ? ? {


? ? ? ? ? ? ? ? float amplitude = 1;

? ? ? ? ? ? ? ? float frequency = 1;

? ? ? ? ? ? ? ? float noiseHeight = 0;


? ? ? ? ? ? ? ? for (int i = 0; i < octaves; i++)

? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? float sampleX = (x + offset.x) / scale * frequency + octavesOffset[i].x;

? ? ? ? ? ? ? ? ? ? float sampleY = (y + offset.y) / scale * frequency + octavesOffset[i].y;


? ? ? ? ? ? ? ? ? ? float perlinValue = Mathf.PerlinNoise(sampleX, sampleY) * 2 - 1;

? ? ? ? ? ? ? ? ? ? noiseHeight += perlinValue * amplitude;


? ? ? ? ? ? ? ? ? ? amplitude *= persistance;

? ? ? ? ? ? ? ? ? ? frequency *= lacunarity;

? ? ? ? ? ? ? ? }


? ? ? ? ? ? ? ? if (noiseHeight > maxNoiseHeight)

? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? maxNoiseHeight = noiseHeight;

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? else if (noiseHeight < minNoiseHeight)

? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? minNoiseHeight = noiseHeight;

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? noiseMap[x, y] = noiseHeight;

? ? ? ? ? ? }

? ? ? ? }


? ? ? ? for (int y = 0; y < mapHeight; y++)

? ? ? ? {

? ? ? ? ? ? for (int x = 0; x < mapWidth; x++)

? ? ? ? ? ? {

? ? ? ? ? ? ? ? noiseMap[x, y] = Mathf.InverseLerp(minNoiseHeight, maxNoiseHeight, noiseMap[x, y]);

? ? ? ? ? ? }

? ? ? ? }


? ? ? ? return noiseMap;

? ? }

}


地形顯示

創(chuàng)建 TerrainDisplay.cs 腳本 用于創(chuàng)建 Terrain 對(duì)象

terrainName:生成的游戲?qū)ο竺Q

terrainMaterial:生成的 Terrain 使用的材質(zhì)

using System.Collections;

using System.Collections.Generic;

using UnityEngine;


public class TerrainDisplay : MonoBehaviour

{

? ? // 地形名稱

? ? public string terrainName = "Terrain";


? ? // 地形材質(zhì)

? ? public Material terrainMaterial;


? ? /// <summary>

? ? /// 創(chuàng)建 Terrain

? ? /// </summary>

? ? public void CreateTerrain(TerrainData terrainData)

? ? {

? ? ? ? // 查找游戲?qū)ο?/p>

? ? ? ? GameObject terrainObj = GameObject.Find(this.terrainName);

? ? ? ? if (terrainObj == null)

? ? ? ? {

? ? ? ? ? ? // 創(chuàng)建游戲?qū)ο?/p>

? ? ? ? ? ? terrainObj = new GameObject(this.terrainName);

? ? ? ? ? ? terrainObj.name = this.terrainName;

? ? ? ? ? ? // 添加地形組件

? ? ? ? ? ? terrainObj.AddComponent<Terrain>();

? ? ? ? ? ? // 添加地形碰撞體組件

? ? ? ? ? ? terrainObj.AddComponent<TerrainCollider>();

? ? ? ? }

? ? ? ? Terrain terrain = terrainObj.GetComponent<Terrain>();

? ? ? ? TerrainCollider terrainCollider = terrainObj.GetComponent<TerrainCollider>();

? ? ? ? terrain.terrainData = terrainData;

? ? ? ? terrainCollider.terrainData = terrainData;

terrain.materialTemplate = terrainMaterial;

? ? }

}

CreateTerrain 的參數(shù)傳入的是 TerrainData 類型 而上面生成噪聲圖是 ?float[,] 二維數(shù)組

所以我們還需要對(duì)數(shù)據(jù)進(jìn)行處理才能使用

地形生成

創(chuàng)建 TerrainGenerator.cs 腳本

using System.Collections;

using System.Collections.Generic;

using UnityEngine;


public class TerrainGenerator : MonoBehaviour

{


? ? public static TerrainData CreateTerrainData(float[,] heightMap, float terrainHeight, int heightmapResolution)

? ? {

? ? ? ? TerrainData terrainData = new TerrainData();


? ? ? ? int width = heightMap.GetLength(0);

? ? ? ? int height = heightMap.GetLength(1);


? ? ? ? terrainData.heightmapResolution = heightmapResolution;

terrainData.alphamapResolution = heightmapResolution - 1;


? ? ? ? terrainData.size = new Vector3(width, terrainHeight, height);

? ? ? ? terrainData.SetHeights(0, 0, heightMap);


? ? ? ? return terrainData;

? ? }


}

接下來我們調(diào)用上面兩個(gè)方法來生成地形

修改 TerrainGenerator.cs

using System.Collections;

using System.Collections.Generic;

using UnityEngine;


public class TerrainGenerator : MonoBehaviour

{

? ? // 高度圖分辨率

? ? public enum HeightmapResolution

? ? {

? ? ? ? h33 = 33,

? ? ? ? h65 = 65,

? ? ? ? h129 = 129,

? ? ? ? h257 = 257,

? ? ? ? h513 = 513,

? ? ? ? h1025 = 1025,

? ? ? ? h2049 = 2049,

? ? ? ? h4097 = 4097,


? ? }

? ? public HeightmapResolution heightmapResolution = HeightmapResolution.h33;


? ? // 縮放

? ? public float scale;


? ? // 抵消

? ? public int octaves;

? ? // 持續(xù)

? ? [Range(0, 1)]

? ? public float persistance;

? ? // 空隙

? ? public float lacunarity;

? ? // 種子

? ? public int seed;

? ? // 偏移

? ? public Vector2 offset;

? ? // 自動(dòng)更新

? ? public bool autoUpdate;

? ? // 地形高度

? ? public float terrainHeight = 1;


? ? public void GenerateMap()

? ? {

? ? ? ? TerrainDisplay display = FindObjectOfType<TerrainDisplay>();


? ? ? ? float[,] noiseMap = Noise.GenerateNoiseMap((int)heightmapResolution,

? ? ? ? ? ? (int)heightmapResolution, seed, scale, octaves, persistance, lacunarity, offset);


? ? ? ? display.CreateTerrain(CreateTerrainData(noiseMap, terrainHeight, (int)heightmapResolution));

? ? }



? ? public static TerrainData CreateTerrainData(float[,] heightMap, float terrainHeight, int heightmapResolution)

? ? {

? ? ? ? TerrainData terrainData = new TerrainData();


? ? ? ? int width = heightMap.GetLength(0);

? ? ? ? int height = heightMap.GetLength(1);


? ? ? ? terrainData.heightmapResolution = heightmapResolution;

terrainData.alphamapResolution = heightmapResolution - 1;


? ? ? ? terrainData.size = new Vector3(width, terrainHeight, height);

? ? ? ? terrainData.SetHeights(0, 0, heightMap);


? ? ? ? return terrainData;

? ? }



}

現(xiàn)在地形生成部分就完成了

接下來我們還需要實(shí)現(xiàn)一個(gè) 點(diǎn)擊按鈕 生成地形的功能

創(chuàng)建 TerrainEditor.cs 腳本


using System.Collections;

using System.Collections.Generic;

using UnityEditor;

using UnityEngine;


[CustomEditor(typeof (TerrainGenerator))]

public class TerrainEditor : Editor

{

? ? public override void OnInspectorGUI()

? ? {


? ? ? ? TerrainGenerator terrainGenerator = (TerrainGenerator)target;


? ? ? ? if (DrawDefaultInspector())

? ? ? ? {

? ? ? ? ? ? if (terrainGenerator.autoUpdate)

? ? ? ? ? ? {

? ? ? ? ? ? ? ? terrainGenerator.GenerateMap();

? ? ? ? ? ? }

? ? ? ? }


? ? ? ? if (GUILayout.Button("Generate"))

? ? ? ? {

? ? ? ? ? ? terrainGenerator.GenerateMap();

? ? ? ? }


? ? }

}



地形生成測(cè)試

添加 空游戲?qū)ο竺麨?Map Generator


將剛才編寫的這兩個(gè)腳本添加到對(duì)象上


調(diào)整面板參數(shù)


點(diǎn)擊 Generate 按鈕即可生成地形


紋理繪制

想要在 Terrain 上繪制紋理需要在 Terrain 中添加 Layer

在繪制紋理前 我們先實(shí)現(xiàn) 添加 Layer 的功能

TerrainDisplay.cs 添加代碼

[System.Serializable]

public struct TerrainLayerInfo

{

? ? public TerrainLayer terrainLayer;

? ? [Range(0, 1)]

? ? public float layerMaxHeight;

? ? [Range(0, 1)]

? ? public float layerMinHeight;

}

添加到最后即可


TerrainDisplay.cs 添加字段

public TerrainLayerInfo[] terrainLayerInfos;


TerrainDisplay.cs 中添加方法


public void TerrainLayerGenerator(Terrain terrain)

{

? ? TerrainLayer[] terrainLayers = new TerrainLayer[terrainLayerInfos.Length];

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

? ? {

? ? ? ? terrainLayers[i] = terrainLayerInfos[i].terrainLayer;

? ? }

? ? terrain.terrainData.terrainLayers = terrainLayers;

}



在腳本中添加 Layer 并點(diǎn)擊 Generate 測(cè)試,可以看見地形已經(jīng)繪制上紋理了


接下來實(shí)現(xiàn)基于高度繪制不同的紋理的功能

TerrainDisplay.cs 添加代碼


public void TerrainLayerAlphaGenerator(Terrain terrain, float[,,] terrainAlphamp, float heightmapResolution)

{

? ? float[,] terrainHeightMap = terrain.terrainData.GetHeights(0, 0, (int)heightmapResolution, (int)heightmapResolution);


? ? for (int layerIndex = 0; layerIndex < terrainAlphamp.GetLength(2); layerIndex++)

? ? {

? ? ? ? for (int y = 0; y < terrainAlphamp.GetLength(1); y++)

? ? ? ? {

? ? ? ? ? ? for (int x = 0; x < terrainAlphamp.GetLength(0); x++)

? ? ? ? ? ? {

? ? ? ? ? ? ? ? if (terrainHeightMap[x, y] <= terrainLayerInfos[layerIndex].layerMaxHeight &&

? ? ? ? ? ? ? ? ? ? terrainHeightMap[x, y] >= terrainLayerInfos[layerIndex].layerMinHeight)

? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? terrainAlphamp[x, y, layerIndex] = 1;

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? else

? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? terrainAlphamp[x, y, layerIndex] = 0;

? ? ? ? ? ? ? ? }

? ? ? ? ? ? }

? ? ? ? }

? ? }


? ? terrain.terrainData.SetAlphamaps(0, 0, terrainAlphamp);

}



CreateTerrain 方法中添加


float[,,] alphamaps = terrain

? ? ? ? ? ? ? ? .terrainData

? ? ? ? ? ? ? ? .GetAlphamaps(0, 0, terrain.terrainData.alphamapWidth, terrain.terrainData.alphamapHeight);

? ? ? ? TerrainLayerAlphaGenerator(terrain,alphamaps,terrainData.heightmapResolution);



紋理繪制測(cè)試

添加 Layer 并點(diǎn)擊 Generate 紋理成功繪制


參考視頻:https://www.bilibili.com/video/BV1sJ411e7nt/?share_source=copy_web&;vd_source=3ff483a8930d34f7fca4f473c89b4c15


Unity 隨機(jī)地形生成(Terrain 組件)的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
会理县| 亚东县| 集贤县| 鄂伦春自治旗| 改则县| 靖远县| 抚松县| 孝义市| 山阳县| 宜兴市| 楚雄市| 宜昌市| 肇庆市| 凤山县| 津市市| 田东县| 宾阳县| 宁远县| 卢氏县| 舞钢市| 昌宁县| 义乌市| 西丰县| 东兴市| 凤凰县| 松溪县| 土默特右旗| 鹤山市| 深泽县| 昂仁县| 玛纳斯县| 辽宁省| 巩留县| 比如县| 剑阁县| 安仁县| 盈江县| 宜城市| 顺昌县| 南昌市| 靖远县|