Hey guys, im trying to figure out a way in VS Code and in Unity3d to add layers to objects such as my terrain chunks. This is a very urgent need of help and I only started about 3 - 4 months ago I think.
Ill give you my script and i hope some people can help me…
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class Chunk : MonoBehaviour {
const float scale = 5f;
const float viewerMoveThresholdForChunkUpdate = 25f;
const float sqrViewerMoveThresholdForChunkUpdate = viewerMoveThresholdForChunkUpdate * viewerMoveThresholdForChunkUpdate;
public LODInfo[] detailLevels;
public static float maxViewDst;
public Transform viewer;
public Material mapMaterial;
public static Vector2 viewerPosition;
Vector2 viewerPositionOld;
static MapGenerator mapGenerator;
int chunkSize;
int chunksVisibleInViewDst;
Dictionary<Vector2, TerrainChunk> terrainChunkDictionary = new Dictionary<Vector2, TerrainChunk>();
static List<TerrainChunk> terrainChunksVisibleLastUpdate = new List<TerrainChunk>();
void Start() {
mapGenerator = FindObjectOfType<MapGenerator> ();
maxViewDst = detailLevels [detailLevels.Length - 1].visibleDstThreshold;
chunkSize = MapGenerator.mapChunkSize - 1;
chunksVisibleInViewDst = Mathf.RoundToInt(maxViewDst / chunkSize);
UpdateVisibleChunks ();
}
void Update() {
viewerPosition = new Vector2 (viewer.position.x, viewer.position.z) / scale;
if ((viewerPositionOld - viewerPosition).sqrMagnitude > sqrViewerMoveThresholdForChunkUpdate) {
viewerPositionOld = viewerPosition;
UpdateVisibleChunks ();
}
}
void UpdateVisibleChunks() {
for (int i = 0; i < terrainChunksVisibleLastUpdate.Count; i++) {
terrainChunksVisibleLastUpdate .SetVisible (false);
}
terrainChunksVisibleLastUpdate.Clear ();
int currentChunkCoordX = Mathf.RoundToInt (viewerPosition.x / chunkSize);
int currentChunkCoordY = Mathf.RoundToInt (viewerPosition.y / chunkSize);
for (int yOffset = -chunksVisibleInViewDst; yOffset <= chunksVisibleInViewDst; yOffset++) {
for (int xOffset = -chunksVisibleInViewDst; xOffset <= chunksVisibleInViewDst; xOffset++) {
Vector2 viewedChunkCoord = new Vector2 (currentChunkCoordX + xOffset, currentChunkCoordY + yOffset);
if (terrainChunkDictionary.ContainsKey (viewedChunkCoord)) {
terrainChunkDictionary [viewedChunkCoord].UpdateTerrainChunk ();
} else {
terrainChunkDictionary.Add (viewedChunkCoord, new TerrainChunk (viewedChunkCoord, chunkSize, detailLevels, transform, mapMaterial));
}
}
}
}
public class TerrainChunk {
GameObject meshObject;
Vector2 position;
Bounds bounds;
MeshRenderer meshRenderer;
MeshFilter meshFilter;
MeshCollider colliderMesh;
LODInfo[] detailLevels;
LODMesh[] lodMeshes;
MapData mapData;
bool mapDataReceived;
int previousLODIndex = -1;
public TerrainChunk(Vector2 coord, int size, LODInfo[] detailLevels, Transform parent, Material material) {
this.detailLevels = detailLevels;
position = coord * size;
bounds = new Bounds(position,Vector2.one * size);
Vector3 positionV3 = new Vector3(position.x,0,position.y);
meshObject = new GameObject("Terrain Chunk");
meshRenderer = meshObject.AddComponent<MeshRenderer>();
meshFilter = meshObject.AddComponent<MeshFilter>();
colliderMesh = meshObject.AddComponent<MeshCollider>();
meshRenderer.material = material;
meshObject.transform.position = positionV3 * scale;
meshObject.transform.parent = parent;
meshObject.transform.localScale = Vector3.one * scale;
SetVisible(false);
lodMeshes = new LODMesh[detailLevels.Length];
for (int i = 0; i < detailLevels.Length; i++) {
lodMeshes = new LODMesh(detailLevels.lod, UpdateTerrainChunk);
}
mapGenerator.RequestMapData(position,OnMapDataReceived);
}
void OnMapDataReceived(MapData mapData) {
this.mapData = mapData;
mapDataReceived = true;
Texture2D texture = TextureGenerator.TextureFromColourMap (mapData.colourMap, MapGenerator.mapChunkSize, MapGenerator.mapChunkSize);
meshRenderer.material.mainTexture = texture;
UpdateTerrainChunk ();
}
public void UpdateTerrainChunk() {
if (mapDataReceived) {
float viewerDstFromNearestEdge = Mathf.Sqrt (bounds.SqrDistance (viewerPosition));
bool visible = viewerDstFromNearestEdge <= maxViewDst;
if (visible) {
int lodIndex = 0;
for (int i = 0; i < detailLevels.Length - 1; i++) {
if (viewerDstFromNearestEdge > detailLevels .visibleDstThreshold) {
lodIndex = i + 1;
} else {
break;
}
}
if (lodIndex != previousLODIndex) {
LODMesh lodMesh = lodMeshes [lodIndex];
if (lodMesh.hasMesh) {
previousLODIndex = lodIndex;
meshFilter.mesh = lodMesh.mesh;
colliderMesh.sharedMesh = lodMesh.mesh;
} else if (!lodMesh.hasRequestedMesh) {
lodMesh.RequestMesh (mapData);
}
}
terrainChunksVisibleLastUpdate.Add (this);
}
SetVisible (visible);
}
}
public void SetVisible(bool visible) {
meshObject.SetActive (visible);
}
public bool IsVisible() {
return meshObject.activeSelf;
}
}
class LODMesh {
public Mesh mesh;
public bool hasRequestedMesh;
public bool hasMesh;
int lod;
System.Action updateCallback;
public LODMesh(int lod, System.Action updateCallback) {
this.lod = lod;
this.updateCallback = updateCallback;
}
void OnMeshDataReceived(MeshData meshData) {
mesh = meshData.CreateMesh ();
hasMesh = true;
updateCallback ();
}
public void RequestMesh(MapData mapData) {
hasRequestedMesh = true;
mapGenerator.RequestMeshData (mapData, lod, OnMeshDataReceived);
}
}
[System.Serializable]
public struct LODInfo {
public int lod;
public float visibleDstThreshold;
}
}