Skip to content

Instantly share code, notes, and snippets.

@kurtdekker
Created March 2, 2022 15:49
Show Gist options
  • Save kurtdekker/efceb3fa007613be5494e51b4f6800c5 to your computer and use it in GitHub Desktop.
Save kurtdekker/efceb3fa007613be5494e51b4f6800c5 to your computer and use it in GitHub Desktop.
Simple star castle style rotating fortress generation
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