Work on architecture. A lot of refractoring. Updated to unity 5.

This commit is contained in:
2015-03-12 10:44:44 +02:00
parent c51c5abbb1
commit c71b8ddd3e
436 changed files with 2144 additions and 17293 deletions

View File

@ -11,7 +11,7 @@ namespace TransportGame.Business
{
public static class BiomeManager
{
private static Dictionary<string, Biome> biomes = new Dictionary<string, Biome>();
private static List<Biome> biomes = new List<Biome>();
/// <summary>
/// Gets all the loaded biomes
@ -20,7 +20,7 @@ namespace TransportGame.Business
{
get
{
return biomes.Values;
return biomes;
}
}
@ -41,7 +41,7 @@ namespace TransportGame.Business
var biome = (Biome)serializer.Deserialize(stream);
// Add it to biome list
biomes.Add(file, biome);
biomes.Add(biome);
Logger.Info("Loaded biome '{0}' from file '{1}'.", biome.Name, file);
}
catch (Exception ex)

View File

@ -1,8 +1,11 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using Assets.Scripts.Model.Config;
using TransportGame.Utils;
namespace TransportGame.Business
{
@ -11,10 +14,14 @@ namespace TransportGame.Business
public static readonly string BiomeDirectory = "Assets\\Data\\Biomes";
public static readonly string ConfigurationDirectory = "Assets\\Data\\Config";
public static readonly string TerrGenConfigFile = "tergen.xml";
public static TerrainGeneratorConfig TerrGenConfig { get; private set; }
public static void LoadConfiguration()
{
// Load terrgen config
TerrGenConfig = XmlHelper.Deserialize<TerrainGeneratorConfig>(Path.Combine(ConfigurationDirectory, TerrGenConfigFile));
}
}
}

View File

@ -1,155 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using TransportGame.Model;
using TransportGame.Utils;
using UnityEngine;
namespace TransportGame.Generators
{
public static class MapImageRenderer
{
[Flags]
public enum Layers
{
None = 0,
Elevation = 1,
Grid = 2,
Centers = 4,
All = Elevation | Grid | Centers
};
private const int Scale = 20;
/// <summary>
/// Renders a map to a file
/// </summary>
/// <param name="file"></param>
/// <param name="map"></param>
/// <param name="layers"></param>
//public static void Render(this Map map, string file, Layers layers = Layers.All)
//{
// // Create texture on which to draw
// Texture2D texture = new Texture2D(
// map.Width * Scale,
// map.Height * Scale,
// TextureFormat.RGB24,
// false);
// // First layer - cells
// DrawCells(texture, map, (layers & Layers.Elevation) > 0, (layers & Layers.Centers) > 0);
// // Second layer - grid
// if ((layers & Layers.Grid) > 0)
// DrawGrid(texture, map);
// // Write to file
// File.WriteAllBytes(file + ".png", texture.EncodeToPNG());
//}
//private static void DrawCells(Texture2D texture, Map map, bool elevation, bool centers)
//{
// for (int x = 0; x < map.Width; x++)
// for (int y = 0; y < map.Height; y++)
// {
// // Calculate scaled corners
// Vector2 c00 = new Vector2(
// map[x, y].Corner00.Pos.x * Scale,
// map[x, y].Corner00.Pos.y * Scale);
// Vector2 c01 = new Vector2(
// map[x, y].Corner01.Pos.x * Scale,
// map[x, y].Corner01.Pos.y * Scale);
// Vector2 c10 = new Vector2(
// map[x, y].Corner10.Pos.x * Scale,
// map[x, y].Corner10.Pos.y * Scale);
// Vector2 c11 = new Vector2(
// map[x, y].Corner11.Pos.x * Scale,
// map[x, y].Corner11.Pos.y * Scale);
// // Calculate color
// Color c = ColorHelper.FromArgb(0x555500);
// // Water - always blue
// if (map.IsWater(x, y))
// c = Color.blue;
// // Map type is elevation map - get elevation color
// else if (elevation)
// c = GetCollorOfTerrain(map[x, y].Elevation);
// // Draw polygon
// texture.FillPolygon(c, c00, c01, c11, c10);
// // Draw center
// if (centers)
// texture.DrawPoint(Color.red,
// Convert.ToInt32(map[x, y].Center.x * Scale),
// Convert.ToInt32(map[x, y].Center.y * Scale),
// 2);
// }
//}
//private static void DrawGrid(Texture2D texture, Map map)
//{
// for (int x = 0; x < map.Width + 1; x++)
// for (int y = 0; y < map.Height + 1; y++)
// {
// Corner c0 = map.Corner(x, y);
// Vector2 c0pos = new Vector2(c0.Pos.x * Scale, c0.Pos.y * Scale);
// // Draw edges
// if (x > 0)
// {
// Corner c1 = map.Corner(x - 1, y);
// Vector2 c1pos = new Vector2(c1.Pos.x * Scale, c1.Pos.y * Scale);
// texture.DrawLine(Color.white, c0pos, c1pos);
// }
// if (y > 0)
// {
// Corner c1 = map.Corner(x, y - 1);
// Vector2 c1pos = new Vector2(c1.Pos.x * Scale, c1.Pos.y * Scale);
// texture.DrawLine(Color.white, c0pos, c1pos);
// }
// // Draw corner
// texture.DrawPoint(Color.white, c0pos, 2);
// }
//}
private static Color GetCollorOfTerrain(float height)
{
Color color1, color2;
float alpha;
if (height < 10f)
{
color1 = ColorHelper.FromArgb(0x00ffa2);
color2 = ColorHelper.FromArgb(0xFCD628);
alpha = height / 10f;
}
else if (height < 25f)
{
color1 = ColorHelper.FromArgb(0xFCD628);
color2 = ColorHelper.FromArgb(0x9C6713);
alpha = (height - 10f) / 15f;
}
else if (height < 50f)
{
color1 = ColorHelper.FromArgb(0xaaaaaa);
color2 = ColorHelper.FromArgb(0xffffff);
alpha = (height - 25f) / 25f;
}
else
{
color1 = color2 = Color.white;
alpha = 1;
}
return Color.Lerp(color1, color2, alpha);
}
}
}

View File

@ -20,6 +20,10 @@ namespace TransportGame.Generator
public TerrainGenerator()
{
Noise = new PerlinNoiseGenerator();
if (ConfigurationManager.TerrGenConfig == null)
throw new Exception("WTF?");
Noise.Octaves = ConfigurationManager.TerrGenConfig.NoiseOctaves;
Noise.NonLinearPower = ConfigurationManager.TerrGenConfig.NoiseNonLinearPower;
Noise.Scale = ConfigurationManager.TerrGenConfig.ElevationScale;
@ -32,6 +36,7 @@ namespace TransportGame.Generator
// Pick a random biome
map.Biome = PickBiome();
Logger.Info("Picked biome: {0}", map.Biome.Name);
// Generate elevation
GenerateElevation(map);
@ -40,6 +45,7 @@ namespace TransportGame.Generator
float waterAmount = random.NextSingle(map.Biome.Moisture.Minimum, map.Biome.Moisture.Maximum);
map.WaterLevel = Mathf.Pow(waterAmount, 3) * (map.Biome.HeightRange.Maximum - map.Biome.HeightRange.Minimum) + map.Biome.HeightRange.Minimum;
DumpData(map);
return map;
}
@ -57,5 +63,22 @@ namespace TransportGame.Generator
for (int y = 0; y < map.Height; ++y)
map[x, y] = Noise.Generate(x, y, map.Biome.HeightRange.Minimum, map.Biome.HeightRange.Maximum);
}
private void DumpData(Map map)
{
StringBuilder builder = new StringBuilder();
for (int x = 0; x < map.Width; ++x)
{
for (int y = 0; y < map.Height; ++y)
{
builder.Append(map[x, y]);
builder.Append(';');
}
builder.AppendLine();
}
Logger.Info("Generated map: \n{0}", builder.ToString());
}
}
}

View File

@ -1,109 +1,28 @@
using UnityEngine;
using System.Collections;
using TransportGame.Utils;
using TransportGame.Model;
using TransportGame.Generators;
using System.Collections.Generic;
using System.Collections;
using System.Threading;
using TransportGame.Business;
using TransportGame.Model;
using TransportGame.Utils;
using UnityEngine;
public class InitializeScript : MonoBehaviour
{
public Material TerrainMaterial;
public int TerrainWidth = 256, TerrainHeight = 256;
private Map map;
// Use this for initialization
public void Start()
{
StartCoroutine(GenerateMap());
}
{
// Load configuration
Logger.Info("Loading configuration...");
ConfigurationManager.LoadConfiguration();
Logger.Info("Finished loading configuration.");
private IEnumerator GenerateMap()
{
// Load biomes
Logger.Info("Loading biomes...");
BiomeManager.LoadBiomes();
Logger.Info("Finished loading biomes.");
// Generate map in the other thread
Thread thread = new Thread(GenerateMapThread);
thread.Start();
while (thread.ThreadState == ThreadState.Running)
{
yield return null;
}
thread.Join();
// map.Render(@"C:\Users\Tiberiu\Desktop\img");
// Log - Generate mesh
yield return null;
Debug.Log("Generating mesh...");
var heights = new float[map.Width, map.Height];
for (int x = 0; x < map.Width; x++)
for (int y = 0; y < map.Height; y++)
heights[x, y] = map[y, x] / 50f;
// Generate mesh using terraindata
TerrainData terrainData = new TerrainData();
terrainData.heightmapResolution = map.Width;
terrainData.size = new Vector3(map.Width * MapMeshGenerator.Scale, 50.0f * MapMeshGenerator.Strength, map.Height * MapMeshGenerator.Scale);
//terrainData.baseMapResolution = 1024;
//terrainData.alphamapResolution = 512;
terrainData.SetDetailResolution(1024, 8);
terrainData.SetHeights(0, 0, heights);
terrainData.name = "Le terrain data";
GameObject terrainObj = Terrain.CreateTerrainGameObject(terrainData);
terrainObj.name = "Le Terrain";
Terrain t1 = terrainObj.GetComponent<Terrain>();
t1.heightmapPixelError = 1;
MapMeshGenerator meshGen = new MapMeshGenerator(map);
//for (int x = 0; x < meshGen.ChunksWidth; x++)
// for (int y = 0; y < meshGen.ChunksHeight; y++)
// {
// CreateGameObjectFromMesh(string.Format("chunk_{0}_{1}", x, y), meshGen[x, y], TerrainMaterial);
// yield return null;
// }
// Generate water
GameObject water = GameObject.Find("Water");
MeshFilter waterFilter = water.GetComponent<MeshFilter>();
waterFilter.mesh = meshGen.Water;
yield return null;
Debug.Log("Finished generating map.");
yield return null;
}
private void CreateGameObjectFromMesh(string name, Mesh mesh, Material material)
{
GameObject gameObject = new GameObject(name);
// Add mesh filter component
MeshFilter meshFilter = gameObject.AddComponent<MeshFilter>();
meshFilter.mesh = mesh;
// Add mesh render component
MeshRenderer meshRenderer = gameObject.AddComponent<MeshRenderer>();
meshRenderer.material = material;
}
private void GenerateMapThread()
{
MapGenerator mapGen = new MapGenerator();
map = mapGen.Generate(TerrainWidth, TerrainHeight);
}
// Update is called once per frame
void Update()
{
}
}

View File

@ -1,8 +1,12 @@
fileFormatVersion: 2
guid: c1e1bcc13284685449456c96db1d1754
timeCreated: 1425647800
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
executionOrder: -100
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -9,11 +9,13 @@ namespace Assets.Scripts.Model.Config
[XmlRoot("terrgenConfig")]
public class TerrainGeneratorConfig
{
[XmlElement("noiseOctaves")]
public int NoiseOctaves { get; set; }
[XmlElement("noiseNonLinearPower")]
public float NoiseNonLinearPower { get; set; }
[XmlElement("elevationScale")]
public float ElevationScale { get; set; }
}
}

View File

@ -20,6 +20,17 @@ namespace TransportGame.Model
/// </summary>
public Biome Biome { get; set; }
/// <summary>
/// Gets the heights array
/// </summary>
public float[,] Heights
{
get
{
return grid;
}
}
/// <summary>
/// Initializes the map
/// </summary>

View File

@ -1,15 +1,87 @@
using UnityEngine;
using System.Collections;
public class TerrainGeneratorScript : MonoBehaviour {
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
}
using UnityEngine;
using System.Collections;
using TransportGame.Utils;
using System.Threading;
using TransportGame.Generator;
using TransportGame.Model;
using TransportGame.Business;
public class TerrainGeneratorScript : MonoBehaviour
{
private Map map = null;
public int TerrainWidth = 256;
public int TerrainHeight = 256;
public GameObject WaterObject;
// Use this for initialization
void Start()
{
StartCoroutine(GenerateMap());
}
private void GenerateMapThread()
{
TerrainGenerator generator = new TerrainGenerator();
map = generator.Generate(TerrainWidth, TerrainHeight);
}
private Mesh GenerateWater()
{
Mesh water = new Mesh();
water.name = "water";
water.vertices = new[] {
new Vector3(0, map.WaterLevel, 0),
new Vector3(0, map.WaterLevel, map.Height),
new Vector3(map.Width, map.WaterLevel, 0),
new Vector3(map.Width, map.WaterLevel, map.Height)
};
water.triangles = new[] { 0, 1, 2, 2, 1, 3 };
water.uv = new[] {
new Vector2(0, 0),
new Vector2(0, 1),
new Vector2(1, 0),
new Vector2(1, 1)
};
water.RecalculateNormals();
return water;
}
private IEnumerator GenerateMap()
{
// Wait for the map generation thread
foreach (var i in Task.RunAsync(GenerateMapThread))
yield return i;
// Generate terrain data
TerrainData terrainData = new TerrainData();
terrainData.heightmapResolution = Mathf.Max(map.Height, map.Width);
terrainData.size = new Vector3(map.Width, map.Biome.HeightRange.Maximum, map.Height);
terrainData.SetDetailResolution(1024, 8);
terrainData.SetHeights(0, 0, map.Heights);
terrainData.name = "Generated Terrain Data";
yield return null;
// Create terrain object
GameObject terrain = Terrain.CreateTerrainGameObject(terrainData);
terrain.name = "Generated Terrain";
yield return null;
Terrain terrainComp = terrain.GetComponent<Terrain>();
terrainComp.heightmapPixelError = 1;
yield return null;
// Set water
if (WaterObject != null)
{
MeshFilter waterMesh = WaterObject.GetComponent<MeshFilter>();
waterMesh.mesh = GenerateWater();
}
}
// Update is called once per frame
void Update()
{
}
}

View File

@ -8,7 +8,7 @@ namespace TransportGame.Utils
{
public static class Logger
{
private static StreamWriter logFile;
private static string logFile = null;
public enum Level
{
@ -23,28 +23,40 @@ namespace TransportGame.Utils
// Open log file if not opened
if (logFile == null)
{
logFile = new StreamWriter(String.Format("Logs\\{0}.log", DateTime.Now.Ticks));
// Create logs folder
if (!Directory.Exists("Logs"))
Directory.CreateDirectory("Logs");
// Create log file
logFile = String.Format("Logs\\{0}.log", DateTime.Now.Ticks);
}
// Log to file
logFile.Write("[{0}] ", Enum.GetName(typeof(Level), level));
logFile.Write(DateTime.Now.ToLongTimeString());
logFile.WriteLine(": " + format, args);
// Log to unity
switch (level)
lock (logFile)
{
case Level.Warning:
UnityEngine.Debug.LogWarning(String.Format(format, args));
break;
using (var writer = new StreamWriter(logFile, true))
{
// Log to file
writer.Write("[{0}] ", Enum.GetName(typeof(Level), level));
writer.Write(DateTime.Now.ToString("%HH:%mm:%ss.%FFF"));
writer.WriteLine(": " + format, args);
writer.Close();
}
case Level.Error:
UnityEngine.Debug.LogError(String.Format(format, args));
break;
// Log to unity
switch (level)
{
case Level.Warning:
UnityEngine.Debug.LogWarning(String.Format(format, args));
break;
case Level.Critical:
UnityEngine.Debug.LogError(String.Format(format, args));
break;
case Level.Error:
UnityEngine.Debug.LogError(String.Format(format, args));
break;
case Level.Critical:
UnityEngine.Debug.LogError(String.Format(format, args));
break;
}
}
}

View File

@ -0,0 +1,56 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace TransportGame.Utils
{
public static class Task
{
private class TaskInfo
{
public Action Action { get; set; }
public bool? Success { get; set; }
public Exception ThrownException { get; set; }
}
private static void RunAsync_ActionThread(object info)
{
TaskInfo taskInfo = (TaskInfo)info;
try
{
taskInfo.Action();
taskInfo.Success = true;
}
catch (Exception ex)
{
taskInfo.ThrownException = ex;
taskInfo.Success = false;
}
}
public static IEnumerable RunAsync(Action action)
{
// Set up task info object
TaskInfo taskInfo = new TaskInfo();
taskInfo.Action = action;
// Start thread and wait
var thread = new Thread(RunAsync_ActionThread);
thread.Start(taskInfo);
// Wait for thread to finish
while (thread.ThreadState == ThreadState.Running)
yield return null;
thread.Join();
// Rethrow exception
if (taskInfo.Success.HasValue && !taskInfo.Success.Value)
throw new Exception("Task failed", taskInfo.ThrownException);
}
}
}

View File

@ -1,8 +1,12 @@
fileFormatVersion: 2
guid: d89d584776261fe4b81720b3615755bb
guid: e07530e47d7019b418499d12a7c29f35
timeCreated: 1425923206
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
namespace TransportGame.Utils
{
public static class XmlHelper
{
/// <summary>
/// Deserializes a file
/// </summary>
/// <typeparam name="T">Type to deserialize</typeparam>
/// <param name="filename">File name</param>
/// <returns>Deserialized object</returns>
public static T Deserialize<T>(string filename)
{
XmlSerializer serializer = new XmlSerializer(typeof(T));
var stream = new StreamReader(filename);
return (T)serializer.Deserialize(stream);
}
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: a4d12846fa3e22f4fbd829e42582d6a9
timeCreated: 1425647029
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: