Skip to content

Instantly share code, notes, and snippets.

@LoganBarnett
Created March 19, 2013 06:23
Show Gist options
  • Select an option

  • Save LoganBarnett/5194081 to your computer and use it in GitHub Desktop.

Select an option

Save LoganBarnett/5194081 to your computer and use it in GitHub Desktop.
Background star creator for Roid Miner game. 1 Draw call, 0 texture memory.
using UnityEngine;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using GoodStuff.NaturalLanguage;
public class BackgroundSpawner : MonoBehaviour {
public int seed = 1;
public float starDensityThreshold = 1f;
public float starCreationMaxCutoff = 0.5f;
public int sampleX = 10;
public int sampleY = 10;
public float nebulaThreshold = 1000f;
public float starThreshold = 0.5f;
public float starPointMinRadius = 1f;
public float starPointMaxRadius = 3f;
public int starMinPoints = 4;
public int starMaxPoints = 8;
public List<Color> starColors;
public Material starMaterial;
public int numberOfStars = 1000;
public float starDensity = 1f;
int originalSeed;
int originalSampleX;
int originalSampleY;
float originalNebulaThreshold;
float originalStarThreshold;
float originalStarPointMinRadius;
float originalStarPointMaxRadius;
int originalStarMinPoints;
int originalStarMaxPoints;
float originalStarDensityThreshold;
float originalStarCreationMaxCutoff;
List<Color> originalStarColors = new List<Color>();
int originalNumberOfStars;
float originalStarDensity;
GameObject background;
bool BackgroundPropertiesChanged {
get {
if(!Application.isEditor) return false; // just for editing
var colorIndex = 0;
var colorsDifferent = originalStarColors.Any(c => c != starColors[colorIndex++]);
return originalSeed != seed ||
originalSampleX != sampleX ||
originalSampleY != sampleY ||
originalNebulaThreshold != nebulaThreshold ||
originalStarThreshold != starThreshold ||
originalStarPointMinRadius != starPointMinRadius ||
originalStarPointMaxRadius != starPointMaxRadius ||
originalStarMinPoints != starMinPoints ||
originalStarMaxPoints != starMaxPoints ||
originalStarDensityThreshold != starDensityThreshold ||
originalStarCreationMaxCutoff != starCreationMaxCutoff ||
// originalStarColors != starColors ||
originalNumberOfStars != numberOfStars ||
originalStarDensity != starDensity ||
colorsDifferent;
}
}
void Start() {
CreateBackground();
StoreBackgroundProperties();
}
void Update() {
if(BackgroundPropertiesChanged) {
CreateBackground();
StoreBackgroundProperties();
}
}
void StoreBackgroundProperties() {
originalSeed = seed;
originalSampleX = sampleX;
originalSampleY = sampleY;
originalNebulaThreshold = nebulaThreshold;
originalStarThreshold = starThreshold;
originalStarPointMinRadius = starPointMinRadius;
originalStarPointMaxRadius = starPointMaxRadius;
originalStarMinPoints = starMinPoints;
originalStarMaxPoints = starMaxPoints;
originalStarDensityThreshold = starDensityThreshold;
originalStarCreationMaxCutoff = starCreationMaxCutoff;
originalStarColors.Clear();
originalStarColors.AddRange(starColors);
originalNumberOfStars = numberOfStars;
originalStarDensity = starDensity;
}
void CreateBackground() {
if(background != null) Destroy(background);
background = new GameObject("Background");
background.layer = LayerMask.NameToLayer("Background");
var starGameObject = new GameObject("Stars", typeof(MeshFilter), typeof(MeshRenderer));
starGameObject.layer = LayerMask.NameToLayer("Background");
starGameObject.transform.parent = background.transform;
starGameObject.transform.localPosition = new Vector3(-sampleX / 2f, 0f, -sampleY / 2f);
starGameObject.renderer.material = starMaterial;
var starMeshData = new MeshData();
var perlin = new Perlin(seed);
Random.seed = seed;
0.UpTo(numberOfStars, i => {
var x = Random.Range(0f, (float)sampleX);
var y = Random.Range(0f, (float)sampleY);
var noise = perlin.Noise(x / (float)sampleX, y / (float)sampleY);
CreateStar(starMeshData, x * starDensity, y * starDensity, noise);
});
// 0.UpTo(sampleX, x => {
// 0.UpTo(sampleY, y => {
// var noise = perlin.Noise((float)x / (float)sampleX, (float)y / (float)sampleY);
// if(noise > nebulaThreshold) {
// CreateNebula(x, y);
// }
// //noise > starThreshold &&
// else if(Random.Range(0f, starCreationMaxCutoff) < Mathf.Abs(noise) + starDensityThreshold) {
//
// CreateStar(starMeshData, x, y, noise);
// }
// });
// });
var starMeshFilter = starGameObject.GetComponent<MeshFilter>();
starMeshFilter.mesh.Clear();
starMeshFilter.mesh.vertices = starMeshData.vertices.ToArray();
starMeshFilter.mesh.triangles = starMeshData.triangles.ToArray();
starMeshFilter.mesh.colors = starMeshData.colors.ToArray();
starMeshFilter.mesh.RecalculateNormals();
}
void CreateStar(MeshData meshData, float x, float y, float noise) {
// how many points on this star
var points = Random.Range(starMinPoints, starMaxPoints);
var vertexes = new List<Vector3>();
vertexes.Add(Vector3.zero); // center point
var triangles = new List<int>();
0.UpTo(points, p => {
var theta = Mathf.PI * 2 * p / (points);
var pointY = Mathf.Sin(theta);
var pointX = Mathf.Cos(theta);
var point = new Vector3(pointX, 0f, pointY);
vertexes.Add(point);
triangles.Add(meshData.vertices.Count() + 0);
triangles.Add(meshData.vertices.Count() + p + 1);
triangles.Add(meshData.vertices.Count() + p);
});
// triangles.Add(0);
// triangles.Add(1);
// triangles.Add(points);
// var randomLength = Random.Range(starPointMinRadius, starPointMaxRadius);
// var semiRandomOffset = Vector3.one * noise;
// Debug.Log(semiRandomOffset);
meshData.vertices.AddRange(vertexes.Select(v => (v * starPointMaxRadius * noise) + new Vector3(x, noise * x * y * 0.001f, y)));
meshData.triangles.AddRange(triangles);
var innerColor = starColors[Random.Range(0, starColors.Count() -1)];
var outerColor = starColors[Random.Range(0, starColors.Count() -1)];
outerColor.a = 0f;
var colors = new List<Color>();
colors.Add(innerColor);
colors.AddRange(Enumerable.Range(0, points + 1).Select(unused => outerColor));
meshData.colors.AddRange(colors);
}
void CreateNebula(int x, int y) {
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment