diff --git a/ButtonReplay.cs b/ButtonReplay.cs new file mode 100644 index 0000000..e3ab77b --- /dev/null +++ b/ButtonReplay.cs @@ -0,0 +1,32 @@ +using System.Collections; +using System.Collections.Generic; +using Unity.VisualScripting; +using UnityEngine; +using UnityEngine.SceneManagement; +using UnityEngine.UI; +using UnityEngine.UIElements; +using Button = UnityEngine.UI.Button; + +public class ButtonReplay : MonoBehaviour +{ + public bool changeScene = false; + + public void ChangeScene(bool changeScene) + { + if (SceneManager.GetActiveScene().name != "Playground") + { + Main.damageExpenses = 0; + SceneManager.LoadScene("Playground"); + } + else + { + if (Main.markedExpenses == Main.damageExpenses) //maybe should also check if they actually picked the right stuff + Main.endCondition = 4; + else if (Main.markedExpenses >= Main.damageExpenses) + Main.endCondition = 3; + else if (Main.markedExpenses <= Main.damageExpenses) + Main.endCondition = 2; + SceneManager.LoadScene("end"); + } + } +} \ No newline at end of file diff --git a/Checkbox.cs b/Checkbox.cs new file mode 100644 index 0000000..0a9daea --- /dev/null +++ b/Checkbox.cs @@ -0,0 +1,18 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +public class Checkbox : MonoBehaviour +{ + + public void bruhSoundEffect() + { + Main.brokenStatus = !Main.brokenStatus; + } + + public void Awake() + { + Main.brokenStatus = false; + } + +} diff --git a/Checklist.cs b/Checklist.cs new file mode 100644 index 0000000..74fea05 --- /dev/null +++ b/Checklist.cs @@ -0,0 +1,38 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.InputSystem; + +public class Checklist : MonoBehaviour +{ + public RectTransform rect; + public static bool onScreen; + // Start is called before the first frame update + void Start() + { + rect.anchoredPosition = new Vector2(-300, 0); + onScreen = false; + } + // Update is called once per frame + + void Update() + { + if (Input.GetButtonDown("Show")) + { + if (onScreen) + { + rect.anchoredPosition = new Vector2(-1000, 0); + Cursor.visible = false; + Cursor.lockState = CursorLockMode.Locked; + } + else + { + rect.anchoredPosition = new Vector2(464, 0); + Cursor.visible = true; + Cursor.lockState = CursorLockMode.None; + } + + onScreen = !onScreen; + } + } +} diff --git a/FirstPersonController.cs b/FirstPersonController.cs new file mode 100644 index 0000000..6981001 --- /dev/null +++ b/FirstPersonController.cs @@ -0,0 +1,271 @@ +using UnityEngine; +#if ENABLE_INPUT_SYSTEM && STARTER_ASSETS_PACKAGES_CHECKED +using UnityEngine.InputSystem; +#endif + +namespace StarterAssets +{ + [RequireComponent(typeof(CharacterController))] +#if ENABLE_INPUT_SYSTEM && STARTER_ASSETS_PACKAGES_CHECKED + [RequireComponent(typeof(PlayerInput))] +#endif + public class FirstPersonController : MonoBehaviour + { + [Header("Player")] + [Tooltip("Move speed of the character in m/s")] + public float MoveSpeed = 4.0f; + [Tooltip("Sprint speed of the character in m/s")] + public float SprintSpeed = 6.0f; + [Tooltip("Rotation speed of the character")] + public float RotationSpeed = 1.0f; + [Tooltip("Acceleration and deceleration")] + public float SpeedChangeRate = 10.0f; + + [Space(10)] + [Tooltip("The height the player can jump")] + public float JumpHeight = 1.2f; + [Tooltip("The character uses its own gravity value. The engine default is -9.81f")] + public float Gravity = -15.0f; + + [Space(10)] + [Tooltip("Time required to pass before being able to jump again. Set to 0f to instantly jump again")] + public float JumpTimeout = 0.1f; + [Tooltip("Time required to pass before entering the fall state. Useful for walking down stairs")] + public float FallTimeout = 0.15f; + + [Header("Player Grounded")] + [Tooltip("If the character is grounded or not. Not part of the CharacterController built in grounded check")] + public bool Grounded = true; + [Tooltip("Useful for rough ground")] + public float GroundedOffset = -0.14f; + [Tooltip("The radius of the grounded check. Should match the radius of the CharacterController")] + public float GroundedRadius = 0.5f; + [Tooltip("What layers the character uses as ground")] + public LayerMask GroundLayers; + + [Header("Cinemachine")] + [Tooltip("The follow target set in the Cinemachine Virtual Camera that the camera will follow")] + public GameObject CinemachineCameraTarget; + [Tooltip("How far in degrees can you move the camera up")] + public float TopClamp = 90.0f; + [Tooltip("How far in degrees can you move the camera down")] + public float BottomClamp = -90.0f; + + // cinemachine + private float _cinemachineTargetPitch; + + // player + private float _speed; + private float _rotationVelocity; + private float _verticalVelocity; + private float _terminalVelocity = 53.0f; + + // timeout deltatime + private float _jumpTimeoutDelta; + private float _fallTimeoutDelta; + + +#if ENABLE_INPUT_SYSTEM && STARTER_ASSETS_PACKAGES_CHECKED + private PlayerInput _playerInput; +#endif + private CharacterController _controller; + private StarterAssetsInputs _input; + private GameObject _mainCamera; + + private const float _threshold = 0.01f; + + private bool IsCurrentDeviceMouse + { + get + { + #if ENABLE_INPUT_SYSTEM && STARTER_ASSETS_PACKAGES_CHECKED + return _playerInput.currentControlScheme == "KeyboardMouse"; + #else + return false; + #endif + } + } + + private void Awake() + { + // get a reference to our main camera + if (_mainCamera == null) + { + _mainCamera = GameObject.FindGameObjectWithTag("MainCamera"); + } + } + + private void Start() + { + Cursor.lockState = CursorLockMode.Locked; + Cursor.visible = false; + _controller = GetComponent(); + _input = GetComponent(); +#if ENABLE_INPUT_SYSTEM && STARTER_ASSETS_PACKAGES_CHECKED + _playerInput = GetComponent(); +#else + Debug.LogError( "Starter Assets package is missing dependencies. Please use Tools/Starter Assets/Reinstall Dependencies to fix it"); +#endif + + // reset our timeouts on start + _jumpTimeoutDelta = JumpTimeout; + _fallTimeoutDelta = FallTimeout; + } + + private void Update() + { + JumpAndGravity(); + GroundedCheck(); + Move(); + } + + private void LateUpdate() + { + if(!Checklist.onScreen) + CameraRotation(); + } + + private void GroundedCheck() + { + // set sphere position, with offset + Vector3 spherePosition = new Vector3(transform.position.x, transform.position.y - GroundedOffset, transform.position.z); + Grounded = Physics.CheckSphere(spherePosition, GroundedRadius, GroundLayers, QueryTriggerInteraction.Ignore); + } + + private void CameraRotation() + { + // if there is an input + if (_input.look.sqrMagnitude >= _threshold) + { + //Don't multiply mouse input by Time.deltaTime + float deltaTimeMultiplier = IsCurrentDeviceMouse ? 1.0f : Time.deltaTime; + + _cinemachineTargetPitch += _input.look.y * RotationSpeed * deltaTimeMultiplier; + _rotationVelocity = _input.look.x * RotationSpeed * deltaTimeMultiplier; + + // clamp our pitch rotation + _cinemachineTargetPitch = ClampAngle(_cinemachineTargetPitch, BottomClamp, TopClamp); + + // Update Cinemachine camera target pitch + CinemachineCameraTarget.transform.localRotation = Quaternion.Euler(_cinemachineTargetPitch, 0.0f, 0.0f); + + // rotate the player left and right + transform.Rotate(Vector3.up * _rotationVelocity); + } + } + + private void Move() + { + // set target speed based on move speed, sprint speed and if sprint is pressed + float targetSpeed = _input.sprint ? SprintSpeed : MoveSpeed; + + // a simplistic acceleration and deceleration designed to be easy to remove, replace, or iterate upon + + // note: Vector2's == operator uses approximation so is not floating point error prone, and is cheaper than magnitude + // if there is no input, set the target speed to 0 + if (_input.move == Vector2.zero) targetSpeed = 0.0f; + + // a reference to the players current horizontal velocity + float currentHorizontalSpeed = new Vector3(_controller.velocity.x, 0.0f, _controller.velocity.z).magnitude; + + float speedOffset = 0.1f; + float inputMagnitude = _input.analogMovement ? _input.move.magnitude : 1f; + + // accelerate or decelerate to target speed + if (currentHorizontalSpeed < targetSpeed - speedOffset || currentHorizontalSpeed > targetSpeed + speedOffset) + { + // creates curved result rather than a linear one giving a more organic speed change + // note T in Lerp is clamped, so we don't need to clamp our speed + _speed = Mathf.Lerp(currentHorizontalSpeed, targetSpeed * inputMagnitude, Time.deltaTime * SpeedChangeRate); + + // round speed to 3 decimal places + _speed = Mathf.Round(_speed * 1000f) / 1000f; + } + else + { + _speed = targetSpeed; + } + + // normalise input direction + Vector3 inputDirection = new Vector3(_input.move.x, 0.0f, _input.move.y).normalized; + + // note: Vector2's != operator uses approximation so is not floating point error prone, and is cheaper than magnitude + // if there is a move input rotate player when the player is moving + if (_input.move != Vector2.zero) + { + // move + inputDirection = transform.right * _input.move.x + transform.forward * _input.move.y; + } + + // move the player + _controller.Move(inputDirection.normalized * (_speed * Time.deltaTime) + new Vector3(0.0f, _verticalVelocity, 0.0f) * Time.deltaTime); + } + + private void JumpAndGravity() + { + if (Grounded) + { + // reset the fall timeout timer + _fallTimeoutDelta = FallTimeout; + + // stop our velocity dropping infinitely when grounded + if (_verticalVelocity < 0.0f) + { + _verticalVelocity = -2f; + } + + // Jump + if (_input.jump && _jumpTimeoutDelta <= 0.0f) + { + // the square root of H * -2 * G = how much velocity needed to reach desired height + _verticalVelocity = Mathf.Sqrt(JumpHeight * -2f * Gravity); + } + + // jump timeout + if (_jumpTimeoutDelta >= 0.0f) + { + _jumpTimeoutDelta -= Time.deltaTime; + } + } + else + { + // reset the jump timeout timer + _jumpTimeoutDelta = JumpTimeout; + + // fall timeout + if (_fallTimeoutDelta >= 0.0f) + { + _fallTimeoutDelta -= Time.deltaTime; + } + + // if we are not grounded, do not jump + _input.jump = false; + } + + // apply gravity over time if under terminal (multiply by delta time twice to linearly speed up over time) + if (_verticalVelocity < _terminalVelocity) + { + _verticalVelocity += Gravity * Time.deltaTime; + } + } + + private static float ClampAngle(float lfAngle, float lfMin, float lfMax) + { + if (lfAngle < -360f) lfAngle += 360f; + if (lfAngle > 360f) lfAngle -= 360f; + return Mathf.Clamp(lfAngle, lfMin, lfMax); + } + + private void OnDrawGizmosSelected() + { + Color transparentGreen = new Color(0.0f, 1.0f, 0.0f, 0.35f); + Color transparentRed = new Color(1.0f, 0.0f, 0.0f, 0.35f); + + if (Grounded) Gizmos.color = transparentGreen; + else Gizmos.color = transparentRed; + + // when selected, draw a gizmo in the position of, and matching radius of, the grounded collider + Gizmos.DrawSphere(new Vector3(transform.position.x, transform.position.y - GroundedOffset, transform.position.z), GroundedRadius); + } + } +} \ No newline at end of file diff --git a/Interactions.cs b/Interactions.cs new file mode 100644 index 0000000..06f59e0 --- /dev/null +++ b/Interactions.cs @@ -0,0 +1,37 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.UI; + +public class Interactions : MonoBehaviour +{ + public Text text; + public RectTransform panel; + private void Start() + { + panel.gameObject.SetActive(false); + } + private void FixedUpdate() + { + RaycastHit hit; + if (Physics.Raycast(transform.position, transform.forward, out hit, 5)) + { + if (hit.collider.gameObject.tag.Equals("POI")) + { + POI p = hit.collider.gameObject.GetComponent(); + panel.gameObject.SetActive(true); + text.text = p.gameObject.name; + if (p.broken && (Main.brokenStatus == true)) + text.text += " (Broken)"; + } + else + { + panel.gameObject.SetActive(false); + } + } + else + { + panel.gameObject.SetActive(false); + } + } +} diff --git a/Main.cs b/Main.cs new file mode 100644 index 0000000..33ee479 --- /dev/null +++ b/Main.cs @@ -0,0 +1,30 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.UI; + +public class Main : MonoBehaviour +{ + public static double budget; + public Text budgetText; + public Text costText; + public static double damageExpenses; + public static double markedExpenses; + public static int endCondition = 0; + public static float thevolume; + public AudioSource wind; + public static bool brokenStatus; + + void Start() + { + budget = damageExpenses + Random.Range(100, 1500); //for now just makes the budget how much everything costs + markedExpenses = 0; + budgetText.text = "Budget: $"+budget; + wind.volume = thevolume; + } + + private void Update() + { + costText.text = "Cost: $" + markedExpenses; + } +} diff --git a/MainMenu.cs b/MainMenu.cs new file mode 100644 index 0000000..86e9f9b --- /dev/null +++ b/MainMenu.cs @@ -0,0 +1,19 @@ +using System.Collections; +using System.Collections.Generic; +using Unity.VisualScripting; +using UnityEngine; +using UnityEngine.SceneManagement; +using UnityEngine.UI; +using UnityEngine.UIElements; +using Button = UnityEngine.UI.Button; + +public class MainMenu : MonoBehaviour +{ + public bool changeScene = false; + + public void ChangeScene(bool changeScene) + { + Main.damageExpenses = 0; + SceneManager.LoadScene("Menu"); + } +} \ No newline at end of file diff --git a/POI.cs b/POI.cs new file mode 100644 index 0000000..5835b55 --- /dev/null +++ b/POI.cs @@ -0,0 +1,36 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +public class POI : MonoBehaviour +{ + public int cost; + public int costAdded; + public int brokenProb; + public bool broken; + public Mesh brokenMesh; + + private void Awake() + { + costAdded = -1; + int rand = Random.Range(0, 100); + print(gameObject.name + " : " + rand); + if (rand < brokenProb) + { + broken = true; + GetComponent().sharedMesh = brokenMesh; + foreach(Transform child in transform) + { + child.gameObject.SetActive(false); + } + Main.damageExpenses += cost; + } + } + + public void toggleCost() + { + costAdded *= -1; + Main.markedExpenses += costAdded * cost; + } +} + + diff --git a/Timer.cs b/Timer.cs new file mode 100644 index 0000000..38744df --- /dev/null +++ b/Timer.cs @@ -0,0 +1,51 @@ +using UnityEngine; +using UnityEngine.UI; +using UnityEngine.SceneManagement; + +public class Timer : MonoBehaviour +{ + public float TimeLeft; + public bool TimerOn = false; + + public Text TimerTxt; + + void Start() + { + TimerOn = true; + } + + void Update() + { + if (TimerOn) + { + if (TimeLeft > 0) + { + TimeLeft -= Time.deltaTime; + updateTimer(TimeLeft); + } + else + { + Debug.Log("Time is UP!"); + TimeLeft = 0; + TimerOn = false; + Cursor.visible = true; + Cursor.lockState = CursorLockMode.None; + Main.endCondition = 1; //ran out of time + if (Main.markedExpenses == Main.damageExpenses) //maybe should also check if they actually picked the right stuff + Main.endCondition = 4; + SceneManager.LoadScene("End"); + } + } + } + + void updateTimer(float currentTime) + { + currentTime += 1; + + float minutes = Mathf.FloorToInt(currentTime / 60); + float seconds = Mathf.FloorToInt(currentTime % 60); + + TimerTxt.text = string.Format("{0:00}:{1:00}", minutes, seconds); + } + +} \ No newline at end of file diff --git a/endconditiontext.cs b/endconditiontext.cs new file mode 100644 index 0000000..ec8d880 --- /dev/null +++ b/endconditiontext.cs @@ -0,0 +1,41 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.UI; + +public class endconditiontext : MonoBehaviour +{ + public Text endText; + + // Start is called before the first frame update + void Awake() + { + int end = Main.endCondition; + if(end == 0) + { + endText.text = "You lose and i dont know why"; //error, don't use 0 + } + if (end == 1) + { + endText.text = "You ran out of time!"; + } + if (end == 2) + { + endText.text = "You lose! You didn't find all the broken parts and the ship sunk when it sailed next."; + } + if (end == 3) + { + endText.text = "You lose, you ran out of money upgrading incorrect things!"; + } + if (end == 4) + { + endText.text = "You win! You've identified all broken parts."; + } + } + + // Update is called once per frame + void Update() + { + + } +}