This commit is contained in:
ntr committed 2023-07-10 00:23:48 +10:00
1 parent d49bafd535
commit 62a8de8b86
99 files changed
+5837 -673

No files matched your search

+40
View File
@@ -0,0 +1,40 @@
using UnityEngine;
using System.Collections;
public class DebugLogPanel : MonoBehaviour
{
uint qsize = 15; // number of messages to keep
Queue myLogQueue = new Queue();
void Start() {
Debug.Log("SpaceRace!");
Debug.Log("WSAD - Strafe");
Debug.Log("Mouse 1 - Thrust");
Debug.Log("Mouse 2 - Decelerate");
Debug.Log("Space - Respawn");
Debug.Log("F10 - Exit");
}
void OnEnable() {
Application.logMessageReceived += HandleLog;
}
void OnDisable() {
Application.logMessageReceived -= HandleLog;
}
void HandleLog(string logString, string stackTrace, LogType type) {
// myLogQueue.Enqueue("[" + type + "] : " + logString);
myLogQueue.Enqueue(logString);
if (type == LogType.Exception)
myLogQueue.Enqueue(stackTrace);
while (myLogQueue.Count > qsize)
myLogQueue.Dequeue();
}
void OnGUI() {
GUILayout.BeginArea(new Rect(0, 0, 400, Screen.height));
GUILayout.Label("\n" + string.Join("\n", myLogQueue.ToArray()));
GUILayout.EndArea();
}
}
+11
View File
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 13ee45edf9a5f1c6789b5ce48c7ee4a3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+5
View File
@@ -0,0 +1,5 @@
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" editor-extension-mode="False">
<Style src="ShipUi.uss" />
<ui:VisualElement name="lap-time-entry">
</ui:VisualElement>
</ui:UXML>
+10
View File
@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: c0634235ba7ac8c449247dcb52927cd6
ScriptedImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 2
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 13804, guid: 0000000000000000e000000000000000, type: 0}
+126
View File
@@ -0,0 +1,126 @@
using Unity.Collections;
using UnityEngine;
using UnityEngine.UIElements;
namespace SpaceRaceUi
{
// An element that displays progress inside a partially filled circle
public class RadialProgress : VisualElement
{
public new class UxmlTraits : VisualElement.UxmlTraits
{
// The progress property is exposed to UXML.
UxmlFloatAttributeDescription m_ProgressAttribute = new UxmlFloatAttributeDescription()
{
name = "progress"
};
// Use the Init method to assign the value of the progress UXML attribute to the C# progress property.
public override void Init(VisualElement ve, IUxmlAttributes bag, CreationContext cc)
{
base.Init(ve, bag, cc);
(ve as RadialProgress).progress = m_ProgressAttribute.GetValueFromBag(bag, cc);
}
}
// Define a factory class to expose this control to UXML.
public new class UxmlFactory : UxmlFactory<RadialProgress, UxmlTraits> { }
// These are USS class names for the control overall and the label.
public static readonly string ussClassName = "radial-progress";
public static readonly string ussLabelClassName = "radial-progress__label";
// These objects allow C# code to access custom USS properties.
static CustomStyleProperty<Color> s_TrackColor = new CustomStyleProperty<Color>("--track-color");
static CustomStyleProperty<Color> s_ProgressColor = new CustomStyleProperty<Color>("--progress-color");
Color m_TrackColor = Color.gray;
Color m_ProgressColor = Color.red;
// This is the label that displays the percentage.
Label m_Label;
// This is the number that the Label displays as a percentage.
float m_Progress;
// A value between 0 and 100
public float progress
{
// The progress property is exposed in C#.
get => m_Progress;
set
{
// Whenever the progress property changes, MarkDirtyRepaint() is named. This causes a call to the
// generateVisualContents callback.
m_Progress = value;
m_Label.text = Mathf.Clamp(Mathf.Round(value), 0, 100) + "%";
MarkDirtyRepaint();
}
}
// This default constructor is RadialProgress's only constructor.
public RadialProgress()
{
// Create a Label, add a USS class name, and add it to this visual tree.
m_Label = new Label();
m_Label.AddToClassList(ussLabelClassName);
Add(m_Label);
// Add the USS class name for the overall control.
AddToClassList(ussClassName);
// Register a callback after custom style resolution.
RegisterCallback<CustomStyleResolvedEvent>(evt => CustomStylesResolved(evt));
// Register a callback to generate the visual content of the control.
generateVisualContent += GenerateVisualContent;
progress = 0.0f;
}
static void CustomStylesResolved(CustomStyleResolvedEvent evt)
{
RadialProgress element = (RadialProgress)evt.currentTarget;
element.UpdateCustomStyles();
}
// After the custom colors are resolved, this method uses them to color the meshes and (if necessary) repaint
// the control.
void UpdateCustomStyles()
{
bool repaint = false;
if (customStyle.TryGetValue(s_ProgressColor, out m_ProgressColor))
repaint = true;
if (customStyle.TryGetValue(s_TrackColor, out m_TrackColor))
repaint = true;
if (repaint)
MarkDirtyRepaint();
}
void GenerateVisualContent(MeshGenerationContext context)
{
float width = contentRect.width;
float height = contentRect.height;
var painter = context.painter2D;
painter.lineWidth = 10.0f;
painter.lineCap = LineCap.Butt;
// Draw the track
painter.strokeColor = m_TrackColor;
painter.BeginPath();
painter.Arc(new Vector2(width * 0.5f, height * 0.5f), width * 0.5f, 0.0f, 360.0f);
painter.Stroke();
// Draw the progress
painter.strokeColor = m_ProgressColor;
painter.BeginPath();
painter.Arc(new Vector2(width * 0.5f, height * 0.5f), width * 0.5f, -90.0f, 360.0f * (progress / 100.0f) - 90.0f);
painter.Stroke();
}
}
}
+11
View File
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: cb873ce7764a21f6ba132e26f404f428
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+20
View File
@@ -0,0 +1,20 @@
.radial-progress {
min-width: 26px;
min-height: 20px;
--track-color: rgb(130, 130, 130);
--progress-color: rgb(46, 132, 24);
--percentage-color: white;
margin-left: 5px;
margin-right: 5px;
margin-top: 5px;
margin-bottom: 5px;
flex-direction: row;
justify-content: center;
width: 100px;
height: 100px;
}
.radial-progress__label {
-unity-text-align: middle-left;
color: var(--percentage-color);
}
+11
View File
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 22ecc27ec3f77ed128879fe6aa00c469
ScriptedImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 2
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 12385, guid: 0000000000000000e000000000000000, type: 0}
disableValidation: 0
+12
View File
@@ -0,0 +1,12 @@
// using System.Collections;
// using System.Collections.Generic;
// using UnityEngine;
// public class RemoveComponentName : MonoBehaviour {
// public void RemoveComponents() {
// MeshRenderer[] meshes = GetComponentsInChildren<MeshRenderer>();
// foreach (MeshRenderer c in meshes) {
// DestroyImmediate(c, true);
// }
// }
// }
+11
View File
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 972bb8f02cd29a544b2ccd68181fa8c7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+17
View File
@@ -0,0 +1,17 @@
// using System.Collections;
// using System.Collections.Generic;
// using UnityEngine;
// using UnityEditor;
// [CustomEditor (typeof (RemoveComponentName))]
// public class RemoveComponentNameEditor : Editor {
// public override void OnInspectorGUI () {
// DrawDefaultInspector ();
// RemoveComponentName rmc = (RemoveComponentName) target;
// if (GUILayout.Button ("Remove ComponentName")) {
// rmc.RemoveComponents ();
// }
// }
// }
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 31c90ce24336b0223aec0a24fc93d896
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+14
View File
@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using UnityEngine;
public class Sector: MonoBehaviour {
public int sector;
public Timing timing;
void OnTriggerEnter(Collider other) {
Debug.Log("Hit sector " + sector);
timing.NextSector(sector);
}
}
+11
View File
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a6214f498273bf702b0ad56b756b4e93
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+181
View File
@@ -0,0 +1,181 @@
using UnityEngine;
public class ShipControls : MonoBehaviour {
public Camera aim;
public Timing timing;
Rigidbody rigidBody;
Vector3 initialPosition;
Vector3 initialForce;
Quaternion initialAim;
Vector3 thrust;
Vector3 strafe;
float strafeMag;
float thrustMag;
float stabliseMag;
ForceMode forceMode;
// Camera Controls
float mouseSenseY = 1.0f;
float mouseSenseX = 1.0f;
float camPitch;
float camYaw;
void Start() {
Cursor.lockState = CursorLockMode.Locked;
rigidBody = GetComponent<Rigidbody>();
// just stop the body from being affected by rotation for now
// until the 3p camera is in to explain why
rigidBody.freezeRotation = true;
initialPosition = rigidBody.transform.position;
initialAim = aim.transform.rotation;
initialForce = Vector3.forward;
thrust = Vector3.zero;
strafe = Vector3.zero;
thrustMag = 50.0f;
strafeMag = 25.0f;
stabliseMag = 75.0f;
camPitch = initialAim.eulerAngles.x;
camYaw = initialAim.eulerAngles.y;
forceMode = ForceMode.Acceleration;
}
void Update() {
// update the movement vectors every frame
thrust = getThrust();
strafe = getStrafe();
// do everything else input related on every frame too
processInput();
}
void FixedUpdate() {
// when you hit the trigger...
// GO
// needs to be done here in fixedUpdate because otherwise the input is checked on every frame
// so they will have already hit the button before this tick
bool shouldStartTimer = !timing.timerEnabled && (thrust != Vector3.zero || strafe != Vector3.zero);
if (shouldStartTimer)
timing.StartTimer();
// the ship being propelled forward
rigidBody.AddForce(thrust, forceMode);
// moving side to side
rigidBody.AddRelativeForce(strafe, forceMode);
// rotating towards the camera's orientation
// not being done by a force because of strange behaviour
// needs investigation
float step = stabliseMag * Time.fixedDeltaTime;
rigidBody.rotation = Quaternion.RotateTowards(transform.rotation, aim.transform.rotation, step);
}
Vector3 getThrust() {
// thrust in the direction of the camera
if (Input.GetMouseButton(0))
// transform from the camera's forward vector into world space
return aim.transform.TransformDirection(Vector3.forward) * thrustMag;
// brake just decelerates the ship against the direction it is moving
if (Input.GetMouseButton(1)) {
// the velocity is already in world space so we just invert it
return rigidBody.velocity.normalized * -1f * thrustMag;
}
return Vector3.zero;
}
// 2D strafing
// we combine all the vectors so you can move in 2 dimensions at once
// thrust is added as a relative force so we don't need to convert to worldspace
Vector3 getStrafe() {
Vector3 strafe = new Vector3(0.0f, 0.0f, 0.0f);
if (Input.GetKey(KeyCode.W))
strafe += strafeMag * Vector3.up;
if (Input.GetKey(KeyCode.S))
strafe += strafeMag * Vector3.down;
if (Input.GetKey(KeyCode.A))
strafe += strafeMag * Vector3.left;
if (Input.GetKey(KeyCode.D))
strafe += strafeMag * Vector3.right;
return strafe;
}
void processInput() {
updateCamera();
// don't just spam respawn
if (Input.GetKeyDown(KeyCode.Space))
Respawn();
if (Input.GetKey(KeyCode.F10))
Application.Quit();
}
public void Respawn() {
// IMPORTANT
// stop the timer before we move the ship or anything
// otherwise it might generate a checkpoint time
// for the final sector
timing.StopTimer();
thrust = new Vector3(0.0f, 0.0f, 0.0f);
transform.position = initialPosition;
rigidBody.transform.forward = initialForce;
rigidBody.velocity = new Vector3(0f, 0f, 0f);
rigidBody.angularVelocity = new Vector3(0f, 0f, 0f);
aim.transform.rotation = initialAim;
camPitch = initialAim.eulerAngles.x;
camYaw = initialAim.eulerAngles.y;
}
void updateCamera() {
camPitch -= mouseSenseY * Input.GetAxis("Mouse Y");
camYaw += mouseSenseX * Input.GetAxis("Mouse X");
aim.transform.eulerAngles = new Vector3(camPitch, camYaw, 0.0f);
}
void OnDrawGizmosSelected() {
if (Application.isPlaying == false)
return;
Gizmos.color = Color.red;
Vector3 right = aim.transform.TransformDirection(Vector3.right) * 10;
Gizmos.DrawRay(transform.position, right);
Gizmos.color = Color.green;
Vector3 direction = aim.transform.TransformDirection(Vector3.up) * 10;
Gizmos.DrawRay(transform.position, direction);
Gizmos.color = Color.blue;
Vector3 forward = aim.transform.TransformDirection(Vector3.forward) * 10;
Gizmos.DrawRay(transform.position, forward);
Gizmos.color = Color.yellow;
Vector3 velocity = rigidBody.velocity;
Gizmos.DrawRay(transform.position, velocity);
Gizmos.color = Color.cyan;
Gizmos.DrawRay(transform.position, thrust);
}
public float Speed() {
return rigidBody.velocity.magnitude;
}
}
+11
View File
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 40716ff800be8d74ead775a18a496d89
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+46
View File
@@ -0,0 +1,46 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;
public class ShipUi : MonoBehaviour {
[SerializeField]
UIDocument uiDocument = null;
[SerializeField]
ShipControls ship;
[SerializeField]
Timing timing;
Label speed;
Label timer;
Label sectors;
VisualElement timeSheet;
void OnEnable() {
speed = uiDocument.rootVisualElement.Q<Label>("speed");
timer = uiDocument.rootVisualElement.Q<Label>("timer");
sectors = uiDocument.rootVisualElement.Q<Label>("sectors");
timeSheet = uiDocument.rootVisualElement.Q<VisualElement>("timeSheet");
}
void FixedUpdate() {
timer.text = $"{timing.sectorTime:0.0}";
speed.text = $"{ship.Speed():0}";
UpdateTimesheet();
}
public void UpdateTimesheet() {
timeSheet.Clear();
foreach (Lap lap in timing.lapTimes) {
Label l = new Label();
l.text = $"{lap}";
timeSheet.Add(l);
}
sectors.text = $"{String.Join(" ", timing.sectorTimes)}";
}
}
+11
View File
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 14d590d5e541e871cb4b472e9e009128
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+21
View File
@@ -0,0 +1,21 @@
#shipUi {
color: white;
font-size: 21px;
}
#list-entry {
height: 41px;
align-items: flex-start;
justify-content: center;
padding-left: 10px;
background-color: rgb(170, 89, 57);
border-color: rgb(49, 26, 17);
border-width: 2px;
border-radius: 15px;
}
#character-name {
-unity-font-style: bold;
font-size: 18px;
color: rgb(49, 26, 17);
}
+11
View File
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: cf92f075876ddf7ffb4cd5c59633ad7b
ScriptedImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 2
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 12385, guid: 0000000000000000e000000000000000, type: 0}
disableValidation: 0
+14
View File
@@ -0,0 +1,14 @@
using UnityEngine;
public enum ECharacterClass
{
Knight, Ranger, Wizard
}
[CreateAssetMenu] //This adds an entry to the **Create** menu
public class SpaceRaceData : ScriptableObject
{
public string CharacterName;
public ECharacterClass Class;
public Sprite PortraitImage;
}
+11
View File
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a26008ff8e485e4bd828df4ce68be09a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+130
View File
@@ -0,0 +1,130 @@
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEditor;
public readonly struct SectorTime {
public SectorTime(int i, double t) {
Sector = i;
Value = t;
}
public int Sector { get; }
public double Value { get; }
public override string ToString() => $"{Sector} {Value:0.000}";
}
public readonly struct Lap {
public Lap(int i, List<SectorTime> s) {
Sectors = s;
Number = i;
}
public int Number { get; }
public List<SectorTime> Sectors { get; }
public override string ToString() {
return $"Lap {Number} : {TotalTime():0.000} {String.Join(" ", Sectors.ConvertAll(s => s.ToString()))}";
}
double TotalTime() {
return Sectors.Sum(s => s.Value);
}
}
public class Timing: MonoBehaviour {
[SerializeField]
public List<Lap> lapTimes;
[SerializeField]
public List<SectorTime> sectorTimes;
public bool timerEnabled;
public double sectorTime;
double sectorStart;
Sector[] sectors;
void Awake() {
lapTimes = new List<Lap>();
sectorTimes = new List<SectorTime>();
sectorStart = 0.0;
sectorTime = 0.0;
sectors = GetComponentsInChildren<Sector>();
Debug.Log("Track Sector Count - " + sectors.Length);
}
void Update() {
if (timerEnabled)
sectorTime = Time.timeAsDouble - sectorStart;
}
public void StartTimer() {
if (sectors.Length == 0) {
Debug.LogWarning("No Sectors found in timing");
return;
}
Debug.Log("Started Timer");
timerEnabled = true;
sectorStart = Time.timeAsDouble;
}
public void StopTimer() {
sectorTimes = new List<SectorTime>();
timerEnabled = false;
sectorTime = 0;
Debug.Log("Timer Stopped");
EndLap();
}
public void NextSector(int sector) {
if (!timerEnabled)
return;
// they turned around or somethin?
if (sectorTimes.Any(s => s.Sector == sector))
return;
// this basically makes sure the timer doesn't do anything weird
// due to respawns, driving in the wrong direction etc
// you have to hit the sectors in numbered order
// ---------------
// make sure sectors are only accessible by being hit by following
// the track correctly!
if (sector != sectorTimes.Count + 1)
return;
double sTime = Time.timeAsDouble - sectorStart;
SectorTime s = new SectorTime(sector, sTime);
sectorTimes.Add(s);
if (sectorTimes.Count == sectors.Length) {
EndLap();
NextLap();
}
}
void NextLap() {
Debug.Log("NextLap" + lapTimes.Count);
sectorTimes = new List<SectorTime>();
StartTimer();
}
public void EndLap() {
// when live reloading this happens
if (sectorTimes == null)
Awake();
if (sectorTimes.Count > 0) {
Lap l = new Lap(lapTimes.Count, sectorTimes);
Debug.Log($"EndLap {l}");
lapTimes.Add(l);
}
}
}
+11
View File
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 385acf04d40a396a9a95f738b7353198
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+34
View File
@@ -0,0 +1,34 @@
using UnityEngine;
public class TrackLimits : MonoBehaviour {
ShipControls ship;
float maxDmg = 125f;
void Awake() {
ship = GetComponent<ShipControls>();
}
void OnCollisionEnter(Collision collision) {
// Debug-draw all contact points and normals
// foreach (ContactPoint contact in collision.contacts) {
// Debug.DrawRay(contact.point, contact.normal, Color.white);
// }
if (collision.relativeVelocity.magnitude > maxDmg) {
Debug.Log("Ddddestroyed by" + collision.gameObject.name);
ship.Respawn();
return;
}
if (collision.gameObject.tag == "TrackLimits") {
Debug.Log("Track Limits " + collision.gameObject.name);
ship.Respawn();
return;
}
}
void HitTrackLimits() {
}
}
+11
View File
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0cee35157fdc2b133bf69416f2db2ac3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: