| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181 |
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using UnityEngine;
- namespace DunGen.Demo
- {
- [RequireComponent(typeof(CharacterController))]
- public class PlayerController : MonoBehaviour
- {
- public float MinYaw = -360;
- public float MaxYaw = 360;
- public float MinPitch = -60;
- public float MaxPitch = 60;
- public float LookSensitivity = 1;
- public float MoveSpeed = 10;
- public float TurnSpeed = 90;
- public bool IsControlling { get { return isControlling; } }
- public Camera ActiveCamera { get { return isControlling ? playerCamera : overheadCamera; } }
- protected CharacterController movementController;
- protected Camera playerCamera;
- protected Camera overheadCamera;
- protected bool isControlling;
- protected float yaw;
- protected float pitch;
- protected Generator gen;
- protected Vector3 velocity;
- protected virtual void Start()
- {
- movementController = GetComponent<CharacterController>();
- playerCamera = GetComponentInChildren<Camera>();
- gen = UnityUtil.FindObjectByType<Generator>();
- overheadCamera = GameObject.Find("Overhead Camera").GetComponent<Camera>();
- isControlling = true;
- ToggleControl();
- gen.DungeonGenerator.Generator.OnGenerationStatusChanged += OnGenerationStatusChanged;
- gen.GetAdditionalText = GetAdditionalScreenText;
- }
- protected virtual void OnDestroy()
- {
- gen.DungeonGenerator.Generator.OnGenerationStatusChanged -= OnGenerationStatusChanged;
- gen.GetAdditionalText = null;
- }
- private void GetAdditionalScreenText(StringBuilder infoText)
- {
- infoText.AppendLine("Press 'C' to switch between camera modes");
- }
- protected virtual void OnGenerationStatusChanged(DungeonGenerator generator, GenerationStatus status)
- {
- if (status == GenerationStatus.Complete)
- {
- FrameDungeonWithCamera();
- transform.position = new Vector3(0, 1, 7); // Hard-coded spawn position
- velocity = Vector3.zero;
- }
- }
- protected virtual void Update()
- {
- if (Input.GetKeyDown(KeyCode.C))
- ToggleControl();
- // Repeatedly frame the dungeon while the generation process is running
- var generator = gen.DungeonGenerator.Generator;
- if (generator.IsGenerating && generator.GenerateAsynchronously && generator.PauseBetweenRooms > 0f)
- FrameDungeonWithCamera();
- if (isControlling)
- {
- Vector3 direction = Vector3.zero;
- direction += transform.forward * Input.GetAxisRaw("Vertical");
- direction += transform.right * Input.GetAxisRaw("Horizontal");
- direction.Normalize();
- if (movementController.isGrounded)
- velocity = Vector3.zero;
- else
- velocity += -transform.up * (9.81f * 10) * Time.deltaTime; // Gravity
- direction += velocity * Time.deltaTime;
- movementController.Move(direction * Time.deltaTime * MoveSpeed);
- // Camera Look
- yaw += Input.GetAxisRaw("Mouse X") * LookSensitivity;
- pitch += Input.GetAxisRaw("Mouse Y") * LookSensitivity;
- yaw = ClampAngle(yaw, MinYaw, MaxYaw);
- pitch = ClampAngle(pitch, MinPitch, MaxPitch);
- transform.rotation = Quaternion.AngleAxis(yaw, Vector3.up);
- playerCamera.transform.localRotation = Quaternion.AngleAxis(pitch, -Vector3.right);
- }
- }
- protected float ClampAngle(float angle)
- {
- return ClampAngle(angle, 0, 360);
- }
- protected float ClampAngle(float angle, float min, float max)
- {
- if (angle < -360)
- angle += 360;
- if (angle > 360)
- angle -= 360;
- return Mathf.Clamp(angle, min, max);
- }
- protected void ToggleControl()
- {
- isControlling = !isControlling;
- overheadCamera.gameObject.SetActive(!isControlling);
- playerCamera.gameObject.SetActive(isControlling);
- overheadCamera.transform.position = new Vector3(transform.position.x, overheadCamera.transform.position.y, transform.position.z);
- Cursor.lockState = (isControlling) ? CursorLockMode.Locked : CursorLockMode.None;
- Cursor.visible = !isControlling;
- if (!isControlling)
- FrameDungeonWithCamera();
- }
- protected void FrameDungeonWithCamera()
- {
- var allDungeons = UnityUtil.FindObjectsByType<Dungeon>()
- .Select(x => x.gameObject)
- .ToArray();
- FrameObjectsWithCamera(allDungeons);
- }
- protected void FrameObjectsWithCamera(params GameObject[] gameObjects)
- {
- if (gameObjects == null || gameObjects.Length == 0)
- return;
- bool hasBounds = false;
- Bounds bounds = new Bounds();
- foreach(var obj in gameObjects)
- {
- var objBounds = UnityUtil.CalculateObjectBounds(obj, false, false);
- if (!hasBounds)
- {
- bounds = objBounds;
- hasBounds = true;
- }
- else
- bounds.Encapsulate(objBounds);
- }
- if (!hasBounds)
- return;
- float radius = Mathf.Max(bounds.size.x, bounds.size.z);
- float distance = radius / Mathf.Sin(overheadCamera.fieldOfView / 2);
- distance = Mathf.Abs(distance);
- Vector3 position = new Vector3(bounds.center.x, bounds.center.y, bounds.center.z);
- position += gen.DungeonGenerator.Generator.UpVector * distance;
- overheadCamera.transform.position = position;
- }
- }
- }
|