using System; using System.Collections; using System.Collections.Generic; using System.Linq; using Ichni.RhythmGame.Beatmap; using UniRx; using UnityEngine; using UnityEngine.Rendering.Universal; using UnityEngine.Serialization; namespace Ichni.RhythmGame { public partial class GameCamera : GameElement, IHaveTransformSubmodule, IHaveTimeDurationSubmodule { [FormerlySerializedAs("camera")] public new Camera gameCamera; public Transform rotationPoint; public Transform positionPoint; public Transform cameraTransform; public CameraViewType cameraViewType; public float perspectiveAngle; public float orthographicSize; public TransformSubmodule transformSubmodule { get; set; } public TimeDurationSubmodule timeDurationSubmodule { get; set; } private static CameraManager cameraManager => GameManager.instance.cameraManager; public static GameCamera GenerateElement(string elementName, Guid id, List tags, bool isFirstGenerated, GameElement parentElement, CameraViewType cameraViewType, float perspectiveAngle, float orthographicSize) { GameCamera gameCamera = Instantiate(GameManager.instance.basePrefabs.gameCamera).GetComponent(); gameCamera.Initialize(elementName, id, tags, isFirstGenerated, parentElement); cameraManager.gameCamera = gameCamera; gameCamera.parentElement = parentElement; gameCamera.cameraViewType = cameraViewType; gameCamera.gameCamera.orthographic = cameraViewType == CameraViewType.Orthographic; gameCamera.perspectiveAngle = perspectiveAngle; gameCamera.orthographicSize = orthographicSize; gameCamera.cameraTransform = gameCamera.transform; return gameCamera; } public override void AfterInitialize() { base.AfterInitialize(); gameCamera.GetComponent().cameraStack.Add(cameraManager.uiCamera); GameManager.instance.backgroundController.backgroundCanvas.worldCamera = gameCamera; } public override void SetDefaultSubmodules() { transformSubmodule = new TransformSubmodule(this); } } public partial class GameCamera { public enum CameraViewType { Perspective = 0, Orthographic = 1 } } public partial class GameCamera { private Vector3 GetWorldEulerAngles() { Vector3 output = transformSubmodule.originalEulerAngles; GameElement element = this; while (element != null) { if (element is IHaveTransformSubmodule) { output += ((TransformSubmodule)element.submoduleList.Where(r => r is TransformSubmodule).First()).currentEulerAngles; } element = element.parentElement; } return output; } public void SetTransformObserver() { Observable.EveryLateUpdate().Subscribe(_ => { if (!GameManager.instance.audioManager.isUpdating && transformSubmodule == null) { return; } bool willRefresh = false; if (transformSubmodule.eulerAnglesOffsetLock) { transform.localEulerAngles = transformSubmodule.originalEulerAngles; } else if (transformSubmodule.eulerAnglesDirtyMark) { Vector3 offset = Vector3.zero; foreach (Vector3 eulerOffset in transformSubmodule.eulerAnglesOffset) { offset += eulerOffset; } transformSubmodule.currentEulerAngles = transformSubmodule.originalEulerAngles + offset; transform.localEulerAngles = transformSubmodule.currentEulerAngles; transformSubmodule.eulerAnglesDirtyMark = false; willRefresh = true; } if (transformSubmodule.positionDirtyMark) { Vector3 offset = Vector3.zero; foreach (Vector3 posOffset in transformSubmodule.positionOffset) { offset += posOffset; } transformSubmodule.currentPosition = transformSubmodule.originalPosition + offset; transform.localPosition = transformSubmodule.currentPosition; transformSubmodule.positionDirtyMark = false; willRefresh = true; } if(willRefresh) { this.Refresh(); } transformSubmodule.eulerAnglesOffset.Clear(); transformSubmodule.positionOffset.Clear(); }).AddTo(gameObject); } } public partial class GameCamera { public override void SaveBM() { matchedBM = new GameCamera_BM(elementName, elementGuid, tags, parentElement.matchedBM as GameElement_BM, cameraViewType, perspectiveAngle, orthographicSize); } } namespace Beatmap { public class GameCamera_BM : GameElement_BM { public GameCamera.CameraViewType cameraViewType; public float perspectiveAngle; public float orthographicSize; public GameCamera_BM() { } public GameCamera_BM(string elementName, Guid elementGuid, List tags, GameElement_BM attachedElement, GameCamera.CameraViewType cameraViewType, float perspectiveAngle, float orthographicSize) : base(elementName, elementGuid, tags, attachedElement) { this.cameraViewType = cameraViewType; this.perspectiveAngle = perspectiveAngle; this.orthographicSize = orthographicSize; } public override void ExecuteBM() { matchedElement = GameCamera.GenerateElement(elementName, elementGuid, tags, false, GetElement(attachedElementGuid), cameraViewType, perspectiveAngle, orthographicSize); } public override GameElement DuplicateBM(GameElement parent) { return GameCamera.GenerateElement(elementName, Guid.NewGuid(), tags, false, parent, cameraViewType, perspectiveAngle, orthographicSize); } } } }