This commit is contained in:
jankaminski1 2024-04-04 20:14:56 +02:00
commit 3e0b425096
20 changed files with 353 additions and 145 deletions

View File

@ -1,5 +1,6 @@
using UnityEditor; using UnityEditor;
using UnityEngine; using UnityEngine;
using Utility;
[CustomPropertyDrawer(typeof(ShowOnlyAttribute))] [CustomPropertyDrawer(typeof(ShowOnlyAttribute))]
public class ShowOnlyDrawer : PropertyDrawer public class ShowOnlyDrawer : PropertyDrawer

View File

@ -38,7 +38,7 @@ RenderSettings:
m_ReflectionIntensity: 1 m_ReflectionIntensity: 1
m_CustomReflection: {fileID: 0} m_CustomReflection: {fileID: 0}
m_Sun: {fileID: 0} m_Sun: {fileID: 0}
m_IndirectSpecularColor: {r: 0.18028378, g: 0.22571412, b: 0.30692285, a: 1} m_IndirectSpecularColor: {r: 0.17732176, g: 0.22198781, b: 0.30422562, a: 1}
m_UseRadianceAmbientProbe: 0 m_UseRadianceAmbientProbe: 0
--- !u!157 &3 --- !u!157 &3
LightmapSettings: LightmapSettings:
@ -134,7 +134,7 @@ GameObject:
- component: {fileID: 179279867} - component: {fileID: 179279867}
- component: {fileID: 179279866} - component: {fileID: 179279866}
m_Layer: 0 m_Layer: 0
m_Name: Directional Light m_Name: Sun
m_TagString: Untagged m_TagString: Untagged
m_Icon: {fileID: 0} m_Icon: {fileID: 0}
m_NavMeshLayer: 0 m_NavMeshLayer: 0
@ -210,13 +210,62 @@ Transform:
m_PrefabAsset: {fileID: 0} m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 179279865} m_GameObject: {fileID: 179279865}
serializedVersion: 2 serializedVersion: 2
m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261} m_LocalRotation: {x: 0.50728154, y: -0, z: -0, w: 0.8617804}
m_LocalPosition: {x: 0, y: 3, z: 0} m_LocalPosition: {x: 0, y: 3, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1} m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0 m_ConstrainProportionsScale: 0
m_Children: [] m_Children: []
m_Father: {fileID: 0} m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0} m_LocalEulerAnglesHint: {x: 60.966, y: 0, z: 0}
--- !u!1 &227416517
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 227416519}
- component: {fileID: 227416518}
m_Layer: 0
m_Name: Time Manager
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &227416518
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 227416517}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: c18f377723b64fd8a8d0261b85b3ba48, type: 3}
m_Name:
m_EditorClassIdentifier:
_daysUntilRelease: 30
_secondsPerDay: 48
_dayTime: 0
_sun: {fileID: 179279866}
_currentWeekday: 0
--- !u!4 &227416519
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 227416517}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 1.466824, y: 5.1305547, z: 5.283371}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &283529456 --- !u!1 &283529456
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@ -252,6 +301,8 @@ MonoBehaviour:
_currentEfficiency: 0 _currentEfficiency: 0
_developers: _developers:
- {fileID: 283529459} - {fileID: 283529459}
_gameRunning:
_falseness: 1
--- !u!4 &283529458 --- !u!4 &283529458
Transform: Transform:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@ -279,6 +330,9 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 6dcc72027d5c35441a351fdb5140b0f8, type: 3} m_Script: {fileID: 11500000, guid: 6dcc72027d5c35441a351fdb5140b0f8, type: 3}
m_Name: m_Name:
m_EditorClassIdentifier: m_EditorClassIdentifier:
_baseEfficiency: 1
_currentCurrentEfficiency: 1
_fingersLeft: 10
--- !u!1 &1737307722 --- !u!1 &1737307722
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@ -378,3 +432,4 @@ SceneRoots:
- {fileID: 1737307725} - {fileID: 1737307725}
- {fileID: 179279867} - {fileID: 179279867}
- {fileID: 283529458} - {fileID: 283529458}
- {fileID: 227416519}

View File

@ -2,23 +2,18 @@ using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;
using UnityEngine.Serialization; using UnityEngine.Serialization;
using Utility;
public class Developer : MonoBehaviour public class Developer : MonoBehaviour
{ {
private string _name; private string _name;
/// <summary>
/// Manche Entwickler sind einfach effizienter als andere.
/// </summary>
[SerializeField] [SerializeField]
private double _baseEfficiency = 1.0; private double _baseEfficiency = 1.0;
[SerializeField, ShowOnly] [SerializeField, ShowOnly]
private double currentCurrentEfficiency = 1.0; private double _currentCurrentEfficiency = 1.0;
/// <summary>
/// Ich hoffe, dass der Entwickler eine Arbeitsunfähigkeitsversicherung hat.
/// </summary>
[SerializeField] [SerializeField]
private int _fingersLeft = 10; private int _fingersLeft = 10;
@ -35,13 +30,13 @@ public class Developer : MonoBehaviour
/// <summary> /// <summary>
/// Gibt die aktuelle Effizienz des Entwicklers in Prozent zurück. /// Gibt die aktuelle Effizienz des Entwicklers in Prozent zurück.
/// </summary> /// </summary>
public double CurrentEfficiency => currentCurrentEfficiency; public double CurrentEfficiency => _currentCurrentEfficiency;
public string Name => _name; public string Name => _name;
public void UpdateEfficiency() public void UpdateEfficiency()
{ {
currentCurrentEfficiency = _baseEfficiency * (_fingersLeft / 10.0); _currentCurrentEfficiency = _baseEfficiency * (_fingersLeft / 10.0);
} }
/// <summary> /// <summary>

View File

@ -3,11 +3,10 @@ using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using UnityEngine; using UnityEngine;
using Utility;
public class GameManager : MonoBehaviour public class GameManager : MonoBehaviourSingleton<GameManager>
{ {
public static GameManager Instance { get; private set; }
[SerializeField] [SerializeField]
private double _baseGameDurationSeconds = 10.0 * 60.0; private double _baseGameDurationSeconds = 10.0 * 60.0;
@ -40,19 +39,6 @@ public class GameManager : MonoBehaviour
public bool IsGameRunning => _gameRunning.IsTrue; public bool IsGameRunning => _gameRunning.IsTrue;
private void Awake()
{
if (Instance == null)
{
Instance = this;
}
else
{
Debug.LogError("GameManager already exists. Deleting duplicate.");
Destroy(gameObject);
}
}
private void Start() private void Start()
{ {
StartGame(); StartGame();

View File

@ -1,53 +0,0 @@
using System;
using UnityEngine;
/// <summary>
/// Stell dir vor, du hättest einen Bool und der könnte einfach mehrmals falsch sein. Wäre das nicht total cool?
/// </summary>
[Serializable]
public struct MultiFalsableBool
{
[SerializeField]
private int _falseness;
public bool IsTrue => _falseness == 0;
public bool IsFalse => _falseness > 0;
/// <summary>
/// Macht den bool noch falscher als er vorher war. Wenn er vorher wahr wahr, dann ist er jetzt definitiv falsch.
/// </summary>
/// <returns>Der neue Wert.</returns>
public bool MakeFalslier()
{
_falseness++;
return this;
}
/// <summary>
/// Macht den bool nicht wahr, sondern lediglich wahrer als er vorher wahr. Wenn er allerdings nur einfach falsch wahr, dann ist er jetzt wahr.
/// Wenn er vorher wahr war, bleibt er wahr.
/// </summary>
/// <returns>Der neue Wert.</returns>
public bool MakeTruer()
{
if (_falseness > 0)
_falseness--;
return this;
}
public MultiFalsableBool(bool value) => _falseness = value ? 0 : 1;
/// <summary>
/// Erzeugt eine neue Instanz von MultiFalsableBool und initialisiert diese mit dem gegebenen Wert.
/// </summary>
/// <param name="value">Der Wert, der angibt, wie falsch der bool ist.</param>
public MultiFalsableBool(int value) => _falseness = (value > 0 ? value : 0);
public static implicit operator bool(MultiFalsableBool value) => value.IsTrue;
public static bool operator ==(MultiFalsableBool a, bool b) => a.IsTrue == b;
public static bool operator !=(MultiFalsableBool a, bool b) => a.IsTrue != b;
}

View File

@ -1,8 +0,0 @@
using UnityEngine;
/// <summary>
/// Das Feld wird im Inspector nur angezeigt und kann nicht verändert werden.
/// </summary>
public class ShowOnlyAttribute : PropertyAttribute
{
}

View File

@ -0,0 +1,67 @@
using System;
using UnityEngine;
using Utility;
public class TimeManager : MonoBehaviourSingleton<TimeManager>
{
[SerializeField]
private int _daysUntilRelease = 30;
[SerializeField]
private double _secondsPerDay = 48;
[SerializeField]
private double _dayTime = 0.0;
[SerializeField] private Light _sun;
[SerializeField]
private Weekday _currentWeekday;
public int DaysLeft => _daysUntilRelease;
public double DayTime => _dayTime;
public TimeSpan TimeOfDay
{
get
{
double hour = _dayTime * 24.0;
double minute = hour * 60;
double seconds = minute * 60;
return new TimeSpan((int)Math.Floor(hour), (int)Math.Floor(minute % 60), (int)Math.Floor(seconds % 60));
}
}
[SerializeField, ShowOnly]
private string stringgy;
void Update()
{
if (GameManager.Instance.IsGameRunning)
{
UpdateTime();
UpdateSun();
}
}
void UpdateTime()
{
_dayTime += Time.deltaTime / _secondsPerDay;
if (_dayTime >= 1.0)
{
_dayTime -= 1.0;
_daysUntilRelease--;
_currentWeekday = _currentWeekday.GetNext();
}
stringgy = TimeOfDay.ToString();
}
private void UpdateSun()
{
_sun.transform.rotation = Quaternion.Euler(new Vector3(Mathf.LerpAngle(-90, 60, (float)Math.Sin(_dayTime * Math.PI)), (float)(_dayTime * 360.0), 0));
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: c18f377723b64fd8a8d0261b85b3ba48
timeCreated: 1712248563

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: a0038d40470c4f06b9f2e4d3a55ef6a2
timeCreated: 1712251934

View File

@ -0,0 +1,48 @@
using UnityEngine;
namespace Utility
{
/// <summary>
/// Ein Singleton das von <see cref="MonoBehaviour"/> erbt. Ermöglicht es aus einem normalen GameObject ein Singleton zu machen.
/// Stellt sicher, dass es nur ein Exemplar von sich selbst gibt.
/// </summary>
/// <typeparam name="T">Der Typ des Singletons.</typeparam>
public abstract class MonoBehaviourSingleton<T> : MonoBehaviour, ISerializationCallbackReceiver where T : MonoBehaviourSingleton<T>
{
private static T _instance;
public static T Instance
{
get => _instance;
private set
{
if (_instance == null)
{
_instance = value;
}
else if (_instance != value)
{
Debug.LogError("Instance already exists. Deleting duplicate.");
Destroy(value.gameObject);
}
}
}
/// <remarks>Wenn du diese methode überlädst, rufe auf jeden Fall base.Awake() auf!</remarks>
protected virtual void Awake()
{
Instance = (T)this;
}
public void OnBeforeSerialize()
{
// Nothing to do here.
}
public void OnAfterDeserialize()
{
// The value of Instance is lost after deserialization, so we need to set it again.
Instance = (T)this;
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 2ce4dbf4ee664bf4a64b41972447deeb
timeCreated: 1712251504

View File

@ -0,0 +1,62 @@
using System;
using UnityEngine;
namespace Utility
{
/// <summary>
/// Stell dir vor, du hättest einen Bool und der könnte einfach mehrmals falsch sein. Wäre das nicht total cool?
/// </summary>
[Serializable]
public struct MultiFalsableBool
{
[SerializeField]
private int _falseness;
public bool IsTrue => _falseness == 0;
public bool IsFalse => _falseness > 0;
/// <summary>
/// Macht den bool noch falscher als er vorher war. Wenn er vorher wahr wahr, dann ist er jetzt definitiv falsch.
/// </summary>
/// <returns>Der neue Wert.</returns>
public bool MakeFalslier()
{
_falseness++;
return this;
}
/// <summary>
/// Macht den bool nicht wahr, sondern lediglich wahrer als er vorher wahr. Wenn er allerdings nur einfach falsch wahr, dann ist er jetzt wahr.
/// Wenn er vorher wahr war, bleibt er wahr.
/// </summary>
/// <returns>Der neue Wert.</returns>
public bool MakeTruer()
{
if (_falseness > 0)
_falseness--;
return this;
}
public MultiFalsableBool(bool value) => _falseness = value ? 0 : 1;
/// <summary>
/// Erzeugt eine neue Instanz von MultiFalsableBool und initialisiert diese mit dem gegebenen Wert.
/// </summary>
/// <param name="value">Der Wert, der angibt, wie falsch der bool ist.</param>
public MultiFalsableBool(int value) => _falseness = (value > 0 ? value : 0);
public static implicit operator bool(MultiFalsableBool value) => value.IsTrue;
public static bool operator ==(MultiFalsableBool a, bool b) => a.IsTrue == b;
public static bool operator !=(MultiFalsableBool a, bool b) => a.IsTrue != b;
public bool Equals(MultiFalsableBool other) => _falseness == other._falseness;
public override bool Equals(object obj) => obj is MultiFalsableBool other && Equals(other);
public override int GetHashCode() => _falseness;
}
}

View File

@ -0,0 +1,11 @@
using UnityEngine;
namespace Utility
{
/// <summary>
/// Das Feld wird im Inspector nur angezeigt und kann nicht verändert werden.
/// </summary>
public class ShowOnlyAttribute : PropertyAttribute
{
}
}

View File

@ -0,0 +1,57 @@
using System.Collections.Generic;
namespace Utility
{
/// <summary>
/// Ermöglicht das erstellen einer Variable mit gestapeltem Wert, sodass überschreiben und zurücksetzen möglich ist.
/// </summary>
public class ValueStack<T> : Stack<T>
{
/// <summary>
/// Erzeugt eine neue Instanz des ValueStacks und initialisiert diesen mit dem Standardwert.
/// </summary>
public ValueStack()
{
Push(default);
}
/// <summary>
/// Erzeugt eine neue Instanz des ValueStacks und initialisiert diesen mit dem gegebenen Wert.
/// </summary>
/// <param name="initialValue">Der Wert, mit dem der Stack initialisiert werden soll.</param>
public ValueStack(T initialValue)
{
Push(initialValue);
}
/// <summary>
/// Setzt den Wert des Stacks auf den gegebenen Wert.
/// </summary>
/// <param name="value">Der Wert, auf den der Stack gesetzt werden soll.</param>
/// <returns>Der gegebene Wert um Verkettung von Expression zu ermöglichen.</returns>
public new T Push(T value)
{
base.Push(value);
return value;
}
/// <summary>
/// Popt den obersten Wert des Stacks, wenn der Stack nur noch einen Wert enthält, wird nicht gepopt und dieser zurückgegeben.
/// </summary>
public new T Pop()
{
if (Count == 1)
return Peek();
return base.Pop();
}
/// <summary>
/// Gibt den aktuellen Wert des ValueStacks zurück.
/// </summary>
public T CurrentValue() => Peek();
public static implicit operator T(ValueStack<T> stack) => stack.CurrentValue();
}
}

View File

@ -0,0 +1,29 @@
namespace Utility
{
public enum Weekday
{
Monday = 0,
Tuesday = 1,
Wednesday = 2,
Thursday = 3,
Friday = 4,
Saturday = 5,
Sunday = 6
}
public static class WeekdayExtension
{
/// <summary>
/// Gibt den Wochentag zurück, der auf den gegebenen Wochentag folgt.
/// </summary>
public static Weekday GetNext(this Weekday current) => GetFutureDay(current, 1);
/// <summary>
/// Gibt den Wochentag zurück, der in der gegebenen Anzahl an Tagen auf den gegebenen Wochentag folgt.
/// </summary>
/// <param name="current">Der aktuelle Wochentag.</param>
/// <param name="days">Die Anzahl an Tagen, die vergehen sollen.</param>
public static Weekday GetFutureDay(this Weekday current, int days) =>
(Weekday)(((int)current + days) % 7);
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 73396106dff94571b3655672f070741c
timeCreated: 1712248985

View File

@ -1,54 +0,0 @@
using System.Collections.Generic;
/// <summary>
/// Ermöglicht das erstellen einer Variable mit gestapeltem Wert, sodass überschreiben und zurücksetzen möglich ist.
/// </summary>
public class ValueStack<T> : Stack<T>
{
/// <summary>
/// Erzeugt eine neue Instanz des ValueStacks und initialisiert diesen mit dem Standardwert.
/// </summary>
public ValueStack()
{
Push(default);
}
/// <summary>
/// Erzeugt eine neue Instanz des ValueStacks und initialisiert diesen mit dem gegebenen Wert.
/// </summary>
/// <param name="initialValue">Der Wert, mit dem der Stack initialisiert werden soll.</param>
public ValueStack(T initialValue)
{
Push(initialValue);
}
/// <summary>
/// Setzt den Wert des Stacks auf den gegebenen Wert.
/// </summary>
/// <param name="value">Der Wert, auf den der Stack gesetzt werden soll.</param>
/// <returns>Der gegebene Wert um Verkettung von Expression zu ermöglichen.</returns>
public new T Push(T value)
{
base.Push(value);
return value;
}
/// <summary>
/// Popt den obersten Wert des Stacks, wenn der Stack nur noch einen Wert enthält, wird nicht gepopt und dieser zurückgegeben.
/// </summary>
public new T Pop()
{
if (Count == 1)
return Peek();
return base.Pop();
}
/// <summary>
/// Gibt den aktuellen Wert des ValueStacks zurück.
/// </summary>
public T CurrentValue() => Peek();
public static implicit operator T(ValueStack<T> stack) => stack.CurrentValue();
}