Files
ichni_Official/Assets/Scripts/Game/GameElements/Essential/GameCamera.cs
SoulliesOfficial 7c60c40d6b 同步
2026-06-05 04:45:57 -04:00

140 lines
5.0 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using DG.Tweening;
using Ichni.RhythmGame.Beatmap;
using Ichni.UI;
using UniRx;
using UnityEngine;
using UnityEngine.Rendering.Universal;
using UnityEngine.Serialization;
namespace Ichni.RhythmGame
{
public partial class GameCamera : GameElement, IHaveTransformSubmodule, IHaveTimeDurationSubmodule
{
#region [] Camera View & Settings
public Camera cam;
//public Transform rotationPoint;
//public Transform positionPoint;
public Transform cameraTransform;
public CameraViewType cameraViewType;
public float perspectiveAngle;
public float orthographicSize;
public float perspectiveOffset;
public float zoomOffset; // 用于效果如CameraZoomEffect的临时视野偏移
public void RefreshFOV()
{
cam.fieldOfView = perspectiveAngle + perspectiveOffset + zoomOffset;
}
#endregion
#region [] Submodules & References
public TransformSubmodule transformSubmodule { get; set; }
public TimeDurationSubmodule timeDurationSubmodule { get; set; }
private static CameraManager cameraManager => GameManager.Instance.cameraManager;
#endregion
#region [] Lifecycle & Factory
public static GameCamera GenerateElement(string elementName, Guid id,
List<string> tags, bool isFirstGenerated, GameElement parentElement,
CameraViewType cameraViewType, float perspectiveAngle, float orthographicSize)
{
GameCamera gameCamera = Instantiate(GameManager.Instance.basePrefabs.gameCamera).GetComponent<GameCamera>();
gameCamera.Initialize(elementName, id, tags, isFirstGenerated, parentElement);
cameraManager.gameCamera = gameCamera;
gameCamera.parentElement = parentElement;
gameCamera.cameraViewType = cameraViewType;
gameCamera.cam.orthographic = cameraViewType == CameraViewType.Orthographic;
gameCamera.perspectiveAngle = perspectiveAngle;
gameCamera.orthographicSize = orthographicSize;
gameCamera.cameraTransform = gameCamera.transform;
float ratioDifference = UIManager.GetScreenRatio() - UIManager.StandardRatio;
if (ratioDifference > 0)
{
//gameCamera.perspectiveOffset = 12.5f * ratioDifference;
}
else
{
gameCamera.perspectiveOffset = -25f * ratioDifference;
}
gameCamera.RefreshFOV();
return gameCamera;
}
public override void AfterInitialize()
{
base.AfterInitialize();
//gameCamera.GetComponent<UniversalAdditionalCameraData>().cameraStack.Add(cameraManager.uiCamera);
GameManager.Instance.backgroundController.backgroundCanvas.worldCamera = cam;
}
public override void SetDefaultSubmodules()
{
transformSubmodule = new TransformSubmodule(this);
}
#endregion
}
#region [] Enums
public partial class GameCamera
{
public enum CameraViewType
{
Perspective = 0,
Orthographic = 1
}
}
#endregion
#region [] Transform Observe & Update Logics
public partial class GameCamera
{
public void SetTransformObserver()
{
transformSubmodule.observer = Observable.EveryLateUpdate()
.Where(_=>GameManager.Instance.songPlayer.isUpdating)
.Subscribe(_ => UpdateTransform())
.AddTo(transformSubmodule.attachedGameElement);
}
public void UpdateTransform(bool refreshAll = true)
{
bool willRefresh = false;
if (!transformSubmodule.eulerAnglesOffsetLock && transformSubmodule.eulerAnglesDirtyMark)
{
transformSubmodule.currentEulerAngles = transformSubmodule.originalEulerAngles + transformSubmodule.eulerAnglesOffset;
transform.localEulerAngles = transformSubmodule.currentEulerAngles;
transformSubmodule.eulerAnglesDirtyMark = false;
willRefresh = true;
transformSubmodule.eulerAnglesOffset = Vector3.zero;
}
if (transformSubmodule.positionDirtyMark)
{
transformSubmodule.currentPosition = transformSubmodule.originalPosition + transformSubmodule.positionOffset;
transform.localPosition = transformSubmodule.currentPosition;
transformSubmodule.positionDirtyMark = false;
willRefresh = true;
transformSubmodule.positionOffset = Vector3.zero;
}
if (refreshAll && willRefresh)
{
Refresh();
}
}
}
#endregion
}