Tech Tree Improvements

This commit is contained in:
hyperion51 2020-04-12 11:05:36 +01:00
commit d1492eb04c
16 changed files with 616 additions and 44 deletions

View file

@ -1278,6 +1278,7 @@
<e p="TabActivator.cs" t="Include" />
<e p="TabButton.cs" t="Include" />
<e p="TabGroup.cs" t="Include" />
<e p="TechArrow.cs" t="Include" />
<e p="TechNode.cs" t="Include" />
<e p="ZoneObject.cs" t="Include" />
<e p="ZoneRenderer.cs" t="Include" />

View file

@ -524,6 +524,7 @@
<Compile Include="Assets\Scripts\UI\TabActivator.cs" />
<Compile Include="Assets\Scripts\UI\TabButton.cs" />
<Compile Include="Assets\Scripts\UI\TabGroup.cs" />
<Compile Include="Assets\Scripts\UI\TechArrow.cs" />
<Compile Include="Assets\Scripts\UI\TechNode.cs" />
<Compile Include="Assets\Scripts\UI\ZoneObject.cs" />
<Compile Include="Assets\Scripts\UI\ZoneRenderer.cs" />

View file

@ -0,0 +1,98 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 6
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: Tech Arrow
m_Shader: {fileID: 203, guid: 0000000000000000f000000000000000, type: 0}
m_ShaderKeywords:
m_LightmapFlags: 0
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _BumpMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailAlbedoMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailMask:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailNormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _EmissionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 2800000, guid: 2108d278f9e8734469689c30c590ef76, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MetallicGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _OcclusionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ParallaxMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Floats:
- _BlendOp: 0
- _BumpScale: 1
- _CameraFadingEnabled: 0
- _CameraFarFadeDistance: 2
- _CameraNearFadeDistance: 1
- _ColorMode: 0
- _Cull: 2
- _Cutoff: 0.5
- _DetailNormalMapScale: 1
- _DistortionBlend: 0.5
- _DistortionEnabled: 0
- _DistortionStrength: 1
- _DistortionStrengthScaled: 0
- _DstBlend: 0
- _EmissionEnabled: 0
- _FlipbookMode: 0
- _GlossMapScale: 1
- _Glossiness: 0.5
- _GlossyReflections: 1
- _InvFade: 1
- _LightingEnabled: 0
- _Metallic: 0
- _Mode: 0
- _OcclusionStrength: 1
- _Parallax: 0.02
- _SmoothnessTextureChannel: 0
- _SoftParticlesEnabled: 0
- _SoftParticlesFarFadeDistance: 1
- _SoftParticlesNearFadeDistance: 0
- _SpecularHighlights: 1
- _SrcBlend: 1
- _UVSec: 0
- _ZWrite: 1
m_Colors:
- _CameraFadeParams: {r: 0, g: Infinity, b: 0, a: 0}
- _Color: {r: 1, g: 1, b: 1, a: 1}
- _ColorAddSubDiff: {r: 0, g: 0, b: 0, a: 0}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _SoftParticleFadeParams: {r: 0, g: 0, b: 0, a: 0}
- _TintColor: {r: 0.09800005, g: 0.47383344, b: 1, a: 1}

View file

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 2a2ec810cb24ddb4d869e73fe8a1510a
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:

View file

@ -8,7 +8,7 @@ Material:
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: Tech Line
m_Shader: {fileID: 203, guid: 0000000000000000f000000000000000, type: 0}
m_Shader: {fileID: 200, guid: 0000000000000000f000000000000000, type: 0}
m_ShaderKeywords:
m_LightmapFlags: 0
m_EnableInstancingVariants: 0
@ -95,4 +95,4 @@ Material:
- _ColorAddSubDiff: {r: 0, g: 0, b: 0, a: 0}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _SoftParticleFadeParams: {r: 0, g: 0, b: 0, a: 0}
- _TintColor: {r: 1, g: 1, b: 1, a: 1}
- _TintColor: {r: 1, g: 1, b: 1, a: 0.5019608}

View file

@ -76,4 +76,4 @@ Material:
m_Colors:
- _Color: {r: 1, g: 1, b: 1, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _TintColor: {r: 0.5019608, g: 0.5019608, b: 0.5019608, a: 1}
- _TintColor: {r: 0.503, g: 0.503, b: 0.503, a: 1}

BIN
Assets/Resources/Sprites/Icons/Stroked/Arrow.png (Stored with Git LFS) Normal file

Binary file not shown.

View file

@ -0,0 +1,110 @@
fileFormatVersion: 2
guid: 2108d278f9e8734469689c30c590ef76
TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 9
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -100
wrapU: 1
wrapV: 1
wrapW: 1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- serializedVersion: 2
buildTarget: DefaultTexturePlatform
maxTextureSize: 64
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- serializedVersion: 2
buildTarget: Standalone
maxTextureSize: 64
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- serializedVersion: 2
buildTarget: WebGL
maxTextureSize: 64
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID: a122cda7ba7cb784c99317d4116e382d
vertices: []
indices:
edges: []
weights: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

View file

@ -10462,7 +10462,7 @@ Transform:
- {fileID: 874726172}
- {fileID: 904172349}
m_Father: {fileID: 712278634}
m_RootOrder: 1
m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &586612707
MonoBehaviour:
@ -10478,6 +10478,8 @@ MonoBehaviour:
m_EditorClassIdentifier:
Label: {fileID: 904172350}
Icon: {fileID: 874726173}
Fill: {fileID: 555365874}
Glow: {fileID: 1343232809}
--- !u!114 &586612708
MonoBehaviour:
m_ObjectHideFlags: 0
@ -13800,7 +13802,7 @@ Transform:
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 712278634}
m_RootOrder: 2
m_RootOrder: 3
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &680383218
MonoBehaviour:
@ -13877,7 +13879,7 @@ LineRenderer:
m_Curve:
- serializedVersion: 3
time: 0
value: 0.067736894
value: 0.20457771
inSlope: 0
outSlope: 0
tangentMode: 0
@ -14318,25 +14320,47 @@ MonoBehaviour:
Tech: {fileID: 586612708}
Link: {fileID: 1941419275}
RadialLink: {fileID: 1417816149}
Arrow: {fileID: 1083812776}
Algorithm: 1
TechCount: 50
SeedTechs: 5
TechCount: 1000
SeedTechs: 15
RollingWindowSize: 50
EliminateIslands: 0
DisconnectedMultiplier: 2
K: 0.25
LengthFactor: 1
Iterations: 250
Iterations: 100
LayerDistance: 1
VertexDistance: 1
VertexDistance: 0.1
WidthPerHeight: 1
PositionMode: -1
Radial: 1
MinimizeEdgeLength: 0
OptimizeWidth: 0
Sections: 360
PaddingRadians: 3.14
StartTier: 3
Scale: 1.5
StartTier: 10
Scale: 2
LinkPoints: 32
LinkDepth: 5
LinkTargetDistance: 0.75
RingDepth: 6
ArrowDepth: 3
Saturation: 0.95
HueMin: 0.5
HueMax: 1
Brightness: 1
RingInnerSaturation: 1
RingOuterSaturation: 0.25
RingInnerBrightness: 1
RingOuterBrightness: 0.1
RingColorKeys: 8
FillOpacity: 0.15
GlowOpacity: 0.6
TechFillMaterial: {fileID: 2100000, guid: c3c13ba00125fdf4c92bd96210dc7230, type: 2}
TechGlowMaterial: {fileID: 2100000, guid: 1426b25e088759647b77658321197be7, type: 2}
TechArrowMaterial: {fileID: 2100000, guid: 2a2ec810cb24ddb4d869e73fe8a1510a, type: 2}
TechLinkMaterial: {fileID: 2100000, guid: 67e23cda35beab546a57003dd2d33de1, type: 2}
--- !u!114 &712278633
MonoBehaviour:
m_ObjectHideFlags: 0
@ -14362,6 +14386,7 @@ Transform:
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children:
- {fileID: 1083812780}
- {fileID: 1941419274}
- {fileID: 586612706}
- {fileID: 680383217}
@ -21345,6 +21370,110 @@ CanvasRenderer:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1081687107}
m_CullTransparentMesh: 0
--- !u!1 &1083812775
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1083812780}
- component: {fileID: 1083812779}
- component: {fileID: 1083812778}
- component: {fileID: 1083812776}
- component: {fileID: 1083812777}
m_Layer: 0
m_Name: Arrow
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &1083812776
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1083812775}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 1281fe44325f9b548aa42dc331b17266, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!114 &1083812777
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1083812775}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: d54298fa75eb6304489e19a84af3413f, type: 3}
m_Name:
m_EditorClassIdentifier:
Icon: {fileID: 1083812778}
--- !u!23 &1083812778
MeshRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1083812775}
m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RenderingLayerMask: 1
m_RendererPriority: 0
m_Materials:
- {fileID: 2100000, guid: 2a2ec810cb24ddb4d869e73fe8a1510a, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0
m_StaticBatchRoot: {fileID: 0}
m_ProbeAnchor: {fileID: 0}
m_LightProbeVolumeOverride: {fileID: 0}
m_ScaleInLightmap: 1
m_PreserveUVs: 0
m_IgnoreNormalsForChartDetection: 0
m_ImportantGI: 0
m_StitchLightmapSeams: 0
m_SelectedEditorRenderState: 3
m_MinimumChartSize: 4
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
--- !u!33 &1083812779
MeshFilter:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1083812775}
m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0}
--- !u!4 &1083812780
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1083812775}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: -4, y: 0, z: 1}
m_LocalScale: {x: 0.66, y: 0.66, z: 1}
m_Children: []
m_Father: {fileID: 712278634}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &1084879508
GameObject:
m_ObjectHideFlags: 0
@ -28301,7 +28430,7 @@ Transform:
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 712278634}
m_RootOrder: 3
m_RootOrder: 4
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &1424588006
GameObject:
@ -36507,7 +36636,6 @@ GameObject:
- component: {fileID: 1813193644}
- component: {fileID: 1813193647}
- component: {fileID: 1813193646}
- component: {fileID: 1813193645}
m_Layer: 0
m_Name: Quad
m_TagString: Untagged
@ -36529,20 +36657,6 @@ Transform:
m_Father: {fileID: 1941419274}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!64 &1813193645
MeshCollider:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1813193643}
m_Material: {fileID: 0}
m_IsTrigger: 0
m_Enabled: 1
serializedVersion: 3
m_Convex: 0
m_CookingOptions: 14
m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0}
--- !u!23 &1813193646
MeshRenderer:
m_ObjectHideFlags: 0
@ -39878,7 +39992,7 @@ Transform:
m_Children:
- {fileID: 1813193644}
m_Father: {fileID: 712278634}
m_RootOrder: 0
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &1941419275
MonoBehaviour:

View file

@ -6,6 +6,7 @@ using System.Linq;
using UnityEngine;
using NaughtyAttributes;
using JM.LinqFaster;
using QuickGraph;
using Unity.Mathematics;
using static Unity.Mathematics.math;
using static Unity.Mathematics.noise;

View file

@ -6,6 +6,7 @@ using System.Reflection;
using System.Text.RegularExpressions;
using LiteNetLib;
using MessagePack;
using QuickGraph;
using Unity.Mathematics;
using static Unity.Mathematics.math;
using Random = Unity.Mathematics.Random;
@ -291,6 +292,42 @@ public static class ObjectExtensions
return (r2.x + r2.width >= r1.x && r2.x <= r1.x + r1.width) &&
(r2.y + r2.height >= r1.y && r2.y <= r1.y + r1.height);
}
public static IEnumerable<T> FindPath<T>(this IEnumerable<Edge<T>> data, T source, T target, Func<T, T, double> costFunction, bool bestFirst = true) where T : class
{
List<DijkstraVertex<T>> members = new List<DijkstraVertex<T>>{new DijkstraVertex<T>{Vertex = source}};
List<T> searched = new List<T>();
while (true)
{
var v = members.Where(m=>!searched.Contains(m.Vertex)).OrderBy(m=>bestFirst?m.Heuristic:m.Cost).FirstOrDefault();
if (v == null) return null; // No vertices left unsearched
if (v.Vertex == target)
{
Stack<DijkstraVertex<T>> path = new Stack<DijkstraVertex<T>>();
path.Push(v);
while(path.Peek().Parent!=null)
path.Push(path.Peek().Parent);
return path.Select(dv => dv.Vertex).ToList();
}
members.AddRange(data.Where(l => l.Source == v.Vertex).Select(l => l.Target).Concat(data.Where(l => l.Target == v.Vertex).Select(l => l.Source))
.Where(n => members.All(m => m.Vertex != n)).Select(n =>
{
var c = new DijkstraVertex<T> {Parent = v, Vertex = n, Cost = v.Cost + costFunction(v.Vertex,n)};
if (bestFirst)
c.Heuristic = c.Cost + costFunction(c.Vertex,target);
return c;
}));
searched.Add(v.Vertex);
}
}
class DijkstraVertex<T>
{
public double Cost;
public double Heuristic;
public DijkstraVertex<T> Parent;
public T Vertex;
}
}
public class ReferenceEqualityComparer : EqualityComparer<Object>

View file

@ -1,4 +1,5 @@
using System.Collections;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using GraphSharp.Algorithms.Layout;
@ -25,9 +26,15 @@ public class TechTreeTest : MonoBehaviour
public Prototype Tech;
public Prototype Link;
public Prototype RadialLink;
public Prototype Arrow;
public LayoutAlgorithm Algorithm;
public int TechCount = 50;
public int SeedTechs = 5;
public int RollingWindowSize = 50;
public bool EliminateIslands = false;
// public float MultipleDependencyProbability = .25f;
// public int MaxDependencyDistance = 4;
// public int MaxDependencyTierDifference = 2;
[Section("Kamada-Kawai")]
public float DisconnectedMultiplier;
@ -41,6 +48,8 @@ public class TechTreeTest : MonoBehaviour
public float WidthPerHeight;
public int PositionMode;
public bool Radial;
public bool MinimizeEdgeLength;
public bool OptimizeWidth;
[Section("Radial")]
public int Sections;
@ -49,11 +58,31 @@ public class TechTreeTest : MonoBehaviour
public float Scale = 1;
public int LinkPoints = 16;
public int LinkDepth = 5;
public float LinkTargetDistance = .75f;
public int RingDepth = 6;
public float ArrowDepth = 3;
[Section("Colors")]
public float Saturation = .95f;
public float HueMin = 0;
public float HueMax = 1;
public float Brightness = 1;
public float RingInnerSaturation;
public float RingOuterSaturation;
public float RingInnerBrightness;
public float RingOuterBrightness;
public int RingColorKeys;
public float FillOpacity = .25f;
public float GlowOpacity = .5f;
public Material TechFillMaterial;
public Material TechGlowMaterial;
public Material TechArrowMaterial;
public Material TechLinkMaterial;
private List<Prototype> _ringInstances = new List<Prototype>();
private List<Prototype> _techInstances = new List<Prototype>();
private List<Prototype> _linkInstances = new List<Prototype>();
private List<Prototype> _arrowInstances = new List<Prototype>();
private Texture2D[] _icons;
void Start()
@ -77,6 +106,9 @@ public class TechTreeTest : MonoBehaviour
foreach (var instance in _linkInstances) instance.ReturnToPool();
_linkInstances.Clear();
foreach (var instance in _arrowInstances) instance.ReturnToPool();
_arrowInstances.Clear();
var vertices = new List<IntVertex>();
var edges = new List<Edge<IntVertex>>();
@ -86,7 +118,7 @@ public class TechTreeTest : MonoBehaviour
{
var vertex = new IntVertex(i);
vertices.Add(vertex);
if(i>loose) edges.Add(new Edge<IntVertex>(vertices[Random.Range(0,i-1)], vertex));
if(i>loose) edges.Add(new Edge<IntVertex>(vertices[Random.Range(max(0,i-RollingWindowSize),i-1)], vertex));
}
foreach (var vertex in vertices.Where(v=>!edges.Any(e=>e.Source!=v&&e.Target!=v)))
{
@ -101,13 +133,82 @@ public class TechTreeTest : MonoBehaviour
// }
var islands = new Dictionary<IntVertex, int>();
var islandCount = graph.WeaklyConnectedComponents(islands);
if(islandCount>1)
for (int i = 1; i < islandCount; i++)
{
var i1 = islands.Where(x => x.Value == i - 1).Select(x=>x.Key).ToArray();
var i2 = islands.Where(x => x.Value == i).Select(x=>x.Key).ToArray();
edges.Add(new Edge<IntVertex>(i1[Random.Range(0,i1.Length-1)],i2[Random.Range(0,i2.Length-1)]));
}
var islandsInverse = islands
.GroupBy(i => i.Value)
.ToDictionary(
i => i.Key,
i => i.Select(g => g.Key).ToArray());
// var vertexTiers = new Dictionary<IntVertex, int>();
// foreach (var island in islandsInverse.Values)
// {
// vertexTiers[island[0]] = 0;
// foreach (var vertex in island.Skip(1))
// {
// vertexTiers[vertex] = edges.FindPath(vertex, island[0], (v1, v2) => 1).Count();
// // var tryGetPath = graph.ShortestPathsDijkstra(edge => 1, vertex);
// // if (tryGetPath(island[0], out var path))
// // {
// // vertexTiers[vertex] = path.Count();
// // }
// // else Debug.Log("Path to root not found?");
// }
// }
//
// foreach (var island in islandsInverse.Values)
// {
// foreach (var vertex in island.Skip(1))
// {
// //var tryGetPath = graph.ShortestPathsDijkstra(edge => 1, vertex);
// //var ancestors = island.Take(Array.IndexOf(island, vertex) - 1);
// var possibleDependencies = island.Where(v =>
// {
// return v != vertex &&
// vertexTiers[v] < vertexTiers[vertex] &&
// abs(vertexTiers[v] - vertexTiers[vertex]) < MaxDependencyTierDifference &&
// edges.FindPath(vertex, v, (v1, v2) => 1).Count() < MaxDependencyDistance;
// // if (v != vertex && tryGetPath(v, out var path))
// // {
// // return path.Count() > 1 && path.Count() < MaxDependencyDistance;
// // }
// //
// // return false;
// }).ToArray();
// var dependencies = new List<int>();
// while (dependencies.Count < possibleDependencies.Length && Random.value < MultipleDependencyProbability)
// {
// var depIndex = Random.Range(0, possibleDependencies.Length);
// dependencies.Add(depIndex);
// edges.Add(new Edge<IntVertex>(possibleDependencies[depIndex], vertex));
// }
// // while (Random.value < MultipleDependencyProbability)
// // {
// // var index = Array.IndexOf(island, vertex);
// // int depIndex;
// // int tries = 0;
// // do
// // {
// // depIndex = Random.Range(max(0, index - MultipleDependencyRollingWindow), index);
// // } while (tries < 10 && dependencies.Contains(depIndex));
// //
// // if (tries < 10)
// // edges.Add(new Edge<IntVertex>(island[depIndex], vertex));
// // else break;
// // }
// }
// }
if (EliminateIslands)
{
if(islandCount>1)
for (int i = 1; i < islandCount; i++)
{
var i1 = islands.Where(x => x.Value == i - 1).Select(x=>x.Key).ToArray();
var i2 = islands.Where(x => x.Value == i).Select(x=>x.Key).ToArray();
edges.Add(new Edge<IntVertex>(i1[Random.Range(0,i1.Length-1)],i2[Random.Range(0,i2.Length-1)]));
}
}
graph = edges.ToBidirectionalGraph<IntVertex,Edge<IntVertex>>();
LayoutAlgorithmBase<IntVertex, Edge<IntVertex>, BidirectionalGraph<IntVertex, Edge<IntVertex>>> layout =
@ -121,8 +222,8 @@ public class TechTreeTest : MonoBehaviour
{
EdgeRouting = SugiyamaEdgeRoutings.Traditional,
LayerDistance = LayerDistance,
MinimizeEdgeLength = true,
OptimizeWidth = true,
MinimizeEdgeLength = MinimizeEdgeLength,
OptimizeWidth = OptimizeWidth,
VertexDistance = VertexDistance,
PositionMode = PositionMode,
WidthPerHeight = WidthPerHeight
@ -147,12 +248,55 @@ public class TechTreeTest : MonoBehaviour
});
layout.Compute();
IDictionary<IntVertex, float2> positions = layout.VertexPositions;
var islandCenters = islandsInverse.ToDictionary(i => i.Key,
i => i.Value.Aggregate(float2(0, 0), (total, v) => total + positions[v]) / i.Value.Length);
Rect bounds = Rect.MinMaxRect(
layout.VertexPositions.Values.Min(v=>v.x),
layout.VertexPositions.Values.Min(v=>v.y),
layout.VertexPositions.Values.Max(v=>v.x),
layout.VertexPositions.Values.Max(v=>v.y));
var islandColors = islandCenters.ToDictionary(
i=>i.Key,
i=>Color.HSVToRGB(HueMin + (HueMax - HueMin) * Rect.PointToNormalized(bounds, i.Value).x, Saturation, Brightness));
var islandFillMaterials = islandColors.ToDictionary(i => i.Key, i =>
{
var mat = new Material(TechFillMaterial);
var col = i.Value;
col.a = FillOpacity;
mat.SetColor("_TintColor", col);
return mat;
});
var islandGlowMaterials = islandColors.ToDictionary(i => i.Key, i =>
{
var mat = new Material(TechGlowMaterial);
var col = i.Value;
col.a = GlowOpacity;
mat.SetColor("_TintColor", col);
return mat;
});
var islandArrowMaterials = islandColors.ToDictionary(i => i.Key, i =>
{
var mat = new Material(TechArrowMaterial);
var col = i.Value;
col.a = 1;
mat.SetColor("_TintColor", col);
return mat;
});
var islandLinkMaterials = islandColors.ToDictionary(i => i.Key, i =>
{
var mat = new Material(TechLinkMaterial);
var col = i.Value;
col.a = 1;
mat.SetColor("_TintColor", col);
return mat;
});
if (Algorithm == LayoutAlgorithm.Sugiyama && Radial)
{
int tiers = Mathf.RoundToInt(bounds.height / LayerDistance);
@ -177,6 +321,19 @@ public class TechTreeTest : MonoBehaviour
ring.positionCount = Sections;
ring.SetPositions(ringPositions);
var tierLerp = (float) i / (tiers / 2 - 1);
ring.colorGradient = new Gradient
{
alphaKeys = new []{new GradientAlphaKey(1,0), new GradientAlphaKey(1,1)},
colorKeys = Enumerable.Range(0,RingColorKeys).Select(x=>
{
var ringLerp = (float) x / (RingColorKeys - 1);
return new GradientColorKey(
Color.HSVToRGB(HueMin + (HueMax - HueMin) * ringLerp,
lerp(RingInnerSaturation, RingOuterSaturation, tierLerp),
lerp(RingInnerBrightness, RingOuterBrightness, tierLerp)), ringLerp);
}).ToArray()
};
_ringInstances.Add(ring.GetComponent<Prototype>());
}
@ -193,7 +350,12 @@ public class TechTreeTest : MonoBehaviour
var tech = Tech.Instantiate<TechNode>();
tech.transform.position = (Vector2) positions[vertex];
tech.Label.text = $"{vertex.N}";
var gradient = tech.Label.colorGradient;
gradient.bottomLeft = gradient.bottomRight = islandColors[islands[vertex]];
tech.Label.colorGradient = gradient;
tech.Icon.material.SetTexture("_MainTex", _icons[Random.Range(0,_icons.Length-1)]);
tech.Fill.material = islandFillMaterials[islands[vertex]];
tech.Glow.material = islandGlowMaterials[islands[vertex]];
_techInstances.Add(tech.GetComponent<Prototype>());
}
@ -202,19 +364,35 @@ public class TechTreeTest : MonoBehaviour
foreach (var edge in edges)
{
var link = RadialLink.Instantiate<LineRenderer>();
link.material = islandLinkMaterials[islands[edge.Source]];
link.positionCount = LinkPoints;
var p1r = length(positions[edge.Source]);
var p2r = length(positions[edge.Target]);
var p1a = (atan2(positions[edge.Source].y, positions[edge.Source].x) + PI * 2.5f) % (PI * 2);
var p2a = (atan2(positions[edge.Target].y, positions[edge.Target].x) + PI * 2.5f) % (PI * 2);
var p1 = float2(sin(p1a) * p1r, -cos(p1a) * p1r);
var p2 = float2(sin(p2a) * p2r, -cos(p2a) * p2r);
var dist = length(p2 - p1);
var distProp = (dist - LinkTargetDistance) / dist;
var dir = new float2();
var lastPos = new float2();
link.SetPositions(Enumerable.Range(0,LinkPoints).Select(i=>
{
var lerp = (float) i / (LinkPoints-1);
var angle = math.lerp(p1a, p2a, ease_out_quad(lerp));
var lerp = (float) i / (LinkPoints-1) * distProp;
var angle = math.lerp(p1a, p2a, (lerp));
var radius = math.lerp(p1r, p2r, lerp);
return new Vector3(sin(angle) * radius, -cos(angle) * radius, LinkDepth);
var pos = float2(sin(angle) * radius, -cos(angle) * radius);
dir = normalize(pos - lastPos);
lastPos = pos;
return (Vector3) float3(lastPos, LinkDepth);
}).ToArray());
_linkInstances.Add(link.GetComponent<Prototype>());
var arrow = Arrow.Instantiate<TechArrow>();
arrow.transform.position = new Vector3(lastPos.x, lastPos.y, ArrowDepth);
arrow.transform.rotation = Quaternion.Euler(0,0,atan2(dir.y, dir.x) * Mathf.Rad2Deg);
arrow.Icon.material = islandArrowMaterials[islands[edge.Source]];
_arrowInstances.Add(arrow.GetComponent<Prototype>());
}
}
else

View file

@ -0,0 +1,8 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TechArrow : MonoBehaviour
{
public MeshRenderer Icon;
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d54298fa75eb6304489e19a84af3413f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -7,4 +7,6 @@ public class TechNode : MonoBehaviour
{
public TextMeshPro Label;
public MeshRenderer Icon;
public MeshRenderer Fill;
public MeshRenderer Glow;
}

View file

@ -1,5 +1,5 @@
# Aetheria
This repository is the home of Aetheria, 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.
This repository is the home of Aetheria, an economy focused RTS MMO where you control the production, research, supply chains and actions of a corporation tasked with colonizing an alien galaxy. Control over your minions is indirect, like in Rimworld, and gameplay takes place over months as your production and tasks continue acting on the world even when you're offline.
<img src="https://i.ibb.co/XxvYPfH/Unity-nr8ih-BUJ75.jpg" style="zoom:50%;" /> <img src="https://i.ibb.co/Twbwk4M/screen-3056x1720-2018-11-18-18-23-01.png" style="zoom:50%;" />