Galaxy Editor Changes

This commit is contained in:
hyperion51 2020-03-23 01:43:37 +00:00
commit 5e5a748720
7 changed files with 120 additions and 204 deletions

BIN
Assets/Resources/Test Galaxy.asset (Stored with Git LFS)

Binary file not shown.

BIN
Assets/Resources/Test.asset (Stored with Git LFS) Normal file

Binary file not shown.

View file

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 931e677be56754f4f9d3d0817e2d38df
guid: 8525ebaeff3478247bbeb4d8eb71ef35
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000

View file

@ -10,30 +10,37 @@ using UnityEditor;
[CustomEditor(typeof(Galaxy))]
public class GalaxyEditor : Editor
{
private Texture2D _preview;
private int _width = 0;
private TextAsset _nameData;
private bool _showNameData;
private bool _showCultureMaps;
private Dictionary<string,bool> _expandRegion = new Dictionary<string, bool>();
private Dictionary<string,bool> _expandSubregion = new Dictionary<string, bool>();
private NameData _names = new NameData();
private bool _showResourceMaps;
private GalaxyMapLayerData _currentLayer;
private string _currentLayerName = "Star Density";
private bool _showStarEditor;
private int _hilbertOrder = 6;
private ulong _hilbertIndex;
private int _starCount = 1;
private int _nameMinLength = 5;
private int _nameMaxLength = 8;
private float _maxLinkLength = .1f;
private float _linkFilter = .5f;
private IEnumerable<Vector2> _stars = new Vector2[0];
private bool _drawStars;
private bool _drawCulture;
private bool _drawResource;
private bool _drawLinks;
private VoronoiMesh< Vertex2, Cell2, VoronoiEdge<Vertex2, Cell2>> _voronoiMesh;
private List<VoronoiLink> _starLinks = new List<VoronoiLink>();
private Texture2D _white;
private Texture2D _starTex;
private Texture2D _linkTex;
private Material _galaxyMat;
private Material _transparent;
private void OnEnable()
{
_white = Color.white.ToTexture();
_galaxyMat = new Material(Shader.Find("Unlit/GalaxyMap"));
_transparent = new Material(Shader.Find("Unlit/Transparent"));
_width = Screen.width;
_starTex = new Texture2D(_width,_width, TextureFormat.ARGB32, false);
_linkTex = new Texture2D(_width,_width, TextureFormat.ARGB32, false);
}
public override void OnInspectorGUI()
{
@ -45,134 +52,84 @@ public class GalaxyEditor : Editor
if (Screen.width != _width)
{
_width = Screen.width;
_preview = new Texture2D(_width,_width,TextureFormat.ARGB32,false);
Render(galaxy.MapData, _currentLayer);
_starTex = new Texture2D(_width,_width, TextureFormat.ARGB32, false);
_linkTex = new Texture2D(_width,_width, TextureFormat.ARGB32, false);
RenderStars();
RenderLinks();
}
GUILayout.Label("Preview", EditorStyles.boldLabel);
EditorGUI.DrawPreviewTexture(EditorGUILayout.GetControlRect(false, _width), _preview);
EditorGUI.BeginChangeCheck();
_galaxyMat.SetFloat("Arms", galaxy.MapData.Arms);
_galaxyMat.SetFloat("Twist", galaxy.MapData.Twist);
_galaxyMat.SetFloat("TwistPower", galaxy.MapData.TwistPower);
_galaxyMat.SetFloat("Arms", galaxy.MapData.Arms);
_galaxyMat.SetFloat("SpokeOffset", _currentLayer.SpokeOffset);
_galaxyMat.SetFloat("SpokeScale", _currentLayer.SpokeScale);
_galaxyMat.SetFloat("CoreBoost", _currentLayer.CoreBoost);
_galaxyMat.SetFloat("CoreBoostOffset", _currentLayer.CoreBoostOffset);
_galaxyMat.SetFloat("CoreBoostPower", _currentLayer.CoreBoostPower);
_galaxyMat.SetFloat("EdgeReduction", _currentLayer.EdgeReduction);
_galaxyMat.SetFloat("NoisePosition", _currentLayer.NoisePosition);
_galaxyMat.SetFloat("NoiseAmplitude", _currentLayer.NoiseAmplitude);
_galaxyMat.SetFloat("NoiseOffset", _currentLayer.NoiseOffset);
_galaxyMat.SetFloat("NoiseGain", _currentLayer.NoiseGain);
_galaxyMat.SetFloat("NoiseLacunarity", _currentLayer.NoiseLacunarity);
_galaxyMat.SetFloat("NoiseFrequency", _currentLayer.NoiseFrequency);
var rect = EditorGUILayout.GetControlRect(false, _width);
EditorGUI.DrawPreviewTexture(rect, _white, _galaxyMat);
if(_drawLinks)
EditorGUI.DrawPreviewTexture(rect, _linkTex, _transparent);
if(_drawStars)
EditorGUI.DrawPreviewTexture(rect, _starTex, _transparent);
_drawStars = EditorGUILayout.ToggleLeft($"Display {_stars.Count()} Stars", _drawStars);
_drawCulture = EditorGUILayout.ToggleLeft("Display Cultures", _drawCulture);
_drawResource = EditorGUILayout.ToggleLeft("Display Resources", _drawResource);
_drawLinks = EditorGUILayout.ToggleLeft($"Display {_starLinks.Count} Links", _drawLinks);
GUILayout.Space(10);
// Show default inspector property editor
DrawDefaultInspector ();
if (galaxy.MapData.CultureDensities.Count != galaxy.NameDatabase.Count)
galaxy.MapData.CultureDensities = galaxy.NameDatabase.Select(continent=>new GalaxyMapLayerData()).ToList();
EditorGUILayout.BeginVertical("Box");
EditorGUI.indentLevel++;
GUILayout.Label(_currentLayerName);
Inspect(_currentLayer);
EditorGUI.indentLevel--;
EditorGUILayout.EndVertical();
if(EditorGUI.EndChangeCheck())
Render(galaxy.MapData, _currentLayer);
EditorGUILayout.BeginVertical("Box");
EditorGUI.indentLevel++;
_showCultureMaps = EditorGUILayout.Foldout(_showCultureMaps, "Culture Density Maps");
if (_showCultureMaps)
_showResourceMaps = EditorGUILayout.Foldout(_showResourceMaps, "Resource Density Maps");
if (_showResourceMaps)
{
EditorGUI.indentLevel++;
for (var i = 0; i < galaxy.MapData.CultureDensities.Count; i++)
foreach (var resourceDensity in galaxy.MapData.ResourceDensities.ToArray())
{
var cultureMap = galaxy.MapData.CultureDensities[i];
var data = galaxy.NameDatabase[i];
if (GUILayout.Button("Inspect " + data.Name))
EditorGUILayout.BeginHorizontal();
var newName = EditorGUILayout.DelayedTextField(resourceDensity.Key);
if (newName != resourceDensity.Key)
{
_currentLayerName = data.Name;
_currentLayer = cultureMap;
Render(galaxy.MapData, _currentLayer);
galaxy.MapData.ResourceDensities.Remove(resourceDensity.Key);
galaxy.MapData.ResourceDensities[newName] = resourceDensity.Value;
}
if (GUILayout.Button("Inspect"))
{
_currentLayerName = resourceDensity.Key;
_currentLayer = resourceDensity.Value;
}
EditorGUILayout.EndHorizontal();
}
EditorGUI.indentLevel--;
if (GUILayout.Button("Add New Resource"))
{
galaxy.MapData.ResourceDensities["New Resource"] = new GalaxyMapLayerData();
}
}
else if(_currentLayer != galaxy.MapData.StarDensity)
{
_currentLayerName = "Star Density";
_currentLayer = galaxy.MapData.StarDensity;
Render(galaxy.MapData, _currentLayer);
}
EditorGUI.indentLevel--;
EditorGUILayout.EndVertical();
EditorGUILayout.BeginVertical("Box");
EditorGUI.indentLevel++;
_showNameData = EditorGUILayout.Foldout(_showNameData, "Name Database Tools");
if (_showNameData)
{
EditorGUI.indentLevel++;
foreach (var region in _names.Names.Keys)
{
if (!_expandRegion.ContainsKey(region))
_expandRegion[region] = false;
_expandRegion[region] = EditorGUILayout.Foldout(_expandRegion[region], region + ": " + _names.Names[region].Count + " Subregions");
if (_expandRegion[region])
{
EditorGUI.indentLevel++;
foreach (var subregion in _names.Names[region].Keys)
{
if (!_expandSubregion.ContainsKey(subregion))
_expandSubregion[subregion] = false;
_expandSubregion[subregion] = EditorGUILayout.Foldout(_expandSubregion[subregion], subregion + ": " + _names.Names[region][subregion].Count + " Towns");
if (_expandSubregion[subregion])
{
EditorGUI.indentLevel++;
foreach (var town in _names.Names[region][subregion])
{
GUILayout.Label(town);
}
EditorGUI.indentLevel--;
}
}
EditorGUI.indentLevel--;
}
}
EditorGUI.indentLevel--;
GUILayout.Space(10);
_nameData = EditorGUILayout.ObjectField(_nameData, typeof(TextAsset), false) as TextAsset;
if (GUILayout.Button("Parse Data"))
{
_names.Names.Clear();
foreach (var s in _nameData.text.Split('\n'))
_names.Add(s);
}
if (GUILayout.Button("Filter Data"))
{
if (!_names.Names.ContainsKey("World"))
{
_names.Names["World"] = new Dictionary<string, List<string>>();
_names.Names["World"]["Miscellaneous"] = new List<string>();
}
foreach (var region in _names.Names.Keys.Where(s=>s!="World").ToArray())
{
if (!_names.Names[region].ContainsKey("Miscellaneous"))
_names.Names[region]["Miscellaneous"] = new List<string>();
foreach (var subregion in _names.Names[region].Keys.Where(s=>s!="Miscellaneous").ToArray())
{
if (_names.Names[region][subregion].Count < 500)
{
_names.Names[region]["Miscellaneous"].AddRange(_names.Names[region][subregion]);
_names.Names[region].Remove(subregion);
}
}
if (_names.Names[region].Count == 1)
{
_names.Names["World"]["Miscellaneous"].AddRange(_names.Names[region]["Miscellaneous"]);
_names.Names.Remove(region);
}
}
}
if (GUILayout.Button("Set Data"))
{
var data = new List<ContinentData>();
data.AddRange(_names.Names.Select(kvp => new ContinentData{Name = kvp.Key,Regions = new List<RegionData>()}));
data.ForEach(c=>c.Regions.AddRange(_names.Names[c.Name].Select(kvp=> new RegionData{Name = kvp.Key,Towns = kvp.Value})));
galaxy.NameDatabase = data;
}
}
EditorGUI.indentLevel--;
EditorGUILayout.EndVertical();
@ -216,29 +173,10 @@ public class GalaxyEditor : Editor
}
Debug.Log($"Generated {stars.Count} stars.");
_stars = stars;
RenderStars();
}
if (_stars.Any())
{
_nameMinLength = EditorGUILayout.IntField("Minimum Length", _nameMinLength);
_nameMaxLength = EditorGUILayout.IntField("Maximum Length", _nameMaxLength);
if (GUILayout.Button("Generate Star Names"))
{
galaxy.MapData.Stars = _stars.Select(s =>
{
var culture = galaxy.MapData.CultureDensities.IndexOf(galaxy.MapData.CultureDensities.OrderByDescending(c => c.Evaluate(s, galaxy.MapData))
.First());
var subculture = UnityEngine.Random.Range(0, galaxy.NameDatabase[culture].Regions.Count);
var markov = new MarkovNameGenerator(galaxy.NameDatabase[culture].Regions[subculture].Towns, 2, _nameMinLength, _nameMaxLength);
return new StarData
{
Position = s,
NameSource = (galaxy.NameDatabase[culture].Regions[subculture].Name == "Miscellaneous")
? galaxy.NameDatabase[culture].Name
: galaxy.NameDatabase[culture].Regions[subculture].Name,
Names = Enumerable.Range(0,20).Select(_ => markov.NextName).ToList()
};
}).ToList();
}
_maxLinkLength = EditorGUILayout.FloatField("Max Link Length", _maxLinkLength);
if (GUILayout.Button("Generate Star Links"))
{
@ -252,6 +190,7 @@ public class GalaxyEditor : Editor
new VoronoiLink(cell.Vertices[2], cell.Vertices[1])};
_starLinks.AddRange(links.Where(l=>!_starLinks.ContainsLine(l) && l.Length < _maxLinkLength));
RenderLinks();
}
}
if (_starLinks.Any())
@ -278,8 +217,9 @@ public class GalaxyEditor : Editor
}
//if (_starLinks.Count(sl => sl.ContainsPoint(link.point1)) > 1 && _starLinks.Count(sl => sl.ContainsPoint(link.point2)) > 1)
}
RenderLinks();
}
if (GUILayout.Button("Apply Star Links"))
if (GUILayout.Button("Save Star Links"))
{
foreach (var star in galaxy.MapData.Stars)
{
@ -298,33 +238,6 @@ public class GalaxyEditor : Editor
EditorUtility.SetDirty(target);
/*
EditorGUI.BeginChangeCheck();
_arms = EditorGUILayout.IntField("Arms", _arms);
_twist = EditorGUILayout.FloatField("Twist", _twist);
_twistPower = EditorGUILayout.FloatField("Twist Power", _twistPower);
EditorGUILayout.field
_edgeReduction = EditorGUILayout.FloatField("Edge Reduction", _edgeReduction);
_coreBoost = EditorGUILayout.FloatField("Core Boost", _coreBoost);
_coreBoostOffset = EditorGUILayout.FloatField("Core Boost Offset", _coreBoostOffset);
_coreBoostPower = EditorGUILayout.FloatField("Core Boost Power", _coreBoostPower);
_noiseAmplitude = EditorGUILayout.FloatField("Noise Amplitude", _noiseAmplitude);
_noise.SetFractalGain(_noiseGain = EditorGUILayout.FloatField("Noise Gain", _noiseGain));
_noise.SetFractalLacunarity(_noiseLacunarity = EditorGUILayout.FloatField("Noise Lacunarity", _noiseLacunarity));
_noise.SetFractalOctaves(_noiseOctaves = EditorGUILayout.IntField("Noise Octaves", _noiseOctaves));
_noise.SetFrequency(_noiseFrequency = EditorGUILayout.FloatField("Noise Frequency", _noiseFrequency));
if(EditorGUI.EndChangeCheck())
Render();
if (GUILayout.Button("Randomize Seed"))
{
_noise.SetSeed((int) (UnityEngine.Random.value*int.MaxValue));
Render();
}
if(GUILayout.Button("Regenerate"))
Render();
*/
}
private IEnumerable<Vector2> EvaluateHilbert(int order, bool normalized = true)
@ -356,45 +269,50 @@ public class GalaxyEditor : Editor
layer.NoiseLacunarity = EditorGUILayout.FloatField("Noise Lacunarity", layer.NoiseLacunarity);
layer.NoiseOctaves = EditorGUILayout.IntField("Noise Octaves", layer.NoiseOctaves);
layer.NoiseFrequency = EditorGUILayout.FloatField("Noise Frequency", layer.NoiseFrequency);
layer.NoiseOffset = EditorGUILayout.FloatField("Noise Seed", layer.NoiseOffset);
layer.SpokeOffset = EditorGUILayout.FloatField("Spoke Offset", layer.SpokeOffset);
layer.SpokeScale = EditorGUILayout.FloatField("Spoke Scale", layer.SpokeScale);
}
int UvToIndex(Vector2 v) => (int) (v.y * _width) * _width + (int) (v.x * _width);
void Render(GalaxyMapData galaxy, GalaxyMapLayerData layer)
void RenderLinks()
{
Color[] pixels = new Color[_width*_width];
Func<int, Vector2> indexToUV = i => new Vector2(i % _width / (float) _width, i / _width / (float) _width);
Func<Vector2, int> uvToIndex = v => (int) (v.y * _width) * _width + (int) (v.x * _width);
for (var i = 0; i < pixels.Length; i++)
{
Vector2 uv = indexToUV(i);
pixels[i] = layer.Evaluate(uv, galaxy) * Color.white;
if (_drawCulture)
pixels[i] += Color.HSVToRGB(
(float) galaxy.CultureDensities.IndexOf(galaxy.CultureDensities.OrderByDescending(m => m.Evaluate(uv, galaxy)).First()) /
galaxy.CultureDensities.Count,
1,
.5f);
pixels[i] = Color.clear;
}
if(_drawStars)
foreach (var s in _stars)
{
pixels[uvToIndex(s)] = Color.white;
pixels[uvToIndex(s + Vector2.up / _width)] += Color.white / 2;
pixels[uvToIndex(s - Vector2.up / _width)] += Color.white / 2;
pixels[uvToIndex(s + Vector2.right / _width)] += Color.white / 2;
pixels[uvToIndex(s - Vector2.right / _width)] += Color.white / 2;
}
if(_drawLinks)
foreach (var l in _starLinks)
{
var pixelCount = Mathf.Max((int) (Mathf.Abs((float) (l.point1.x - l.point2.x)) * _width), (int) (Mathf.Abs((float) (l.point1.y - l.point2.y)) * _width));
//Debug.Log($"Marching across {pixelCount} pixels!");
for(int i=0;i<pixelCount;i++)
pixels[uvToIndex(Vector2.Lerp(l.point1.ToVector2(),l.point2.ToVector2(),(float)i/pixelCount))] += Color.white / 2;
}
_preview.SetPixels(pixels);
_preview.Apply();
foreach (var l in _starLinks)
{
var pixelCount = Mathf.Max((int) (Mathf.Abs((float) (l.point1.x - l.point2.x)) * _width), (int) (Mathf.Abs((float) (l.point1.y - l.point2.y)) * _width));
//Debug.Log($"Marching across {pixelCount} pixels!");
for(int i=0;i<pixelCount;i++)
pixels[UvToIndex(Vector2.Lerp(l.point1.ToVector2(),l.point2.ToVector2(),(float)i/pixelCount))] = XKCDColors.OrangeRed;
}
_linkTex.SetPixels(pixels);
_linkTex.Apply();
}
void RenderStars()
{
Color[] pixels = new Color[_width*_width];
for (var i = 0; i < pixels.Length; i++)
{
pixels[i] = Color.clear;
}
foreach (var s in _stars)
{
pixels[UvToIndex(s)] = Color.white;
pixels[UvToIndex(s + Vector2.up / _width)] = new Color(.5f, .5f, .5f, 1);
pixels[UvToIndex(s - Vector2.up / _width)] = new Color(.5f, .5f, .5f, 1);
pixels[UvToIndex(s + Vector2.right / _width)] = new Color(.5f, .5f, .5f, 1);
pixels[UvToIndex(s - Vector2.right / _width)] = new Color(.5f, .5f, .5f, 1);
pixels[UvToIndex(s + Vector2.up / _width + Vector2.right / _width)] = new Color(0, 0, 0, 1);
pixels[UvToIndex(s + Vector2.up / _width - Vector2.right / _width)] = new Color(0, 0, 0, 1);
pixels[UvToIndex(s - Vector2.up / _width - Vector2.right / _width)] = new Color(0, 0, 0, 1);
pixels[UvToIndex(s - Vector2.up / _width + Vector2.right / _width)] = new Color(0, 0, 0, 1);
}
_starTex.SetPixels(pixels);
_starTex.Apply();
}
}

View file

@ -15,7 +15,6 @@ using static NoiseFbm;
public class Galaxy : ScriptableObject
{
public GalaxyMapData MapData;
public List<ContinentData> NameDatabase;
}
[Serializable]
@ -28,7 +27,7 @@ public class GalaxyMapData
[HideInInspector]
public GalaxyMapLayerData StarDensity;
[HideInInspector]
public List<GalaxyMapLayerData> CultureDensities = new List<GalaxyMapLayerData>();
public Dictionary<string,GalaxyMapLayerData> ResourceDensities = new Dictionary<string, GalaxyMapLayerData>();
//[HideInInspector]
public List<StarData> Stars = new List<StarData>();
}
@ -77,8 +76,6 @@ public class StarData
{
public Vector2 Position;
public List<int> Links = new List<int>();
public string NameSource;
public List<string> Names = new List<string>();
}
public static class NoiseFbm
@ -121,7 +118,7 @@ public class GalaxyMapLayerData
float angle = pow(length(offset)*2,galaxy.TwistPower) * galaxy.Twist;
float2 twist = float2(offset.x*cos(angle) - offset.y*sin(angle), offset.x*sin(angle) + offset.y*cos(angle));
float atan = atan2(twist.y,twist.x);
float spokes = sin(atan*galaxy.Arms) * SpokeScale + SpokeOffset;
float spokes = (sin(atan*galaxy.Arms) + SpokeOffset) * SpokeScale;
float noise = fBm(uv + float2(NoisePosition), NoiseOctaves, NoiseFrequency, NoiseOffset, NoiseAmplitude, NoiseLacunarity, NoiseGain);
float shape = lerp(spokes - EdgeReduction * length(offset), 1, pow(circle + CoreBoostOffset, CoreBoostPower) * CoreBoost);
float gal = max(shape - noise * saturate(circle), 0);
@ -254,7 +251,8 @@ public static class VoronoiLinkExtensions
int lastCount = members.Count;
// For each member, add all vertices that are connected to it via a line but are not already a member
foreach (Vertex2 m in members.ToArray())
members.AddRange(data.Where(l => l.point1 == m).Select(l => l.point2).Concat(data.Where(l => l.point2 == m).Select(l => l.point1))
members.AddRange(data.Where(l => l.point1 == m).Select(l => l.point2)
.Concat(data.Where(l => l.point2 == m).Select(l => l.point1))
.Where(n => !members.Contains(n)));
// If we have stopped finding neighbors, stop traversing
if (members.Count == lastCount)

View file

@ -20,10 +20,10 @@
NoiseGain("NoiseGain", Float) = 1
NoiseLacunarity("NoiseLacunarity", Float) = 2
NoiseFrequency("NoiseFrequency", Float) = 1
GlowOffset("GlowOffset", Float) = 1
GlowAmount("GlowAmount", Float) = 1
GlowPower("GlowPower", Float) = 1
StarBoost("StarBoost", Float) = 1
GlowOffset("GlowOffset", Float) = 0
GlowAmount("GlowAmount", Float) = 0
GlowPower("GlowPower", Float) = 0
StarBoost("StarBoost", Float) = 0
// required for UI.Mask
_StencilComp ("Stencil Comparison", Float) = 8
@ -127,13 +127,13 @@
float angle = pow(length(offset)*2,TwistPower) * Twist;
float2 twist = float2(offset.x*cos(angle) - offset.y*sin(angle), offset.x*sin(angle) + offset.y*cos(angle));
float atan = atan2(twist.y,twist.x);
float spokes = sin(atan*Arms) * SpokeScale + SpokeOffset;
float spokes = (sin(atan*Arms) + SpokeOffset) * SpokeScale;
float noise = fBm(i.uv + NoisePosition.xx, 7);
float shape = lerp(spokes - EdgeReduction * length(offset), 1, pow(circle + CoreBoostOffset, CoreBoostPower) * CoreBoost);
float gal = max(shape - noise * clamp(circle,0,1), 0);
float glow = (pow(circle,GlowPower) + GlowOffset) * GlowAmount;
float stars = tex2D(_MainTex, i.uv2) * clamp(shape*StarBoost, 0, 1);
fixed4 col = fixed4(gal*_CloudColor.rgb + glow*_GlowColor.rgb + stars.xxx,1);
fixed4 col = fixed4(gal*_CloudColor.rgb + glow*_GlowColor.rgb + stars.xxx, 1);
return col;
}
ENDCG

View file

@ -1,7 +1,7 @@
# Aetheria-Economy
Economy Simulation for Aetheria
This repository is the home of Aetheria, which could be described as a sci-fi hybrid ARPG/RTS MMO about a group of corporations colonizing a hostile alien galaxy, with a satirical narrative critiquing late-stage capitalism.
The ARPG game design document is available [here](https://docs.google.com/document/d/1iULu1WsbuQoUM3c87XkGseb1P-8R5xlruoiyg03TsSE/edit?usp=sharing), while the RTS gameplay is documented [here](https://docs.google.com/document/d/1U3uGFqQboAiFJ_Y-nUOGpyixbXUHRbc5DiCuB59GM4w/edit?usp=sharing). The goal is to essentially create two games which both take place in the same persistent universe, allowing players with vastly different preferences to struggle together for the survival of mankind.
## Architecture