Created
March 2, 2022 15:49
-
-
Save kurtdekker/efceb3fa007613be5494e51b4f6800c5 to your computer and use it in GitHub Desktop.
Simple star castle style rotating fortress generation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections; | |
using System.Collections.Generic; | |
using UnityEngine; | |
// @kurtdekker | |
// | |
// to use, just drop this onto a blank GameObject located where you want the rings | |
public class StarCastle : MonoBehaviour | |
{ | |
// structure of a given ring | |
public class RingDef | |
{ | |
public float radius; | |
public int segments; | |
} | |
// how to stand up the cubes | |
public class CubeDef | |
{ | |
// as a fraction of segment length - negative is gapped | |
public float overlap; | |
// inwards-outwards thickness | |
public float thickness; | |
// overall "height" of the walls | |
public float height; | |
} | |
GameObject MakeWithCubes( Vector3 pos, RingDef[] rings, CubeDef cubeDef) | |
{ | |
Transform parent = new GameObject("MakeWithCubes();").transform; | |
foreach ( var ring in rings) | |
{ | |
Transform ringParent = new GameObject( "Ring").transform; | |
ringParent.transform.SetParent( parent); | |
float circumference = ring.radius * 2 * Mathf.PI; | |
float segmentLength = circumference / ring.segments; | |
segmentLength += segmentLength * cubeDef.overlap; | |
for( int segment = 0; segment < ring.segments; segment++) | |
{ | |
float angle = (360.0f * segment) / ring.segments; | |
Quaternion rotation = Quaternion.Euler( 0, 0, angle); | |
GameObject chunk = GameObject.CreatePrimitive( PrimitiveType.Cube); | |
chunk.transform.SetParent( ringParent); | |
chunk.transform.localScale = new Vector3( segmentLength, cubeDef.thickness, cubeDef.height); | |
Vector3 segmentPosition = Vector3.up * ring.radius; | |
segmentPosition = rotation * segmentPosition; | |
chunk.transform.position = segmentPosition; | |
chunk.transform.localRotation = rotation; | |
} | |
} | |
parent.transform.position = pos; | |
return parent.gameObject; | |
} | |
// demo it all out | |
IEnumerator Start () | |
{ | |
// some arbitrary rings | |
RingDef ring1 = new RingDef() { radius = 1.0f, segments = 10 }; | |
RingDef ring2 = new RingDef() { radius = 1.2f, segments = 12 }; | |
RingDef ring3 = new RingDef() { radius = 1.4f, segments = 16 }; | |
RingDef[] AllRings = new RingDef[] { ring1, ring2, ring3}; | |
// some arbitrary presentation | |
CubeDef cubeDef = new CubeDef() { | |
overlap = 0.1f, | |
thickness = 0.05f, | |
height = 0.5f, | |
}; | |
// make it! | |
GameObject Castle = MakeWithCubes(transform.position, AllRings, cubeDef); | |
const float RateOfRotationBase = 90; | |
const float ExtraRotation = 30; | |
float age = 0; | |
// spin it!! | |
while(true) | |
{ | |
age += Time.deltaTime; | |
// using knowledge that the immediate children are rotate-able | |
for (int i = 0; i < Castle.transform.childCount; i++) | |
{ | |
Transform pivot = Castle.transform.GetChild(i); | |
float angle = RateOfRotationBase + i * ExtraRotation; | |
angle *= age; | |
// every other ring opposite direction | |
angle *= ( (i & 1) == 0) ? -1 : 1; | |
pivot.localRotation = Quaternion.Euler( 0, 0, angle); | |
} | |
yield return null; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment