740 lines
24 KiB
C#
740 lines
24 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
|
|
namespace ARLocation
|
|
{
|
|
public class WorldVoxelController : MonoBehaviour
|
|
{
|
|
// Start is called before the first frame update
|
|
public PrefabDatabase PrefabDatabase;
|
|
|
|
[System.Serializable]
|
|
class Voxel
|
|
{
|
|
public string PrefabId;
|
|
public int i, j, k;
|
|
|
|
[System.NonSerialized]
|
|
public GameObject Instance;
|
|
}
|
|
|
|
struct VoxelHit
|
|
{
|
|
public Voxel Voxel;
|
|
public Vector3 Normal;
|
|
public Vector3 WorldNorma;
|
|
}
|
|
|
|
[System.Serializable]
|
|
class WorldChunk
|
|
{
|
|
public List<Voxel> Voxels = new List<Voxel>();
|
|
public Location ChunkLocation;
|
|
public float ChunkRotation;
|
|
public bool HasLocation;
|
|
public int Length;
|
|
|
|
[System.NonSerialized]
|
|
public Vector3 Origin;
|
|
|
|
[System.NonSerialized]
|
|
public GameObject ChunkContainer;
|
|
|
|
[System.NonSerialized]
|
|
public Bounds Bounds;
|
|
|
|
//[System.NonSerialized]
|
|
//public GameObject ChunkPlaneInstance;
|
|
|
|
[System.NonSerialized]
|
|
public bool IsFresh;
|
|
}
|
|
|
|
[System.Serializable]
|
|
class World
|
|
{
|
|
public List<WorldChunk> Chunks = new List<WorldChunk>();
|
|
}
|
|
|
|
[System.Serializable]
|
|
public class ElementsSettingsData
|
|
{
|
|
public Button ClearWorldBtn;
|
|
public Button PickAxeBtn;
|
|
public Button BrickBtn;
|
|
public Button StoneBtn;
|
|
public Button GoldBtn;
|
|
public Text DebugText;
|
|
public AudioClip Create;
|
|
public AudioClip Destroy;
|
|
public ParticleSystem BrickParticle;
|
|
public GameObject IndicatorPlane;
|
|
public GameObject ChunkPlanePrefab;
|
|
}
|
|
|
|
public enum Tools
|
|
{
|
|
PickAxe,
|
|
Block
|
|
}
|
|
|
|
public enum Blocks
|
|
{
|
|
Brick,
|
|
Stone,
|
|
Gold
|
|
}
|
|
|
|
[System.Serializable]
|
|
public class RaycastMarginSettings
|
|
{
|
|
public float Top;
|
|
public float Bottom;
|
|
public float Left;
|
|
public float Right;
|
|
|
|
public bool IsInside(Vector2 v)
|
|
{
|
|
if (v.x < Left || v.x > (1 - Right)) return false;
|
|
if (v.y < Bottom || v.y > (1 - Top)) return false;
|
|
|
|
return true;
|
|
}
|
|
}
|
|
|
|
[System.Serializable]
|
|
public class SettingsData
|
|
{
|
|
public float CunkScale = 1.0f;
|
|
public Color ButtonNormalColor;
|
|
public Color ButtonSelectedColor;
|
|
}
|
|
|
|
class StateData
|
|
{
|
|
public ApplicationState AppState;
|
|
public GameState GameState;
|
|
public Blocks CurrentBlock;
|
|
public WorldChunk CurrentChunk;
|
|
public Location CurrentLocation;
|
|
}
|
|
|
|
public ElementsSettingsData Elements;
|
|
public RaycastMarginSettings RaycastMargins;
|
|
public SettingsData Settings;
|
|
|
|
private World world = new World();
|
|
private readonly StateData state = new StateData();
|
|
|
|
private void LogText(string str)
|
|
{
|
|
Debug.Log(str);
|
|
Elements.DebugText.text = str;
|
|
}
|
|
|
|
enum ApplicationState
|
|
{
|
|
Initializing,
|
|
Running
|
|
};
|
|
|
|
enum GameState
|
|
{
|
|
Destroy,
|
|
Build
|
|
};
|
|
|
|
private IEnumerator StartWorld()
|
|
{
|
|
LogText($"Loading previous session file...");
|
|
yield return new WaitForSeconds(0.5f);
|
|
|
|
if (RestoreWorldFromLocalStorage())
|
|
{
|
|
LogText($"Restored world with {world.Chunks.Count} chunks");
|
|
yield return new WaitForSeconds(0.5f);
|
|
|
|
if (world.Chunks.Count > 0)
|
|
{
|
|
double distance;
|
|
var closestChunk = FindClosestChunk(state.CurrentLocation, out distance, 1000.0);
|
|
if (closestChunk != null)
|
|
{
|
|
LogText($"Found closes chunk at {closestChunk.ChunkLocation}, d = {distance}");
|
|
yield return new WaitForSeconds(0.5f);
|
|
|
|
SetCurrentChunk(closestChunk);
|
|
LogText($"Current Chunk Set");
|
|
yield return new WaitForSeconds(0.5f);
|
|
|
|
yield break;
|
|
}
|
|
else
|
|
{
|
|
LogText($"No chunk nearby!");
|
|
yield return new WaitForSeconds(0.5f);
|
|
|
|
var i = 0;
|
|
foreach (var c in world.Chunks)
|
|
{
|
|
var d = Location.HorizontalDistance(state.CurrentLocation, c.ChunkLocation);
|
|
LogText($"Chunk {i} at {c.ChunkLocation}, d = {d}");
|
|
yield return new WaitForSeconds(0.5f);
|
|
i++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
LogText($"No world to restore!");
|
|
yield return new WaitForSeconds(0.5f);
|
|
}
|
|
|
|
LogText("Creating new chunk...");
|
|
yield return new WaitForSeconds(0.5f);
|
|
|
|
var chunk = CreateTestChunk();
|
|
chunk.IsFresh = true;
|
|
world.Chunks.Add(chunk);
|
|
SetCurrentChunk(chunk);
|
|
UpdateChunkLocation(chunk);
|
|
|
|
LogText("Added new chunk!");
|
|
yield return new WaitForSeconds(0.5f);
|
|
}
|
|
|
|
|
|
private IEnumerator Start()
|
|
{
|
|
Utils.Misc.HideGameObject(Elements.IndicatorPlane);
|
|
ARLocationProvider.Instance.OnLocationUpdated.AddListener(OnLocationUpdatedListener);
|
|
ChooseBrick();
|
|
|
|
LogText("Starting...");
|
|
LogText("Waiting for location...");
|
|
yield return new WaitForSeconds(0.5f);
|
|
|
|
yield return StartCoroutine(WaitForLocationServices());
|
|
state.CurrentLocation = ARLocationProvider.Instance.CurrentLocation.ToLocation();
|
|
LogText($"Location enabled: {state.CurrentLocation}");
|
|
yield return new WaitForSeconds(0.5f);
|
|
|
|
yield return StartCoroutine(StartWorld());
|
|
|
|
LogText($"Starting UI Listeners...");
|
|
yield return new WaitForSeconds(0.5f);
|
|
InitUiListeners();
|
|
|
|
LogText($"Setting app running...");
|
|
yield return new WaitForSeconds(0.5f);
|
|
state.AppState = ApplicationState.Running;
|
|
|
|
LogText($"App is running!");
|
|
}
|
|
|
|
void SetCurrentChunk(WorldChunk chunk)
|
|
{
|
|
if ((state.CurrentChunk != null) && (state.CurrentChunk.ChunkContainer != null)) Destroy(state.CurrentChunk.ChunkContainer);
|
|
|
|
state.CurrentChunk = chunk;
|
|
|
|
if (chunk.ChunkContainer == null)
|
|
{
|
|
BuildChunk(chunk);
|
|
}
|
|
}
|
|
|
|
void AddVoxelToChunk(WorldChunk c, string PrefabId, int i, int j, int k)
|
|
{
|
|
Voxel v = new Voxel { PrefabId = PrefabId, i = i, j = j, k = k };
|
|
v.Instance = Instantiate(PrefabDatabase.GetEntryById(PrefabId), c.ChunkContainer.transform);
|
|
v.Instance.transform.localPosition = new Vector3(v.i, v.j, v.k);
|
|
c.Voxels.Add(v);
|
|
}
|
|
|
|
WorldChunk CreateDefaultChunk()
|
|
{
|
|
return new WorldChunk { Origin = new Vector3(0, -1.4f, 4), Length = 100 };
|
|
}
|
|
|
|
WorldChunk CreateTestChunk()
|
|
{
|
|
WorldChunk c = new WorldChunk
|
|
{
|
|
Voxels = new List<Voxel>
|
|
{
|
|
new Voxel
|
|
{
|
|
PrefabId = "Brick",
|
|
Instance = null,
|
|
i = 0, j = 0, k = 0
|
|
}
|
|
},
|
|
Origin = new Vector3(0, -1.4f, 4),
|
|
Length = 100
|
|
};
|
|
|
|
for (int i = 1; i < 10; i++)
|
|
{
|
|
c.Voxels.Add(new Voxel { PrefabId = "Brick", i = i, j = 0, k = 0 });
|
|
}
|
|
|
|
for (int i = 1; i < 10; i++)
|
|
{
|
|
c.Voxels.Add(new Voxel { PrefabId = "Brick", i = i, j = 0, k = 9 });
|
|
}
|
|
|
|
for (int i = 1; i < 10; i++)
|
|
{
|
|
c.Voxels.Add(new Voxel { PrefabId = "Brick", i = 0, j = 0, k = i });
|
|
}
|
|
|
|
for (int i = 1; i < 10; i++)
|
|
{
|
|
c.Voxels.Add(new Voxel { PrefabId = "Brick", i = 9, j = 0, k = i });
|
|
}
|
|
|
|
return c;
|
|
}
|
|
|
|
IEnumerator WaitForLocationServices()
|
|
{
|
|
while (!ARLocationProvider.Instance.IsEnabled)
|
|
{
|
|
yield return new WaitForSeconds(0.1f);
|
|
}
|
|
}
|
|
|
|
bool InputIsDown(out Vector2 pos)
|
|
{
|
|
if (Application.isEditor)
|
|
{
|
|
pos = Input.mousePosition;
|
|
return Input.GetMouseButtonDown(0) && RaycastMargins.IsInside(pos / new Vector2(Screen.width, Screen.height));
|
|
}
|
|
|
|
if (Input.touchCount == 1 && Input.touches[0].phase == TouchPhase.Began)
|
|
{
|
|
pos = Input.touches[0].position;
|
|
return RaycastMargins.IsInside(pos / new Vector2(Screen.width, Screen.height));
|
|
}
|
|
|
|
pos = new Vector3();
|
|
return false;
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
if (state.AppState == ApplicationState.Initializing) return;
|
|
|
|
if (state.CurrentChunk == null)
|
|
{
|
|
FindClosestChunkOrCreateNew(state.CurrentLocation);
|
|
return;
|
|
}
|
|
|
|
Ray ray = Camera.main.ViewportPointToRay(new Vector3(0.5f, 0.5f, 0));
|
|
VoxelHit hit;
|
|
if (RaycastChunk(ray, state.CurrentChunk, out hit))
|
|
{
|
|
Utils.Misc.ShowGameObject(Elements.IndicatorPlane);
|
|
var t = Elements.IndicatorPlane.transform;
|
|
t.SetParent(state.CurrentChunk.ChunkContainer.transform);
|
|
t.transform.localScale = new Vector3(0.1f, 0.1f, 0.1f);
|
|
t.transform.localEulerAngles = new Vector3(0, 0, 0);
|
|
t.transform.localPosition = new Vector3(hit.Voxel.i + Mathf.FloorToInt(hit.Normal.x) * 0.505f, hit.Voxel.j + Mathf.FloorToInt(hit.Normal.y) * 0.505f, hit.Voxel.k + Mathf.FloorToInt(hit.Normal.z) * 0.505f);
|
|
//LogText("" + hit.Normal);
|
|
var Normal = hit.Normal;
|
|
|
|
if (Mathf.Abs(Normal.x) < 0.0001f && Mathf.Abs(Normal.y) < 0.0001f)
|
|
{
|
|
float sign = Normal.z < 0 ? -1.0f : 1.0f;
|
|
Elements.IndicatorPlane.transform.localEulerAngles = new Vector3(sign * 90.0f, 0, 0);
|
|
}
|
|
else if (Mathf.Abs(Normal.z) < 0.0001f && Mathf.Abs(Normal.y) < 0.0001f)
|
|
{
|
|
float sign = Normal.x < 0 ? 1.0f : -1.0f;
|
|
Elements.IndicatorPlane.transform.localEulerAngles = new Vector3(0, 0, sign * 90.0f);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Utils.Misc.HideGameObject(Elements.IndicatorPlane);
|
|
return;
|
|
}
|
|
|
|
Vector2 touchPos;
|
|
bool isDown = InputIsDown(out touchPos);
|
|
|
|
switch (state.GameState)
|
|
{
|
|
case GameState.Destroy:
|
|
{
|
|
if (isDown && hit.Voxel.Instance != null)
|
|
{
|
|
var i = Instantiate(Elements.BrickParticle);
|
|
i.transform.position = hit.Voxel.Instance.transform.position;
|
|
i.GetComponent<ParticleSystemRenderer>().material = hit.Voxel.Instance.GetComponent<MeshRenderer>().material;
|
|
i.Play();
|
|
|
|
state.CurrentChunk.Voxels.Remove(hit.Voxel);
|
|
Destroy(hit.Voxel.Instance);
|
|
|
|
|
|
var a = Camera.main.GetComponent<AudioSource>();
|
|
if (a)
|
|
{
|
|
a.clip = Elements.Destroy;
|
|
a.Play();
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case GameState.Build:
|
|
{
|
|
if (isDown)
|
|
{
|
|
AddVoxelToChunk(state.CurrentChunk, GetMeshIdForBlock(state.CurrentBlock), hit.Voxel.i + Mathf.FloorToInt(hit.Normal.x), hit.Voxel.j + Mathf.FloorToInt(hit.Normal.y), hit.Voxel.k + Mathf.FloorToInt(hit.Normal.z));
|
|
var a = Camera.main.GetComponent<AudioSource>();
|
|
if (a)
|
|
{
|
|
a.clip = Elements.Create;
|
|
a.Play();
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
bool RaycastChunk(Ray ray, WorldChunk chunk, out VoxelHit hit)
|
|
{
|
|
//if (!chunk.Bounds.IntersectRay(ray)) {
|
|
// hit = new VoxelHit();
|
|
// return false;
|
|
//}
|
|
|
|
VoxelHit currentHit = new VoxelHit();
|
|
float currentDistance = 0;
|
|
bool hasHit = false;
|
|
foreach (var v in chunk.Voxels)
|
|
{
|
|
if (v.Instance)
|
|
{
|
|
var collider = v.Instance.GetComponent<BoxCollider>();
|
|
|
|
Debug.Assert(collider);
|
|
|
|
RaycastHit h;
|
|
if (collider.Raycast(ray, out h, chunk.Length))
|
|
{
|
|
if (!hasHit || h.distance < currentDistance)
|
|
{
|
|
hasHit = true;
|
|
currentDistance = h.distance;
|
|
currentHit = new VoxelHit { Voxel = v, WorldNorma = h.normal, Normal = chunk.ChunkContainer.transform.InverseTransformDirection(h.normal) };
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
hit = currentHit;
|
|
|
|
if (hasHit)
|
|
{
|
|
hit = currentHit;
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
var chunkOrigin = chunk.ChunkContainer.transform.position;
|
|
var plane = new Plane(new Vector3(0, 1, 0), -chunkOrigin.y + 0.5f * Settings.CunkScale);
|
|
float d;
|
|
if (plane.Raycast(ray, out d))
|
|
{
|
|
var p = chunk.ChunkContainer.transform.InverseTransformPoint(ray.GetPoint(d));
|
|
|
|
var i = Mathf.FloorToInt(p.x + 0.5f);
|
|
var j = -1;
|
|
var k = Mathf.FloorToInt(p.z + 0.5f);
|
|
|
|
hit = new VoxelHit { Voxel = new Voxel { PrefabId = "", i = i, j = j, k = k }, Normal = new Vector3(0, 1, 0) };
|
|
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool RestoreWorldFromLocalStorage()
|
|
{
|
|
string json = "";
|
|
try
|
|
{
|
|
json = System.IO.File.ReadAllText(GetJsonFilename(), System.Text.Encoding.UTF8);
|
|
}
|
|
catch
|
|
{
|
|
Debug.Log("[ARLocation::WorldBuilder::RestoreWorld]: Failed to open json file for reading.");
|
|
//RandomPopulateWorld();
|
|
return false;
|
|
}
|
|
|
|
world = JsonUtility.FromJson<World>(json);
|
|
Debug.Log($"Restored world from json file '{GetJsonFilename()}'");
|
|
|
|
return true;
|
|
}
|
|
|
|
string GetJsonFilename()
|
|
{
|
|
var s = "WorldVoxelCraft";
|
|
|
|
return Application.persistentDataPath + "/" + s + ".json";
|
|
}
|
|
|
|
WorldChunk FindClosestChunk(Location l, out double distance, double maxDistance)
|
|
{
|
|
WorldChunk current = null;
|
|
double currentDistance = 0;
|
|
|
|
foreach (var c in world.Chunks)
|
|
{
|
|
var d = Location.HorizontalDistance(c.ChunkLocation, l);
|
|
|
|
if (current == null || d < currentDistance)
|
|
{
|
|
current = c;
|
|
currentDistance = d;
|
|
}
|
|
}
|
|
|
|
distance = currentDistance;
|
|
|
|
if (currentDistance > maxDistance) return null;
|
|
|
|
return current;
|
|
}
|
|
|
|
void BuildChunk(WorldChunk chunk)
|
|
{
|
|
chunk.ChunkContainer = new GameObject();
|
|
chunk.ChunkContainer.transform.localScale = new Vector3(Settings.CunkScale, Settings.CunkScale, Settings.CunkScale);
|
|
if (chunk.HasLocation)
|
|
{
|
|
PlaceAtLocation.AddPlaceAtComponent(chunk.ChunkContainer, chunk.ChunkLocation, new PlaceAtLocation.PlaceAtOptions { MaxNumberOfLocationUpdates = 2 });
|
|
chunk.ChunkContainer.transform.localEulerAngles = new Vector3(0, chunk.ChunkRotation, 0);
|
|
}
|
|
else
|
|
{
|
|
chunk.ChunkContainer.transform.position = chunk.Origin;
|
|
chunk.Bounds = new Bounds(chunk.Origin, new Vector3(chunk.Length, chunk.Length, chunk.Length));
|
|
chunk.ChunkContainer.AddComponent<GroundHeight>();
|
|
}
|
|
|
|
foreach (var v in chunk.Voxels)
|
|
{
|
|
v.Instance = Instantiate(PrefabDatabase.GetEntryById(v.PrefabId), chunk.ChunkContainer.transform);
|
|
v.Instance.transform.localPosition = new Vector3(v.i, v.j, v.k);
|
|
}
|
|
|
|
//if (Elements.ChunkPlanePrefab != null)
|
|
//{
|
|
// chunk.ChunkPlaneInstance = Instantiate(Elements.ChunkPlanePrefab, chunk.ChunkContainer.transform);
|
|
// chunk.ChunkPlaneInstance.transform.localPosition = new Vector3(0, -0.5f, 0);
|
|
// //chunk.ChunkPlaneInstance.transform.localScale = new Vector3(5, 1, 5);
|
|
// chunk.ChunkPlaneInstance.transform.localScale = new Vector3(chunk.Length/10, 1, chunk.Length/10);
|
|
// //chunk.ChunkPlaneInstance.GetComponent<MeshRenderer>().material.mainTextureScale = new Vector2(50, 50);
|
|
// chunk.ChunkPlaneInstance.GetComponent<MeshRenderer>().material.mainTextureScale = new Vector2(chunk.Length, chunk.Length);
|
|
// chunk.ChunkPlaneInstance.GetComponent<MeshRenderer>().material.mainTextureOffset = new Vector2(0.5f, 0.5f);
|
|
//}
|
|
}
|
|
|
|
private void OnApplicationPause(bool pause)
|
|
{
|
|
if (pause) SaveWorldToLocalStorage();
|
|
}
|
|
|
|
private void OnDestroy()
|
|
{
|
|
SaveWorldToLocalStorage();
|
|
}
|
|
|
|
void SaveWorldToLocalStorage()
|
|
{
|
|
var json = JsonUtility.ToJson(world);
|
|
|
|
try
|
|
{
|
|
System.IO.File.WriteAllText(GetJsonFilename(), json);
|
|
}
|
|
catch
|
|
{
|
|
Debug.Log("[ARLocation::WorldBuilder::SaveWorld]: Failed to open json file for writing.");
|
|
return;
|
|
}
|
|
|
|
Debug.Log("Saved " + GetJsonFilename());
|
|
}
|
|
|
|
private void OnLocationUpdatedListener(Location l)
|
|
{
|
|
|
|
if (state.AppState != ApplicationState.Running) return;
|
|
|
|
state.CurrentLocation = l;
|
|
|
|
FindClosestChunkOrCreateNew(l);
|
|
|
|
if (state.CurrentChunk != null)
|
|
{
|
|
UpdateChunkLocation(state.CurrentChunk);
|
|
}
|
|
|
|
}
|
|
|
|
private void FindClosestChunkOrCreateNew(Location l)
|
|
{
|
|
double distance;
|
|
var newClosestChunk = FindClosestChunk(l, out distance, 1000.0f);
|
|
if (newClosestChunk != state.CurrentChunk && newClosestChunk != null)
|
|
{
|
|
SetCurrentChunk(newClosestChunk);
|
|
}
|
|
|
|
if (state.CurrentChunk == null)
|
|
{
|
|
SetCurrentChunk(CreateDefaultChunk());
|
|
}
|
|
|
|
}
|
|
|
|
void UpdateChunkLocation(WorldChunk c)
|
|
{
|
|
if (!c.IsFresh) return;
|
|
|
|
c.ChunkLocation = ARLocationManager.Instance.GetLocationForWorldPosition(c.ChunkContainer.transform.position);
|
|
c.ChunkLocation.Altitude = 0;
|
|
c.ChunkLocation.AltitudeMode = AltitudeMode.GroundRelative;
|
|
var arLocationRoot = ARLocationManager.Instance.gameObject.transform;
|
|
float angle = Vector3.SignedAngle(c.ChunkContainer.transform.forward, arLocationRoot.forward, new Vector3(0, 1, 0));
|
|
c.ChunkRotation = angle;
|
|
c.HasLocation = true;
|
|
|
|
LogText($"Updated chunk location to {c.ChunkLocation}");
|
|
}
|
|
|
|
private void InitUiListeners()
|
|
{
|
|
Elements.ClearWorldBtn.onClick.AddListener(() =>
|
|
{
|
|
ClearWorld();
|
|
});
|
|
|
|
Elements.PickAxeBtn.onClick.AddListener(() =>
|
|
{
|
|
ChoosePickaxe();
|
|
});
|
|
|
|
Elements.BrickBtn.onClick.AddListener(() =>
|
|
{
|
|
ChooseBrick();
|
|
});
|
|
|
|
Elements.StoneBtn.onClick.AddListener(() =>
|
|
{
|
|
ChooseStone();
|
|
});
|
|
|
|
Elements.GoldBtn.onClick.AddListener(() =>
|
|
{
|
|
ChooseGold();
|
|
});
|
|
}
|
|
|
|
void ChooseBrick()
|
|
{
|
|
state.GameState = GameState.Build;
|
|
state.CurrentBlock = Blocks.Brick;
|
|
|
|
Elements.BrickBtn.GetComponent<Image>().color = Settings.ButtonSelectedColor;
|
|
Elements.GoldBtn.GetComponent<Image>().color = Settings.ButtonNormalColor;
|
|
Elements.StoneBtn.GetComponent<Image>().color = Settings.ButtonNormalColor;
|
|
Elements.PickAxeBtn.GetComponent<Image>().color = Settings.ButtonNormalColor;
|
|
}
|
|
|
|
void ChooseGold()
|
|
{
|
|
state.GameState = GameState.Build;
|
|
state.CurrentBlock = Blocks.Gold;
|
|
|
|
Elements.BrickBtn.GetComponent<Image>().color = Settings.ButtonNormalColor;
|
|
Elements.GoldBtn.GetComponent<Image>().color = Settings.ButtonSelectedColor;
|
|
Elements.StoneBtn.GetComponent<Image>().color = Settings.ButtonNormalColor;
|
|
Elements.PickAxeBtn.GetComponent<Image>().color = Settings.ButtonNormalColor;
|
|
}
|
|
|
|
void ChooseStone()
|
|
{
|
|
state.GameState = GameState.Build;
|
|
state.CurrentBlock = Blocks.Stone;
|
|
|
|
Elements.BrickBtn.GetComponent<Image>().color = Settings.ButtonNormalColor;
|
|
Elements.GoldBtn.GetComponent<Image>().color = Settings.ButtonNormalColor;
|
|
Elements.StoneBtn.GetComponent<Image>().color = Settings.ButtonSelectedColor;
|
|
Elements.PickAxeBtn.GetComponent<Image>().color = Settings.ButtonNormalColor;
|
|
}
|
|
|
|
void ChoosePickaxe()
|
|
{
|
|
state.GameState = GameState.Destroy;
|
|
|
|
|
|
Elements.BrickBtn.GetComponent<Image>().color = Settings.ButtonNormalColor;
|
|
Elements.GoldBtn.GetComponent<Image>().color = Settings.ButtonNormalColor;
|
|
Elements.StoneBtn.GetComponent<Image>().color = Settings.ButtonNormalColor;
|
|
Elements.PickAxeBtn.GetComponent<Image>().color = Settings.ButtonSelectedColor;
|
|
}
|
|
|
|
void ClearChunk(WorldChunk chunk)
|
|
{
|
|
if (chunk.ChunkContainer != null)
|
|
{
|
|
Elements.IndicatorPlane.transform.SetParent(null);
|
|
Destroy(chunk.ChunkContainer);
|
|
}
|
|
|
|
chunk.Voxels = new List<Voxel>();
|
|
}
|
|
|
|
void ClearWorld()
|
|
{
|
|
world.Chunks.ForEach(ClearChunk);
|
|
world.Chunks = new List<WorldChunk>();
|
|
state.CurrentChunk = null;
|
|
LogText("World cleared!");
|
|
}
|
|
|
|
private string GetMeshIdForBlock(Blocks b)
|
|
{
|
|
switch (b)
|
|
{
|
|
case Blocks.Brick:
|
|
return "Brick";
|
|
case Blocks.Stone:
|
|
return "Stone";
|
|
case Blocks.Gold:
|
|
return "Gold";
|
|
default:
|
|
return "";
|
|
}
|
|
}
|
|
}
|
|
}
|