122 lines
5.3 KiB
C#
122 lines
5.3 KiB
C#
using System.Collections.Generic;
|
|||
|
|
using UnityEngine;
|
||
|
|
|
||
|
|
namespace Ironspore
|
||
|
|
{
|
||
|
|
public static class WorldFactory
|
||
|
|
{
|
||
|
|
static readonly Dictionary<string, Material> materials = new Dictionary<string, Material>();
|
||
|
|
public static Material Material(Color color, bool glow = false)
|
||
|
|
{
|
||
|
|
string key = ColorUtility.ToHtmlStringRGB(color) + (glow ? "g" : "");
|
||
|
|
if (materials.TryGetValue(key, out var cached) && cached)
|
||
|
|
return cached;
|
||
|
|
var mat = new Material(Shader.Find("Standard"));
|
||
|
|
mat.color = color;
|
||
|
|
mat.SetFloat("_Metallic", .3f);
|
||
|
|
mat.SetFloat("_Glossiness", .35f);
|
||
|
|
if (glow)
|
||
|
|
{
|
||
|
|
mat.EnableKeyword("_EMISSION");
|
||
|
|
mat.SetColor("_EmissionColor", color * 1.8f);
|
||
|
|
}
|
||
|
|
materials[key] = mat;
|
||
|
|
return mat;
|
||
|
|
}
|
||
|
|
public static GameObject Box(string name, Vector3 position, Vector3 scale, Color color, Transform parent, bool collision = true, bool glow = false)
|
||
|
|
{
|
||
|
|
return Primitive(PrimitiveType.Cube, name, position, scale, color, parent, collision, glow);
|
||
|
|
}
|
||
|
|
public static GameObject Cylinder(string name, Vector3 position, Vector3 scale, Color color, Transform parent, bool collision = true)
|
||
|
|
{
|
||
|
|
return Primitive(PrimitiveType.Cylinder, name, position, scale, color, parent, collision, false);
|
||
|
|
}
|
||
|
|
public static GameObject Primitive(PrimitiveType type, string name, Vector3 position, Vector3 scale, Color color, Transform parent, bool collision, bool glow)
|
||
|
|
{
|
||
|
|
var obj = GameObject.CreatePrimitive(type);
|
||
|
|
obj.name = name;
|
||
|
|
obj.transform.SetParent(parent);
|
||
|
|
obj.transform.position = position;
|
||
|
|
obj.transform.localScale = scale;
|
||
|
|
obj.GetComponent<Renderer>().sharedMaterial = Material(color, glow);
|
||
|
|
if (!collision)
|
||
|
|
Object.Destroy(obj.GetComponent<Collider>());
|
||
|
|
return obj;
|
||
|
|
}
|
||
|
|
public static GameObject Cockpit(Transform camera)
|
||
|
|
{
|
||
|
|
var root = new GameObject("CockpitFrame");
|
||
|
|
root.transform.SetParent(camera, false);
|
||
|
|
foreach (int side in new[] { -1, 1 })
|
||
|
|
{
|
||
|
|
var frame = Box("CanopyRail", Vector3.zero, new Vector3(.045f, .8f, .06f), new Color(.08f, .16f, .19f), root.transform, false);
|
||
|
|
frame.transform.localPosition = new Vector3(side * .48f, -.05f, .7f);
|
||
|
|
frame.transform.localRotation = Quaternion.Euler(0, 0, side * -12);
|
||
|
|
var indicator = Box("CanopyIndicator", Vector3.zero, new Vector3(.018f, .27f, .065f), new Color(.05f, .9f, .75f), root.transform, false, true);
|
||
|
|
indicator.transform.localPosition = new Vector3(side * .48f, -.15f, .66f);
|
||
|
|
}
|
||
|
|
var dashboard = Box("Dashboard", Vector3.zero, new Vector3(1.3f, .14f, .2f), new Color(.07f, .13f, .16f), root.transform, false);
|
||
|
|
dashboard.transform.localPosition = new Vector3(0, -.42f, .75f);
|
||
|
|
foreach (var child in root.GetComponentsInChildren<Transform>())
|
||
|
|
child.gameObject.layer = 8;
|
||
|
|
root.SetActive(false);
|
||
|
|
return root;
|
||
|
|
}
|
||
|
|
public static void Label(string key, Vector3 position, Color color, Transform parent)
|
||
|
|
{
|
||
|
|
var obj = new GameObject("Sign");
|
||
|
|
obj.transform.SetParent(parent);
|
||
|
|
obj.transform.position = position;
|
||
|
|
var label = obj.AddComponent<TextMesh>();
|
||
|
|
label.fontSize = 40;
|
||
|
|
label.characterSize = .09f;
|
||
|
|
label.anchor = TextAnchor.MiddleCenter;
|
||
|
|
label.color = color;
|
||
|
|
obj.AddComponent<LocalizedWorldLabel>().Initialize(key);
|
||
|
|
obj.AddComponent<FaceCamera>();
|
||
|
|
}
|
||
|
|
public static void Tracer(Vector3 from, Vector3 to, Color color)
|
||
|
|
{
|
||
|
|
var obj = new GameObject("ShotTrace");
|
||
|
|
var line = obj.AddComponent<LineRenderer>();
|
||
|
|
line.positionCount = 2;
|
||
|
|
line.SetPosition(0, from);
|
||
|
|
line.SetPosition(1, to);
|
||
|
|
line.startWidth = .045f;
|
||
|
|
line.endWidth = .015f;
|
||
|
|
line.sharedMaterial = Material(color, true);
|
||
|
|
Object.Destroy(obj, .07f);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
public sealed class FaceCamera : MonoBehaviour
|
||
|
|
{
|
||
|
|
void LateUpdate()
|
||
|
|
{
|
||
|
|
var c = Camera.main;
|
||
|
|
if (!c)
|
||
|
|
c = Object.FindAnyObjectByType<Camera>();
|
||
|
|
if (c)
|
||
|
|
transform.rotation = c.transform.rotation;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
public static class GameAudio
|
||
|
|
{
|
||
|
|
public static void Cue(float frequency, float length, float volume = .12f)
|
||
|
|
{
|
||
|
|
int count = (int)(22050 * length);
|
||
|
|
var data = new float[count];
|
||
|
|
for (int i = 0; i < count; i++)
|
||
|
|
{
|
||
|
|
float t = i / 22050f;
|
||
|
|
data[i] = Mathf.Sin(t * frequency * Mathf.PI * 2) * Mathf.Exp(-t / length * 6);
|
||
|
|
}
|
||
|
|
var clip = AudioClip.Create("SynthCue", count, 1, 22050, false);
|
||
|
|
clip.SetData(data, 0);
|
||
|
|
var camera = Object.FindAnyObjectByType<AudioListener>();
|
||
|
|
if (camera)
|
||
|
|
AudioSource.PlayClipAtPoint(clip, camera.transform.position, volume);
|
||
|
|
Object.Destroy(clip, length + 1);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|