public static Vector3 SphericalToCartesian(float longitude, float latitude, float radius)
{
float x = radius * Mathf.Sin(latitude) * Mathf.Cos(longitude);
float y = radius * Mathf.Cos(latitude) * Mathf.Sin(longitude);
return new Vector3(x, y);
}
latitude += Input.GetAxis("Mouse X") * xSpeed;
longitude -= Input.GetAxis("Mouse Y") * ySpeed;
transform.RotateAround(target.position, transform.up, latitude);
transform.RotateAround(target.position, transform.right, longitude);
longitude = 0;
latitude = 0;
distance = Vector3.Distance(transform.position, target.position);
distance = ZoomLimit(distance, zoomMin, zoomMax);
relativePosition = SphericalToCartesian(longitude, latitude, distance);
position = relativePosition + target.position;
transform.position = Vector3.Lerp(transform.position, position, Time.deltaTime);
void Update() {
viewerPosition = new Vector2 (viewer.position.x, viewer.position.z) / mapGenerator.terrainData.uniformScale;
if ((viewerPositionOld - viewerPosition).sqrMagnitude > sqrViewerMoveThresholdForChunkUpdate) {
viewerPositionOld = viewerPosition;
UpdateVisibleChunks ();
}
}
void UpdateVisibleChunks() {
for (int i = 0; i < terrainChunksVisibleLastUpdate.Count; i++) {
terrainChunksVisibleLastUpdate [i].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 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 [i].visibleDstThreshold) {
lodIndex = i + 1;
} else {
break;
}
}
if (lodIndex != previousLODIndex) {
LODMesh lodMesh = lodMeshes [lodIndex];
if (lodMesh.hasMesh) {
previousLODIndex = lodIndex;
meshFilter.mesh = lodMesh.mesh;
} else if (!lodMesh.hasRequestedMesh) {
lodMesh.RequestMesh (mapData);
}
}
if (lodIndex == 0) {
if (collisionLODMesh.hasMesh) {
meshCollider.sharedMesh = collisionLODMesh.mesh;
} else if (!collisionLODMesh.hasRequestedMesh) {
collisionLODMesh.RequestMesh (mapData);
}
}
terrainChunksVisibleLastUpdate.Add (this);
}
SetVisible (visible);
}
}