diff --git a/Assets/Scenes/MainScene.unity b/Assets/Scenes/MainScene.unity
index 027d58f..e2b9cc6 100644
--- a/Assets/Scenes/MainScene.unity
+++ b/Assets/Scenes/MainScene.unity
@@ -159,12 +159,12 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 17322847}
serializedVersion: 2
- m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
- m_Father: {fileID: 0}
+ m_Father: {fileID: 1457077473}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &61846315
GameObject:
@@ -734,12 +734,12 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 253946925}
serializedVersion: 2
- m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
- m_LocalPosition: {x: 0.12123265, y: 0.17553951, z: -8.531889}
+ m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
- m_Father: {fileID: 0}
+ m_Father: {fileID: 1457077473}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &320210793
GameObject:
@@ -753,7 +753,7 @@ GameObject:
- component: {fileID: 320210797}
- component: {fileID: 320210796}
- component: {fileID: 320210795}
- m_Layer: 0
+ m_Layer: 6
m_Name: Floor
m_TagString: Untagged
m_Icon: {fileID: 0}
@@ -1677,30 +1677,29 @@ MonoBehaviour:
m_GameObject: {fileID: 963194225}
m_Enabled: 1
m_EditorHideFlags: 0
- m_Script: {fileID: 11500000, guid: 6a028bd12cca23f45a9eeb9fb0c4d1f1, type: 3}
+ m_Script: {fileID: 11500000, guid: b9e222cf9df32df4196f08036d68d740, type: 3}
m_Name:
m_EditorClassIdentifier:
mouseActive: 1
- autoplayCamSpeed: 2
- xAutoRotateTime: 5
- yAutoRotateTime: 5
lockUserInput: 0
_cameraSpeedNormal: 100
_cameraSpeedMax: 1000
- _speedH: 2
- _speedV: 2
- autoRotate: 0
+ _speedH: 1
+ _speedV: 1
+ _autoRotate: 0
target: {fileID: 1255004942}
- targetRenderer: {fileID: 1255004940}
- floorRenderer: {fileID: 394856875}
- matAlpha: 0
- orbitDistance: 5000
- orbitXSpeed: 0.1
- orbitYSpeed: 0.1
+ _orbitDistance: 5
+ _orbitXSpeed: 0.1
+ _orbitYSpeed: 0.1
+ _zoomSpeed: 5
orbitYMinLimit: -20
orbitYMaxLimit: 80
- orbitDistanceMin: 10
- orbitDistanceMax: 10000
+ targetRenderer: {fileID: 1255004940}
+ floorRenderer: {fileID: 320210796}
+ matAlpha: 0
+ autoplayCamSpeed: 2
+ xAutoRotateTime: 5
+ yAutoRotateTime: 5
forwardToCameraAngle: 0
--- !u!1 &986996500
GameObject:
@@ -1875,6 +1874,52 @@ MeshRenderer:
m_SortingLayer: 0
m_SortingOrder: 0
m_AdditionalVertexStreams: {fileID: 0}
+--- !u!1 &1036072789
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 1036072790}
+ - component: {fileID: 1036072791}
+ m_Layer: 0
+ m_Name: InputManager
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!4 &1036072790
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1036072789}
+ serializedVersion: 2
+ m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
+ m_LocalPosition: {x: 1715.5709, y: 1660.0452, z: 811.7122}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children: []
+ m_Father: {fileID: 1457077473}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!114 &1036072791
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1036072789}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 6a028bd12cca23f45a9eeb9fb0c4d1f1, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ mouseActive: 1
+ lockUserInput: 0
--- !u!1 &1254435375
GameObject:
m_ObjectHideFlags: 0
@@ -2268,6 +2313,40 @@ MeshRenderer:
m_SortingLayer: 0
m_SortingOrder: 0
m_AdditionalVertexStreams: {fileID: 0}
+--- !u!1 &1457077472
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 1457077473}
+ m_Layer: 0
+ m_Name: Managers
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!4 &1457077473
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1457077472}
+ serializedVersion: 2
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children:
+ - {fileID: 253946927}
+ - {fileID: 1036072790}
+ - {fileID: 17322849}
+ m_Father: {fileID: 0}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &1658847972
GameObject:
m_ObjectHideFlags: 0
@@ -2622,8 +2701,7 @@ SceneRoots:
- {fileID: 963194228}
- {fileID: 705507995}
- {fileID: 674567085}
- - {fileID: 253946927}
- {fileID: 2052906806}
- - {fileID: 17322849}
- {fileID: 1255004942}
- {fileID: 564968303}
+ - {fileID: 1457077473}
diff --git a/Assets/Scripts/InputManager.cs b/Assets/Scripts/InputManager.cs
deleted file mode 100644
index 180319f..0000000
--- a/Assets/Scripts/InputManager.cs
+++ /dev/null
@@ -1,463 +0,0 @@
-using System.Collections;
-using System.Collections.Generic;
-using UnityEngine;
-using System.Linq;
-
-public class InputManager : MonoBehaviour
-{
-
- public static InputManager Instance { get; private set; }
-
-
-
- public bool mouseActive = true;
- [System.Serializable]
- public struct CameraPreset
- {
- public Vector3 position;
- public Quaternion rotation;
- }
-
- public float autoplayCamSpeed = 2f;
- public float xAutoRotateTime = 5f;
- public float yAutoRotateTime = 5f;
- private Coroutine autoplayRoutine;
-
-
- public bool lockUserInput = false;
-
- private float _cameraSpeed;
- public float _cameraSpeedNormal = 5.0f;
- public float _cameraSpeedMax = 10.0f;
-
- public float _speedH = 2.0f;
- public float _speedV = 2.0f;
-
- private float _yaw = 0.0f;
- private float _pitch = 0.0f;
-
- private float reloadModifier;
-
- // Orbit controller
- public bool autoRotate = false;
-
- public Transform target;
- public Renderer targetRenderer;
- public Renderer floorRenderer;
- public float matAlpha;
- public float orbitDistance = 5.0f;
- public float orbitXSpeed = 120.0f;
- public float orbitYSpeed = 120.0f;
-
- public float orbitYMinLimit = -20f;
- public float orbitYMaxLimit = 80f;
-
- public float orbitDistanceMin = .5f;
- public float orbitDistanceMax = 15f;
-
- private Rigidbody _rigidbody;
-
- float x = 0.0f;
- float y = 0.0f;
-
-
- CameraPreset fourPos = new CameraPreset();
- CameraPreset fivePos = new CameraPreset();
- CameraPreset sixPos = new CameraPreset();
-
- Vector3 wVector = Vector3.forward;
- Vector3 aVector = Vector3.left;
- Vector3 sVector = Vector3.back;
- Vector3 dVector = Vector3.right;
-
- public float forwardToCameraAngle;
-
- void SetCameraRotation(Quaternion rotation)
- {
- transform.rotation = rotation;
- _pitch = rotation.eulerAngles.x;
- _yaw = rotation.eulerAngles.y;
- }
-
- public static float ClampAngle(float angle, float min, float max)
- {
- if (angle < -360F)
- angle += 360F;
- if (angle > 360F)
- angle -= 360F;
- return Mathf.Clamp(angle, min, max);
- }
-
- private void Awake()
- {
- if (Instance == null) {
- Instance = this;
- DontDestroyOnLoad(gameObject);
- } else {
- Destroy(gameObject);
- }
- }
-
- // Start is called before the first frame update
- void Start()
- {
- fourPos.position = new Vector3(0, 0, 0);
- fourPos.rotation = Quaternion.Euler(0,0,0);
- fivePos.position = new Vector3(0, 0, 0);
- fivePos.rotation = Quaternion.Euler(0, 0, 0);
- sixPos.position = new Vector3(0, 0, 0);
- sixPos.rotation = Quaternion.Euler(0, 0, 0);
-
- Vector3 angles = transform.eulerAngles;
- x = angles.y;
- y = angles.x;
-
- UpdateTargetAlpha();
- }
-
- // Update is called once per frame
- void Update()
- {
- HandleInput();
- }
-
- IEnumerator AutoPlayRoutine()
- {
- while (true)
- {
- float elapsedTime = 0f;
- while (elapsedTime <= xAutoRotateTime)
- {
- x += Time.unscaledDeltaTime * autoplayCamSpeed * orbitDistance * 0.02f;
- UpdateCamPosition();
- elapsedTime += Time.unscaledDeltaTime;
- yield return null;
- }
- elapsedTime = 0f;
- while (elapsedTime <= yAutoRotateTime)
- {
- y -= Time.unscaledDeltaTime * autoplayCamSpeed * orbitDistance * 0.02f;
- UpdateCamPosition();
- elapsedTime += Time.unscaledDeltaTime;
- yield return null;
- }
- elapsedTime = 0f;
- while (elapsedTime <= xAutoRotateTime)
- {
- x -= Time.unscaledDeltaTime * autoplayCamSpeed * orbitDistance * 0.02f;
- UpdateCamPosition();
- elapsedTime += Time.unscaledDeltaTime;
- yield return null;
- }
- elapsedTime = 0f;
- while (elapsedTime <= yAutoRotateTime)
- {
- y += Time.unscaledDeltaTime * autoplayCamSpeed * orbitDistance * 0.02f;
- UpdateCamPosition();
- elapsedTime += Time.unscaledDeltaTime;
- yield return null;
- }
- yield return null;
- }
-
- }
- void ResetCameraTarget()
- {
- RaycastHit hit;
- if(Physics.Raycast(transform.position, transform.forward, out hit, float.MaxValue, LayerMask.GetMask("Floor"), QueryTriggerInteraction.Ignore))
- {
- target.transform.position = hit.point;
- orbitDistance = hit.distance;
- Vector3 angles = transform.eulerAngles;
- x = angles.y;
- y = angles.x;
- UpdateCamPosition();
- }
- else
- {
- target.transform.position = transform.position + (transform.forward * 100);
- orbitDistance = 100;
- Vector3 angles = transform.eulerAngles;
- x = angles.y;
- y = angles.x;
- //UpdateCamPosition();
- }
- }
-
- public void EnableTargetRenderer(bool enable) { targetRenderer.enabled = enable; }
-
- public void EnableFloorGridRenderer(bool enable) { floorRenderer.enabled = enable; }
-
- private void HandleMouseInput()
- {
- // Orbit
- if (target)
- {
- if (Input.GetMouseButton(0))
- {
- x += Input.GetAxis("Mouse X") * orbitXSpeed * orbitDistance * 0.02f;
- y -= Input.GetAxis("Mouse Y") * orbitYSpeed * orbitDistance * 0.02f;
-
- y = ClampAngle(y, orbitYMinLimit, orbitYMaxLimit);
- UpdateCamPosition();
-
- }
- // Rotate
- else if (Input.GetMouseButton(1))
- {
- _yaw += _speedH * Input.GetAxis("Mouse X");
- _pitch -= _speedV * Input.GetAxis("Mouse Y");
-
- transform.eulerAngles = new Vector3(_pitch, _yaw, 0.0f);
- }
-
- }
-
-
- }
-
- private void UpdateCamPosition()
- {
- Quaternion rotation = Quaternion.Euler(y, x, 0);
- RaycastHit hit;
- //Debug.DrawLine(target.position, transform.position, Color.red);
- if (Physics.Linecast(target.position, transform.position, out hit, ~LayerMask.GetMask("Floor"), QueryTriggerInteraction.Ignore))
- {
- orbitDistance -= hit.distance;
- }
- Vector3 negDistance = new Vector3(0.0f, 0.0f, -orbitDistance);
- Vector3 position = rotation * negDistance + target.position;
- UpdateTargetAlpha();
-
- SetCameraRotation(rotation);
- transform.position = position;
- }
-
- private void HandleInput()
- {
- if (!lockUserInput)
- {
- HandleLockableInput();
- }
- HandleNonLockableInput();
- }
-
- void HandleScrollWheelInput()
- {
- if (Input.GetAxis("Mouse ScrollWheel") != 0)
- {
- orbitDistance = Mathf.Clamp(orbitDistance - Input.GetAxis("Mouse ScrollWheel") * 500, orbitDistanceMin, orbitDistanceMax);
- UpdateCamPosition();
- }
- }
-
- void UpdateTargetAlpha()
- {
- matAlpha = (orbitDistance - orbitDistanceMin) / (orbitDistanceMax - orbitDistanceMin);
- matAlpha = Mathf.Max(Mathf.Sqrt(matAlpha) - 0.5f, 0);
- Color matColor = targetRenderer.material.color;
- matColor.a = matAlpha;
- targetRenderer.material.color = matColor;
- }
-
- void UpdateDirectionVectors()
- {
- Vector3 cameraToTarget = target.position - transform.position;
- cameraToTarget.y = 0;
- forwardToCameraAngle = Vector3.SignedAngle(Vector3.forward, cameraToTarget, Vector3.down);
-
- if(forwardToCameraAngle >-45f && forwardToCameraAngle <= 45f)
- {
- wVector = Vector3.forward;
- aVector = Vector3.left;
- sVector = Vector3.back;
- dVector = Vector3.right;
- }
- else if(forwardToCameraAngle > 45f && forwardToCameraAngle <= 135f)
- {
- wVector = Vector3.left;
- aVector = Vector3.back;
- sVector = Vector3.right;
- dVector = Vector3.forward;
- }
- else if(forwardToCameraAngle > 135f || forwardToCameraAngle <= -135f)
- {
- wVector = Vector3.back;
- aVector = Vector3.right;
- sVector = Vector3.forward;
- dVector = Vector3.left;
- }
- else if(forwardToCameraAngle > -135f && forwardToCameraAngle <= -45f)
- {
- wVector = Vector3.right;
- aVector = Vector3.forward;
- sVector = Vector3.left;
- dVector = Vector3.back;
- }
-
- }
-
- void HandleLockableInput()
- {
-
- HandleMouseInput();
- if (Input.GetKey(KeyCode.LeftShift))
- {
- reloadModifier = -.1f;
- _cameraSpeed = _cameraSpeedMax;
- }
- else
- {
- reloadModifier = .1f;
- _cameraSpeed = _cameraSpeedNormal;
- }
-
- // TRANSLATIONAL MOVEMENT
- if (Input.GetKey(KeyCode.W) || Input.GetKey(KeyCode.UpArrow))
- {
- UpdateDirectionVectors();
- //transform.Translate(Vector3.forward * Time.deltaTime * _cameraSpeed);
- target.Translate(wVector * Time.unscaledDeltaTime * _cameraSpeed);
- UpdateCamPosition();
- }
- if (Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.LeftArrow))
- {
- UpdateDirectionVectors();
- //transform.Translate(Vector3.left * Time.deltaTime * _cameraSpeed);
- target.Translate(aVector * Time.unscaledDeltaTime * _cameraSpeed);
- UpdateCamPosition();
- }
- if (Input.GetKey(KeyCode.S) || Input.GetKey(KeyCode.DownArrow))
- {
- UpdateDirectionVectors();
- //transform.Translate(Vector3.back * Time.deltaTime * _cameraSpeed);
- target.Translate(sVector * Time.unscaledDeltaTime * _cameraSpeed);
- UpdateCamPosition();
- }
- if (Input.GetKey(KeyCode.D) || Input.GetKey(KeyCode.RightArrow))
- {
- UpdateDirectionVectors();
- //transform.Translate(Vector3.right * Time.deltaTime * _cameraSpeed);
- target.Translate(dVector * Time.unscaledDeltaTime * _cameraSpeed);
- UpdateCamPosition();
- }
- if (Input.GetKey(KeyCode.Q))
- {
- //transform.Translate(Vector3.up * Time.deltaTime * _cameraSpeed);
- target.Translate(Vector3.up * Time.unscaledDeltaTime * _cameraSpeed);
-
- UpdateCamPosition();
- }
- if (Input.GetKey(KeyCode.E))
- {
- //transform.Translate(Vector3.down * Time.deltaTime * _cameraSpeed);
- target.Translate(Vector3.down * Time.unscaledDeltaTime * _cameraSpeed);
-
- UpdateCamPosition();
- }
-
- }
-
- void HandleNonLockableInput()
- {
- HandleScrollWheelInput();
- if (Input.GetKeyDown(KeyCode.I))
-
-
- if (Input.GetKeyDown(KeyCode.C))
- {
-
- }
-
- if (Input.GetKeyDown(KeyCode.Space))
- {
- // Pause the time
- if (SimManager.Instance.IsSimulationRunning()) {
- SimManager.Instance.PauseSimulation();
- } else {
- SimManager.Instance.ResumeSimulation();
- }
- }
-
- if (Input.GetKeyDown(KeyCode.P))
- {
- autoRotate = !autoRotate;
- if (autoRotate)
- {
- autoplayRoutine = StartCoroutine(AutoPlayRoutine());
- }
- else
- {
- StopCoroutine( autoplayRoutine );
- }
- }
-
- if (Input.GetKeyDown(KeyCode.Alpha1))
- {
- // ORIGIN
- transform.position = new Vector3(0, 20, -20);
- SetCameraRotation(Quaternion.Euler(24f, -0.5f, 0));
- Camera.main.fieldOfView = 45f;
- ResetCameraTarget();
- }
-
- if (Input.GetKeyDown(KeyCode.Alpha2))
- {
- transform.position = new Vector3(0, 30, -20);
- SetCameraRotation(Quaternion.Euler(36.6f, -0.5f, 0));
- Camera.main.fieldOfView = 60f;
- ResetCameraTarget();
-
- }
-
-
- if (Input.GetKeyDown(KeyCode.Alpha4))
- {
- if (Input.GetKey(KeyCode.LeftShift))
- {
- fourPos.position = transform.position;
- fourPos.rotation = transform.rotation;
- }
- else
- {
- transform.position = fourPos.position;
- SetCameraRotation(fourPos.rotation);
- ResetCameraTarget();
- }
-
- }
-
- if (Input.GetKeyDown(KeyCode.Alpha5))
- {
- if (Input.GetKey(KeyCode.LeftShift))
- {
- fivePos.position = transform.position;
- fivePos.rotation = transform.rotation;
- }
- else
- {
- transform.position = fivePos.position;
- SetCameraRotation(fivePos.rotation);
- ResetCameraTarget();
- }
- }
-
- if (Input.GetKeyDown(KeyCode.Alpha6))
- {
- if (Input.GetKey(KeyCode.LeftShift))
- {
- sixPos.position = transform.position;
- sixPos.rotation = transform.rotation;
- }
- else
- {
- transform.position = sixPos.position;
- SetCameraRotation(sixPos.rotation);
- ResetCameraTarget();
- }
- }
-
-
- }
-
-}
diff --git a/Assets/Scripts/Managers.meta b/Assets/Scripts/Managers.meta
new file mode 100644
index 0000000..52062cf
--- /dev/null
+++ b/Assets/Scripts/Managers.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 9411e01e9e0fecb45ac53c53b65fa917
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/Managers/InputManager.cs b/Assets/Scripts/Managers/InputManager.cs
new file mode 100644
index 0000000..258a9c8
--- /dev/null
+++ b/Assets/Scripts/Managers/InputManager.cs
@@ -0,0 +1,177 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using System.Linq;
+
+public class InputManager : MonoBehaviour
+{
+
+ public static InputManager Instance { get; private set; }
+
+
+
+ public bool mouseActive = true;
+ [System.Serializable]
+ public struct CameraPreset
+ {
+ public Vector3 position;
+ public Quaternion rotation;
+ }
+
+ public bool lockUserInput = false;
+
+
+ private void Awake()
+ {
+ if (Instance == null) {
+ Instance = this;
+ DontDestroyOnLoad(gameObject);
+ } else {
+ Destroy(gameObject);
+ }
+ }
+
+ // Start is called before the first frame update
+ void Start()
+ {
+
+ }
+
+ // Update is called once per frame
+ void Update()
+ {
+ HandleInput();
+ }
+
+
+
+ private void HandleMouseInput()
+ {
+ if (Input.GetMouseButton(0))
+ {
+ CameraController.Instance.OrbitCamera(Input.GetAxis("Mouse X"), Input.GetAxis("Mouse Y"));
+
+ }
+ else if (Input.GetMouseButton(1))
+ {
+ CameraController.Instance.RotateCamera(Input.GetAxis("Mouse X"), Input.GetAxis("Mouse Y"));
+ }
+ }
+
+
+ private void HandleInput()
+ {
+ if (!lockUserInput)
+ {
+ HandleLockableInput();
+ }
+ HandleNonLockableInput();
+ }
+
+ void HandleScrollWheelInput()
+ {
+ if (Input.GetAxis("Mouse ScrollWheel") != 0)
+ {
+ CameraController.Instance.ZoomCamera(Input.GetAxis("Mouse ScrollWheel") * 500);
+ }
+ }
+
+ void HandleLockableInput()
+ {
+
+ HandleMouseInput();
+ if (Input.GetKey(KeyCode.LeftShift))
+ {
+ CameraController.Instance.SetCameraSpeed(CameraController.Instance.GetCameraSpeedMax());
+ }
+ else
+ {
+ CameraController.Instance.SetCameraSpeed(CameraController.Instance.GetCameraSpeedNormal());
+ }
+
+ // TRANSLATIONAL MOVEMENT
+ if (Input.GetKey(KeyCode.W) || Input.GetKey(KeyCode.UpArrow))
+ {
+ CameraController.Instance.TranslateCamera(CameraController.TranslationInput.Forward);
+ }
+ if (Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.LeftArrow))
+ {
+ CameraController.Instance.TranslateCamera(CameraController.TranslationInput.Left);
+ }
+ if (Input.GetKey(KeyCode.S) || Input.GetKey(KeyCode.DownArrow))
+ {
+ CameraController.Instance.TranslateCamera(CameraController.TranslationInput.Back);
+ }
+ if (Input.GetKey(KeyCode.D) || Input.GetKey(KeyCode.RightArrow))
+ {
+ CameraController.Instance.TranslateCamera(CameraController.TranslationInput.Right);
+ }
+ if (Input.GetKey(KeyCode.Q))
+ {
+ CameraController.Instance.TranslateCamera(CameraController.TranslationInput.Up);
+ }
+ if (Input.GetKey(KeyCode.E))
+ {
+ CameraController.Instance.TranslateCamera(CameraController.TranslationInput.Down);
+ }
+
+ }
+
+ void HandleNonLockableInput()
+ {
+ HandleScrollWheelInput();
+ if (Input.GetKeyDown(KeyCode.I))
+
+
+ if (Input.GetKeyDown(KeyCode.C))
+ {
+
+ }
+
+ if (Input.GetKeyDown(KeyCode.Space))
+ {
+ // Pause the time
+ if (SimManager.Instance.IsSimulationRunning()) {
+ SimManager.Instance.PauseSimulation();
+ } else {
+ SimManager.Instance.ResumeSimulation();
+ }
+ }
+
+ if (Input.GetKeyDown(KeyCode.P))
+ {
+ CameraController.Instance.SetAutoRotate(!CameraController.Instance.IsAutoRotate());
+ }
+
+ if (Input.GetKeyDown(KeyCode.Alpha1))
+ {
+ // ORIGIN
+ // Set pre-set view 1
+ }
+
+ if (Input.GetKeyDown(KeyCode.Alpha2))
+ {
+ // Set pre-set view 2
+
+ }
+
+
+ if (Input.GetKeyDown(KeyCode.Alpha4))
+ {
+ // Set pre-set view 4
+ }
+
+ if (Input.GetKeyDown(KeyCode.Alpha5))
+ {
+ // Set pre-set view 5
+ }
+
+ if (Input.GetKeyDown(KeyCode.Alpha6))
+ {
+ // Set pre-set view 6
+ }
+
+
+ }
+
+}
diff --git a/Assets/Scripts/InputManager.cs.meta b/Assets/Scripts/Managers/InputManager.cs.meta
similarity index 100%
rename from Assets/Scripts/InputManager.cs.meta
rename to Assets/Scripts/Managers/InputManager.cs.meta
diff --git a/Assets/Scripts/UI.meta b/Assets/Scripts/UI.meta
new file mode 100644
index 0000000..146c7c1
--- /dev/null
+++ b/Assets/Scripts/UI.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: c17270294c7dd6d45b8731a468423a83
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/UI/CameraController.cs b/Assets/Scripts/UI/CameraController.cs
new file mode 100644
index 0000000..3784838
--- /dev/null
+++ b/Assets/Scripts/UI/CameraController.cs
@@ -0,0 +1,489 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+public class CameraController : MonoBehaviour
+{
+ #region Singleton
+
+ ///
+ /// Singleton instance of the CameraController.
+ ///
+ public static CameraController Instance { get; private set; }
+
+ #endregion
+
+ #region Camera Settings
+
+ ///
+ /// Determines if mouse input is active for camera control.
+ ///
+ public bool mouseActive = true;
+
+ ///
+ /// Locks user input for camera control.
+ ///
+ public bool lockUserInput = false;
+
+ ///
+ /// Normal speed of camera movement.
+ ///
+ [SerializeField] private float _cameraSpeedNormal = 100.0f;
+
+ ///
+ /// Maximum speed of camera movement.
+ ///
+ [SerializeField] private float _cameraSpeedMax = 1000.0f;
+
+ ///
+ /// Current speed of camera movement.
+ ///
+ private float _cameraSpeed;
+
+ ///
+ /// Horizontal rotation speed.
+ ///
+ public float _speedH = 2.0f;
+
+ ///
+ /// Vertical rotation speed.
+ ///
+ public float _speedV = 2.0f;
+
+ ///
+ /// Current yaw angle of the camera.
+ ///
+ private float _yaw = 0.0f;
+
+ ///
+ /// Current pitch angle of the camera.
+ ///
+ private float _pitch = 0.0f;
+
+ #endregion
+
+ #region Orbit Settings
+
+ ///
+ /// Determines if the camera should auto-rotate.
+ ///
+ public bool _autoRotate = false;
+
+ ///
+ /// Target transform for orbit rotation.
+ ///
+ public Transform target;
+
+ ///
+ /// Distance from the camera to the orbit target.
+ ///
+ [SerializeField] private float _orbitDistance = 5.0f;
+
+ ///
+ /// Horizontal orbit rotation speed.
+ ///
+ [SerializeField] private float _orbitXSpeed = 120.0f;
+
+ ///
+ /// Vertical orbit rotation speed.
+ ///
+ [SerializeField] private float _orbitYSpeed = 120.0f;
+
+ ///
+ /// Speed of camera zoom.
+ ///
+ [SerializeField] private float _zoomSpeed = 500.0f;
+
+ ///
+ /// Minimum vertical angle limit for orbit.
+ ///
+ public float orbitYMinLimit = -20f;
+
+ ///
+ /// Maximum vertical angle limit for orbit.
+ ///
+ public float orbitYMaxLimit = 80f;
+
+ ///
+ /// Minimum distance for orbit.
+ ///
+ private float _orbitDistanceMin = 10f;
+
+ ///
+ /// Maximum distance for orbit.
+ ///
+ private float _orbitDistanceMax = 10000f;
+
+ ///
+ /// Current horizontal orbit angle.
+ ///
+ private float _orbitX = 0.0f;
+
+ ///
+ /// Current vertical orbit angle.
+ ///
+ private float _orbitY = 0.0f;
+
+ #endregion
+
+ #region Rendering
+
+ ///
+ /// Renderer for the orbit target.
+ ///
+ public Renderer targetRenderer;
+
+ ///
+ /// Renderer for the floor.
+ ///
+ public Renderer floorRenderer;
+
+ ///
+ /// Alpha value for material transparency.
+ ///
+ public float matAlpha;
+
+ #endregion
+
+ #region Autoplay Settings
+
+ ///
+ /// Speed of camera movement during autoplay.
+ ///
+ public float autoplayCamSpeed = 2f;
+
+ ///
+ /// Duration of horizontal auto-rotation.
+ ///
+ public float xAutoRotateTime = 5f;
+
+ ///
+ /// Duration of vertical auto-rotation.
+ ///
+ public float yAutoRotateTime = 5f;
+
+ ///
+ /// Coroutine for autoplay functionality.
+ ///
+ private Coroutine autoplayRoutine;
+
+ #endregion
+
+ #region Camera Presets
+
+ ///
+ /// Represents a preset camera position and rotation.
+ ///
+ [System.Serializable]
+ public struct CameraPreset
+ {
+ public Vector3 position;
+ public Quaternion rotation;
+ }
+
+ ///
+ /// Preset camera position for key 4.
+ ///
+ CameraPreset fourPos = new CameraPreset();
+
+ ///
+ /// Preset camera position for key 5.
+ ///
+ CameraPreset fivePos = new CameraPreset();
+
+ ///
+ /// Preset camera position for key 6.
+ ///
+ CameraPreset sixPos = new CameraPreset();
+
+ #endregion
+
+ #region Movement
+
+ ///
+ /// Mapping of translation inputs to movement vectors.
+ ///
+ private Dictionary _translationInputToVectorMap;
+
+ ///
+ /// Forward movement vector.
+ ///
+ Vector3 wVector = Vector3.forward;
+
+ ///
+ /// Left movement vector.
+ ///
+ Vector3 aVector = Vector3.left;
+
+ ///
+ /// Backward movement vector.
+ ///
+ Vector3 sVector = Vector3.back;
+
+ ///
+ /// Right movement vector.
+ ///
+ Vector3 dVector = Vector3.right;
+
+ ///
+ /// Angle between forward vector and camera direction.
+ ///
+ public float forwardToCameraAngle;
+
+ #endregion
+
+ void SetCameraRotation(Quaternion rotation)
+ {
+ transform.rotation = rotation;
+ _pitch = rotation.eulerAngles.x;
+ _yaw = rotation.eulerAngles.y;
+ }
+
+ public void SetCameraSpeed(float speed)
+ {
+ _cameraSpeed = speed;
+ }
+
+ public float GetCameraSpeedMax()
+ {
+ return _cameraSpeedMax;
+ }
+
+ public float GetCameraSpeedNormal()
+ {
+ return _cameraSpeedNormal;
+ }
+
+ public bool IsAutoRotate()
+ {
+ return _autoRotate;
+ }
+
+ public void SetAutoRotate(bool autoRotate)
+ {
+ if (autoRotate && !_autoRotate) {
+ _autoRotate = true;
+ autoplayRoutine = StartCoroutine(AutoPlayRoutine());
+ } else if (!autoRotate && _autoRotate) {
+ _autoRotate = false;
+ StopCoroutine(autoplayRoutine);
+ }
+ }
+
+ public static float ClampAngle(float angle, float min, float max)
+ {
+ if (angle < -360F)
+ angle += 360F;
+ if (angle > 360F)
+ angle -= 360F;
+ return Mathf.Clamp(angle, min, max);
+ }
+
+ private void Awake()
+ {
+ if (Instance == null) {
+ Instance = this;
+ DontDestroyOnLoad(gameObject);
+ } else {
+ Destroy(gameObject);
+ }
+
+ _translationInputToVectorMap = new Dictionary {
+ {TranslationInput.Forward, wVector},
+ {TranslationInput.Left, aVector},
+ {TranslationInput.Back, sVector},
+ {TranslationInput.Right, dVector},
+ {TranslationInput.Up, Vector3.up},
+ {TranslationInput.Down, Vector3.down}
+ };
+ }
+
+ // Start is called before the first frame update
+ void Start()
+ {
+ fourPos.position = new Vector3(0, 0, 0);
+ fourPos.rotation = Quaternion.Euler(0,0,0);
+ fivePos.position = new Vector3(0, 0, 0);
+ fivePos.rotation = Quaternion.Euler(0, 0, 0);
+ sixPos.position = new Vector3(0, 0, 0);
+ sixPos.rotation = Quaternion.Euler(0, 0, 0);
+
+ Vector3 angles = transform.eulerAngles;
+ _orbitX = angles.y;
+ _orbitY = angles.x;
+
+ UpdateTargetAlpha();
+ ResetCameraTarget();
+ }
+
+ IEnumerator AutoPlayRoutine()
+ {
+ while (true)
+ {
+ float elapsedTime = 0f;
+ while (elapsedTime <= xAutoRotateTime)
+ {
+ _orbitX += Time.unscaledDeltaTime * autoplayCamSpeed * _orbitDistance * 0.02f;
+ UpdateCamPosition(_orbitX, _orbitY);
+ elapsedTime += Time.unscaledDeltaTime;
+ yield return null;
+ }
+ elapsedTime = 0f;
+ while (elapsedTime <= yAutoRotateTime)
+ {
+ _orbitY -= Time.unscaledDeltaTime * autoplayCamSpeed * _orbitDistance * 0.02f;
+ UpdateCamPosition(_orbitX, _orbitY);
+ elapsedTime += Time.unscaledDeltaTime;
+ yield return null;
+ }
+ elapsedTime = 0f;
+ while (elapsedTime <= xAutoRotateTime)
+ {
+ _orbitX -= Time.unscaledDeltaTime * autoplayCamSpeed * _orbitDistance * 0.02f;
+ UpdateCamPosition(_orbitX, _orbitY);
+ elapsedTime += Time.unscaledDeltaTime;
+ yield return null;
+ }
+ elapsedTime = 0f;
+ while (elapsedTime <= yAutoRotateTime)
+ {
+ _orbitY += Time.unscaledDeltaTime * autoplayCamSpeed * _orbitDistance * 0.02f;
+ UpdateCamPosition(_orbitX, _orbitY);
+ elapsedTime += Time.unscaledDeltaTime;
+ yield return null;
+ }
+ yield return null;
+ }
+
+ }
+ void ResetCameraTarget()
+ {
+ RaycastHit hit;
+ if(Physics.Raycast(transform.position, transform.forward, out hit, float.MaxValue, LayerMask.GetMask("Floor"), QueryTriggerInteraction.Ignore))
+ {
+ target.transform.position = hit.point;
+ _orbitDistance = hit.distance;
+ Vector3 angles = transform.eulerAngles;
+ _orbitX = angles.y;
+ _orbitY = angles.x;
+ UpdateCamPosition(_orbitX, _orbitY);
+ }
+ else
+ {
+ target.transform.position = transform.position + (transform.forward * 100);
+ _orbitDistance = 100;
+ Vector3 angles = transform.eulerAngles;
+ _orbitX = angles.y;
+ _orbitY = angles.x;
+ //UpdateCamPosition();
+ }
+ }
+
+ public void EnableTargetRenderer(bool enable) { targetRenderer.enabled = enable; }
+
+ public void EnableFloorGridRenderer(bool enable) { floorRenderer.enabled = enable; }
+
+
+ public void OrbitCamera(float xOrbit, float yOrbit) {
+ if (target)
+ {
+ _orbitX += xOrbit * _orbitXSpeed * _orbitDistance * 0.02f;
+ _orbitY -= yOrbit * _orbitYSpeed * _orbitDistance * 0.02f;
+
+ _orbitY = ClampAngle(_orbitY, orbitYMinLimit, orbitYMaxLimit);
+ UpdateCamPosition(_orbitX, _orbitY);
+ }
+ }
+
+ public void RotateCamera(float xRotate, float yRotate) {
+ _yaw += xRotate * _speedH;
+ _pitch -= yRotate * _speedV;
+ transform.eulerAngles = new Vector3(_pitch, _yaw, 0.0f);
+ }
+
+ private void UpdateCamPosition(float x, float y)
+ {
+ Quaternion rotation = Quaternion.Euler(y, x, 0);
+ RaycastHit hit;
+ //Debug.DrawLine(target.position, transform.position, Color.red);
+ if (Physics.Linecast(target.position, transform.position, out hit, ~LayerMask.GetMask("Floor"), QueryTriggerInteraction.Ignore))
+ {
+ _orbitDistance -= hit.distance;
+ }
+ Vector3 negDistance = new Vector3(0.0f, 0.0f, -_orbitDistance);
+ Vector3 position = rotation * negDistance + target.position;
+ UpdateTargetAlpha();
+
+ SetCameraRotation(rotation);
+ transform.position = position;
+ }
+
+
+ public void ZoomCamera(float zoom)
+ {
+ _orbitDistance = Mathf.Clamp(_orbitDistance - zoom * _zoomSpeed, _orbitDistanceMin, _orbitDistanceMax);
+ UpdateCamPosition(_orbitX, _orbitY);
+ }
+
+ void UpdateTargetAlpha()
+ {
+ matAlpha = (_orbitDistance - _orbitDistanceMin) / (_orbitDistanceMax - _orbitDistanceMin);
+ matAlpha = Mathf.Max(Mathf.Sqrt(matAlpha) - 0.5f, 0);
+ Color matColor = targetRenderer.material.color;
+ matColor.a = matAlpha;
+ targetRenderer.material.color = matColor;
+ }
+
+ void UpdateDirectionVectors()
+ {
+ Vector3 cameraToTarget = target.position - transform.position;
+ cameraToTarget.y = 0;
+ forwardToCameraAngle = Vector3.SignedAngle(Vector3.forward, cameraToTarget, Vector3.down);
+
+ if(forwardToCameraAngle >-45f && forwardToCameraAngle <= 45f)
+ {
+ _translationInputToVectorMap[TranslationInput.Forward] = Vector3.forward;
+ _translationInputToVectorMap[TranslationInput.Left] = Vector3.left;
+ _translationInputToVectorMap[TranslationInput.Back] = Vector3.back;
+ _translationInputToVectorMap[TranslationInput.Right] = Vector3.right;
+ }
+ else if(forwardToCameraAngle > 45f && forwardToCameraAngle <= 135f)
+ {
+ _translationInputToVectorMap[TranslationInput.Forward] = Vector3.left;
+ _translationInputToVectorMap[TranslationInput.Left] = Vector3.back;
+ _translationInputToVectorMap[TranslationInput.Back] = Vector3.right;
+ _translationInputToVectorMap[TranslationInput.Right] = Vector3.forward;
+ }
+ else if(forwardToCameraAngle > 135f || forwardToCameraAngle <= -135f)
+ {
+ _translationInputToVectorMap[TranslationInput.Forward] = Vector3.back;
+ _translationInputToVectorMap[TranslationInput.Left] = Vector3.right;
+ _translationInputToVectorMap[TranslationInput.Back] = Vector3.forward;
+ _translationInputToVectorMap[TranslationInput.Right] = Vector3.left;
+ }
+ else if(forwardToCameraAngle > -135f && forwardToCameraAngle <= -45f)
+ {
+ _translationInputToVectorMap[TranslationInput.Forward] = Vector3.right;
+ _translationInputToVectorMap[TranslationInput.Left] = Vector3.forward;
+ _translationInputToVectorMap[TranslationInput.Back] = Vector3.left;
+ _translationInputToVectorMap[TranslationInput.Right] = Vector3.back;
+ }
+
+ }
+
+ public enum TranslationInput {
+ Forward,
+ Left,
+ Back,
+ Right,
+ Up,
+ Down
+ }
+
+ public void TranslateCamera(TranslationInput input) {
+ UpdateDirectionVectors();
+ target.Translate(_translationInputToVectorMap[input] * Time.unscaledDeltaTime * _cameraSpeed);
+ UpdateCamPosition(_orbitX, _orbitY);
+ }
+
+}
diff --git a/Assets/Scripts/UI/CameraController.cs.meta b/Assets/Scripts/UI/CameraController.cs.meta
new file mode 100644
index 0000000..b5d307d
--- /dev/null
+++ b/Assets/Scripts/UI/CameraController.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: b9e222cf9df32df4196f08036d68d740
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/UI/Dialogs.meta b/Assets/Scripts/UI/Dialogs.meta
new file mode 100644
index 0000000..e2446ca
--- /dev/null
+++ b/Assets/Scripts/UI/Dialogs.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 27829404610ae9a479fd6f44c6da81ca
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/UI/Dialogs/AgentStatusDialog.cs b/Assets/Scripts/UI/Dialogs/AgentStatusDialog.cs
new file mode 100644
index 0000000..224a330
--- /dev/null
+++ b/Assets/Scripts/UI/Dialogs/AgentStatusDialog.cs
@@ -0,0 +1,36 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+public class BotStatusDialog : UIDialog
+{
+ // Start is called before the first frame update
+ public override void Start()
+ {
+ base.Start();
+
+
+ UISelectableEntry missiles = CreateSelectableEntry();
+ missiles.SetTextContent(new List(new string[] { "Missiles" }));
+ missiles.SetIsSelectable(false);
+
+ UISelectableEntry submunitions = CreateSelectableEntry();
+ submunitions.SetTextContent(new List(new string[] { "Submunitions" }));
+ submunitions.SetIsSelectable(false);
+
+ UISelectableEntry targets = CreateSelectableEntry();
+ targets.SetTextContent(new List(new string[] { "Targets" }));
+ targets.SetIsSelectable(false);
+
+ SetDialogEntries(new List(new UISelectableEntry[] { missiles, submunitions, targets }));
+
+ AddDialogTab("All", () => { });
+
+ }
+
+ // Update is called once per frame
+ void Update()
+ {
+
+ }
+}
diff --git a/Assets/Scripts/UI/Dialogs/AgentStatusDialog.cs.meta b/Assets/Scripts/UI/Dialogs/AgentStatusDialog.cs.meta
new file mode 100644
index 0000000..cfa323d
--- /dev/null
+++ b/Assets/Scripts/UI/Dialogs/AgentStatusDialog.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: a404f59a5c2ba814a9c1ca121b596df9
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/UI/RectTransformExtensions.cs b/Assets/Scripts/UI/RectTransformExtensions.cs
new file mode 100644
index 0000000..b68ddc5
--- /dev/null
+++ b/Assets/Scripts/UI/RectTransformExtensions.cs
@@ -0,0 +1,23 @@
+ using UnityEngine;
+ public static class RectTransformExtensions
+ {
+ public static void SetLeft(this RectTransform rt, float left)
+ {
+ rt.offsetMin = new Vector2(left, rt.offsetMin.y);
+ }
+
+ public static void SetRight(this RectTransform rt, float right)
+ {
+ rt.offsetMax = new Vector2(-right, rt.offsetMax.y);
+ }
+
+ public static void SetTop(this RectTransform rt, float top)
+ {
+ rt.offsetMax = new Vector2(rt.offsetMax.x, -top);
+ }
+
+ public static void SetBottom(this RectTransform rt, float bottom)
+ {
+ rt.offsetMin = new Vector2(rt.offsetMin.x, bottom);
+ }
+ }
\ No newline at end of file
diff --git a/Assets/Scripts/UI/RectTransformExtensions.cs.meta b/Assets/Scripts/UI/RectTransformExtensions.cs.meta
new file mode 100644
index 0000000..1d18e42
--- /dev/null
+++ b/Assets/Scripts/UI/RectTransformExtensions.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: c991d4191b4586742a5d8dfc8ece23bb
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/UI/UIBuildButton.cs b/Assets/Scripts/UI/UIBuildButton.cs
new file mode 100644
index 0000000..88b4745
--- /dev/null
+++ b/Assets/Scripts/UI/UIBuildButton.cs
@@ -0,0 +1,18 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+public class UIBuildButton : MonoBehaviour
+{
+ // Start is called before the first frame update
+ void Start()
+ {
+
+ }
+
+ // Update is called once per frame
+ void Update()
+ {
+
+ }
+}
diff --git a/Assets/Scripts/UI/UIBuildButton.cs.meta b/Assets/Scripts/UI/UIBuildButton.cs.meta
new file mode 100644
index 0000000..cd65090
--- /dev/null
+++ b/Assets/Scripts/UI/UIBuildButton.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 56ea3cedd2ebcbc42a98ea19ebc61632
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/UI/UIDialog.cs b/Assets/Scripts/UI/UIDialog.cs
new file mode 100644
index 0000000..da53a3c
--- /dev/null
+++ b/Assets/Scripts/UI/UIDialog.cs
@@ -0,0 +1,213 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using TMPro;
+using System;
+using UnityEngine.UI;
+
+public class UIDialog : MonoBehaviour
+{
+ [SerializeField]
+ private string dialogTitle;
+
+ [SerializeField]
+ private TextMeshProUGUI dialogTitleHandle;
+ [SerializeField]
+ private RectTransform contentHandle;
+
+ /// TABS
+ [SerializeField]
+ private float tabWidth = 50f;
+ [SerializeField]
+ private float tabHeight = 16f;
+ // List of dialog tabs
+ private List dialogTabs;
+
+ /// ENTRIES
+ private List entries;
+
+ private float entryHeight = 20f;
+ private float entryIndentWidth= 10f;
+
+ private List cleanupPool;
+
+
+ private bool isOpen;
+
+
+
+
+ // Start is called before the first frame update
+ public virtual void Start()
+ {
+ dialogTitleHandle.text = dialogTitle;
+ dialogTitleHandle.font = UIManager.Instance.Font;
+ isOpen = gameObject.activeSelf;
+ dialogTabs = new List();
+ entries = new List();
+ cleanupPool = new List();
+ }
+
+ internal RectTransform GetContentHandle()
+ {
+ return contentHandle;
+ }
+
+ public bool IsOpen()
+ {
+ return isOpen;
+ }
+
+ protected virtual void OnEnable() { isOpen = true; }
+ protected virtual void OnDisable() { isOpen = false; }
+
+ public float GetTabWidth() { return tabWidth; }
+ public float GetTabHeight() { return tabHeight; }
+
+ ///
+ /// Returns the height of the dialog title bar
+ ///
+ public float GetTitleBarHeight() { return dialogTitleHandle.rectTransform.sizeDelta.y; }
+
+ ///
+ /// Adds a new tab to the dialog, when clicked it will call the given callback
+ ///
+ public void AddDialogTab(string tabName, Action onClick)
+ {
+ dialogTabs.Add(AddTabButton(tabName, onClick));
+ }
+
+ ///
+ /// Add the tab button to the right of the existing tabs
+ ///
+ private GameObject AddTabButton(string tabName, Action onClick)
+ {
+ GameObject tabButton = new GameObject("TabButton", typeof(RectTransform));
+ tabButton.transform.SetParent(transform); // worldPositionStays ?
+ // RectTransform anchors to the right of the content handle
+ RectTransform rTransform = tabButton.GetComponent();
+ rTransform.anchorMin = new Vector2(0, 1);
+ rTransform.anchorMax = new Vector2(0, 1);
+ rTransform.pivot = new Vector2(0, 1);
+ rTransform.sizeDelta = new Vector2(tabWidth, tabHeight);
+ // Count tabs * tabSize to get the position from the left
+ rTransform.anchoredPosition = new Vector2(tabWidth * dialogTabs.Count, -(GetTitleBarHeight()));
+
+ // Add the onClick callback to the button
+ Button button = tabButton.AddComponent