PlayerController.cs 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. using System.Collections.Generic;
  2. using System.Linq;
  3. using System.Text;
  4. using UnityEngine;
  5. namespace DunGen.Demo
  6. {
  7. [RequireComponent(typeof(CharacterController))]
  8. public class PlayerController : MonoBehaviour
  9. {
  10. public float MinYaw = -360;
  11. public float MaxYaw = 360;
  12. public float MinPitch = -60;
  13. public float MaxPitch = 60;
  14. public float LookSensitivity = 1;
  15. public float MoveSpeed = 10;
  16. public float TurnSpeed = 90;
  17. public bool IsControlling { get { return isControlling; } }
  18. public Camera ActiveCamera { get { return isControlling ? playerCamera : overheadCamera; } }
  19. protected CharacterController movementController;
  20. protected Camera playerCamera;
  21. protected Camera overheadCamera;
  22. protected bool isControlling;
  23. protected float yaw;
  24. protected float pitch;
  25. protected Generator gen;
  26. protected Vector3 velocity;
  27. protected virtual void Start()
  28. {
  29. movementController = GetComponent<CharacterController>();
  30. playerCamera = GetComponentInChildren<Camera>();
  31. gen = UnityUtil.FindObjectByType<Generator>();
  32. overheadCamera = GameObject.Find("Overhead Camera").GetComponent<Camera>();
  33. isControlling = true;
  34. ToggleControl();
  35. gen.DungeonGenerator.Generator.OnGenerationStatusChanged += OnGenerationStatusChanged;
  36. gen.GetAdditionalText = GetAdditionalScreenText;
  37. }
  38. protected virtual void OnDestroy()
  39. {
  40. gen.DungeonGenerator.Generator.OnGenerationStatusChanged -= OnGenerationStatusChanged;
  41. gen.GetAdditionalText = null;
  42. }
  43. private void GetAdditionalScreenText(StringBuilder infoText)
  44. {
  45. infoText.AppendLine("Press 'C' to switch between camera modes");
  46. }
  47. protected virtual void OnGenerationStatusChanged(DungeonGenerator generator, GenerationStatus status)
  48. {
  49. if (status == GenerationStatus.Complete)
  50. {
  51. FrameDungeonWithCamera();
  52. transform.position = new Vector3(0, 1, 7); // Hard-coded spawn position
  53. velocity = Vector3.zero;
  54. }
  55. }
  56. protected virtual void Update()
  57. {
  58. if (Input.GetKeyDown(KeyCode.C))
  59. ToggleControl();
  60. // Repeatedly frame the dungeon while the generation process is running
  61. var generator = gen.DungeonGenerator.Generator;
  62. if (generator.IsGenerating && generator.GenerateAsynchronously && generator.PauseBetweenRooms > 0f)
  63. FrameDungeonWithCamera();
  64. if (isControlling)
  65. {
  66. Vector3 direction = Vector3.zero;
  67. direction += transform.forward * Input.GetAxisRaw("Vertical");
  68. direction += transform.right * Input.GetAxisRaw("Horizontal");
  69. direction.Normalize();
  70. if (movementController.isGrounded)
  71. velocity = Vector3.zero;
  72. else
  73. velocity += -transform.up * (9.81f * 10) * Time.deltaTime; // Gravity
  74. direction += velocity * Time.deltaTime;
  75. movementController.Move(direction * Time.deltaTime * MoveSpeed);
  76. // Camera Look
  77. yaw += Input.GetAxisRaw("Mouse X") * LookSensitivity;
  78. pitch += Input.GetAxisRaw("Mouse Y") * LookSensitivity;
  79. yaw = ClampAngle(yaw, MinYaw, MaxYaw);
  80. pitch = ClampAngle(pitch, MinPitch, MaxPitch);
  81. transform.rotation = Quaternion.AngleAxis(yaw, Vector3.up);
  82. playerCamera.transform.localRotation = Quaternion.AngleAxis(pitch, -Vector3.right);
  83. }
  84. }
  85. protected float ClampAngle(float angle)
  86. {
  87. return ClampAngle(angle, 0, 360);
  88. }
  89. protected float ClampAngle(float angle, float min, float max)
  90. {
  91. if (angle < -360)
  92. angle += 360;
  93. if (angle > 360)
  94. angle -= 360;
  95. return Mathf.Clamp(angle, min, max);
  96. }
  97. protected void ToggleControl()
  98. {
  99. isControlling = !isControlling;
  100. overheadCamera.gameObject.SetActive(!isControlling);
  101. playerCamera.gameObject.SetActive(isControlling);
  102. overheadCamera.transform.position = new Vector3(transform.position.x, overheadCamera.transform.position.y, transform.position.z);
  103. Cursor.lockState = (isControlling) ? CursorLockMode.Locked : CursorLockMode.None;
  104. Cursor.visible = !isControlling;
  105. if (!isControlling)
  106. FrameDungeonWithCamera();
  107. }
  108. protected void FrameDungeonWithCamera()
  109. {
  110. var allDungeons = UnityUtil.FindObjectsByType<Dungeon>()
  111. .Select(x => x.gameObject)
  112. .ToArray();
  113. FrameObjectsWithCamera(allDungeons);
  114. }
  115. protected void FrameObjectsWithCamera(params GameObject[] gameObjects)
  116. {
  117. if (gameObjects == null || gameObjects.Length == 0)
  118. return;
  119. bool hasBounds = false;
  120. Bounds bounds = new Bounds();
  121. foreach(var obj in gameObjects)
  122. {
  123. var objBounds = UnityUtil.CalculateObjectBounds(obj, false, false);
  124. if (!hasBounds)
  125. {
  126. bounds = objBounds;
  127. hasBounds = true;
  128. }
  129. else
  130. bounds.Encapsulate(objBounds);
  131. }
  132. if (!hasBounds)
  133. return;
  134. float radius = Mathf.Max(bounds.size.x, bounds.size.z);
  135. float distance = radius / Mathf.Sin(overheadCamera.fieldOfView / 2);
  136. distance = Mathf.Abs(distance);
  137. Vector3 position = new Vector3(bounds.center.x, bounds.center.y, bounds.center.z);
  138. position += gen.DungeonGenerator.Generator.UpVector * distance;
  139. overheadCamera.transform.position = position;
  140. }
  141. }
  142. }