Files
Ultimate-Fishing-Simulator-…/Assets/Scripts/Assembly-CSharp/Camera3D.cs
2026-03-04 09:37:33 +08:00

290 lines
7.2 KiB
C#

using GISTech.GISTerrainLoader;
using UnityEngine;
public class Camera3D : MonoBehaviour
{
public KeyCode RotateLeft;
public KeyCode RotateRight;
public KeyCode ResetCameraPosKey;
[Header("Adapte Camera to GIS Container")]
public bool AdapteToGISContainer;
[Header("Camera Movements")]
public float PanSpeed = 0.1f;
public float RotationSpeed = 0.15f;
public float ZoomSpeed;
public float FollowSpeed = 0.1f;
public float SmoothingFactor = 0.1f;
[Header("Camera Parameters")]
[Space(4f)]
public bool UseKeyboardInput = true;
public bool UseMouseInput = true;
public bool AdaptToTerrainHeight = true;
public bool IncreaseSpeedWhenZoomedOut = true;
public bool CorrectZoomingOutRatio = true;
public bool Smoothing = true;
[Header("Follow a GameObject")]
public GameObject TargetToFollow;
[Header("Enable/Disbale Position On Start")]
public bool UseStartPosition;
public Vector3 StartPosition;
public Vector3 StartRotation;
private float mousepanSpeed = 15f;
private float mousezoomSpeed = 100f;
private Vector2 MinMaxZoom = new Vector2(0f, 0f);
private float minZoomDistance = 20f;
private float maxZoomDistance = 2f;
private Vector3 cameraTarget;
private float currentCameraDistance;
private Vector3 lastMousePos;
private Vector3 lastPanSpeed = Vector3.zero;
private Vector3 goingToCameraTarget = Vector3.zero;
private bool doingAutoMovement;
private Vector3 lastpos;
private Rect bound;
private GISTerrainContainer container;
private void OnEnable()
{
RuntimeTerrainGenerator.OnFinish += OnTerrainGenerated;
}
private void OnDisable()
{
RuntimeTerrainGenerator.OnFinish -= OnTerrainGenerated;
}
public void Start()
{
currentCameraDistance = minZoomDistance + (maxZoomDistance - minZoomDistance) / 2f;
base.transform.position = lastpos;
if (UseStartPosition)
{
GoTo(StartPosition);
base.transform.localEulerAngles = StartRotation;
}
}
public void Update()
{
if (Input.GetKeyDown(ResetCameraPosKey))
{
ResetCameraPosition();
}
UpdatePanning();
UpdateZooming();
UpdatePosition();
UpdateAutoMovement();
lastMousePos = Input.mousePosition;
}
public void GoTo(Vector3 position)
{
doingAutoMovement = true;
goingToCameraTarget = position;
TargetToFollow = null;
}
public void Follow(GameObject gameObjectToFollow)
{
TargetToFollow = gameObjectToFollow;
}
private void UpdatePanning()
{
Vector3 vector = new Vector3(0f, 0f, 0f);
if (UseKeyboardInput)
{
if (Input.GetKey(KeyCode.LeftArrow))
{
vector.x -= 1f;
}
if (Input.GetKey(KeyCode.DownArrow))
{
vector.z -= 1f;
}
if (Input.GetKey(KeyCode.RightArrow))
{
vector.x += 1f;
}
if (Input.GetKey(KeyCode.UpArrow))
{
vector.z += 1f;
}
}
if (UseMouseInput)
{
if (Input.GetMouseButton(0))
{
Vector3 vector2 = Input.mousePosition - lastMousePos;
vector += new Vector3(0f - vector2.x, 0f, 0f - vector2.y) * PanSpeed;
}
if (Input.GetMouseButton(2))
{
vector += new Vector3(0f, 0f - (Input.mousePosition - lastMousePos).y, 0f) * PanSpeed;
}
}
if (vector != Vector3.zero)
{
TargetToFollow = null;
doingAutoMovement = false;
}
Vector3 direction = vector;
if (Smoothing)
{
direction = (lastPanSpeed = Vector3.Lerp(lastPanSpeed, vector, SmoothingFactor));
}
float x = base.transform.localEulerAngles.x;
base.transform.SetLocalEulerAngles(0f);
float num = (IncreaseSpeedWhenZoomedOut ? Mathf.Sqrt(currentCameraDistance) : 1f);
cameraTarget += base.transform.TransformDirection(direction) * mousepanSpeed * num * Time.deltaTime;
base.transform.SetLocalEulerAngles(x);
}
private void UpdateZooming()
{
float num = 0f;
if (UseKeyboardInput)
{
if (Input.GetKey(KeyCode.F))
{
num = 1f;
}
if (Input.GetKey(KeyCode.R))
{
num = -1f;
}
}
if (!UseMouseInput)
{
return;
}
float axis = Input.GetAxis("Mouse ScrollWheel");
num -= axis * ZoomSpeed;
float num2 = (CorrectZoomingOutRatio ? ((currentCameraDistance - minZoomDistance) / (maxZoomDistance - minZoomDistance)) : 0f);
if (axis > 0f || axis < 0f)
{
float num3 = minZoomDistance * axis * ZoomSpeed * Time.deltaTime;
if (axis < 0f && minZoomDistance - num3 < MinMaxZoom.y)
{
minZoomDistance -= num3;
}
if (axis > 0f && minZoomDistance + num3 > MinMaxZoom.x)
{
minZoomDistance -= num3;
}
if (minZoomDistance <= MinMaxZoom.x)
{
minZoomDistance = MinMaxZoom.x;
}
float num4 = Mathf.Clamp(Mathf.Max(minZoomDistance, Mathf.Min(maxZoomDistance, currentCameraDistance + num * Time.deltaTime * mousezoomSpeed * (num2 * 2f + 1f))), MinMaxZoom.x, MinMaxZoom.y);
currentCameraDistance = num4;
}
}
private void UpdatePosition()
{
if (TargetToFollow != null && FollowSpeed > 0f)
{
cameraTarget = Vector3.Lerp(cameraTarget, TargetToFollow.transform.position, FollowSpeed);
}
if (base.transform.position != Vector3.zero && cameraTarget != Vector3.zero)
{
base.transform.position = cameraTarget;
base.transform.Translate(Vector3.back * currentCameraDistance);
}
if (AdapteToGISContainer)
{
if (cameraTarget.y >= MinMaxZoom.y)
{
cameraTarget = new Vector3(cameraTarget.x, MinMaxZoom.y, cameraTarget.z);
}
if (cameraTarget.x <= MinMaxZoom.x)
{
cameraTarget = new Vector3(cameraTarget.x, MinMaxZoom.x, cameraTarget.z);
}
float x = Mathf.Clamp(base.transform.position.x, bound.xMin, bound.xMax);
float y = Mathf.Clamp(base.transform.position.y, MinMaxZoom.x, MinMaxZoom.y);
float z = Mathf.Clamp(base.transform.position.z, bound.yMin, bound.yMax);
base.transform.position = new Vector3(x, y, z);
}
}
private void UpdateAutoMovement()
{
if (doingAutoMovement)
{
cameraTarget = Vector3.Lerp(cameraTarget, goingToCameraTarget, FollowSpeed);
if (Vector3.Distance(goingToCameraTarget, cameraTarget) < 1f)
{
doingAutoMovement = false;
}
}
}
private void OnDrawGizmosSelected()
{
if (AdapteToGISContainer)
{
Vector3 position = base.transform.position;
Gizmos.DrawLine(new Vector3(bound.xMin, position.y, bound.yMin), new Vector3(bound.xMin, position.y, bound.yMax));
Gizmos.DrawLine(new Vector3(bound.xMin, position.y, bound.yMax), new Vector3(bound.xMax, position.y, bound.yMax));
Gizmos.DrawLine(new Vector3(bound.xMax, position.y, bound.yMax), new Vector3(bound.xMax, position.y, bound.yMin));
Gizmos.DrawLine(new Vector3(bound.xMax, position.y, bound.yMin), new Vector3(bound.xMin, position.y, bound.yMin));
}
}
private void OnTerrainGenerated(GISTerrainContainer m_container)
{
container = m_container;
ResetCameraPosition();
}
public void ResetCameraPosition()
{
if (container != null)
{
bound = new Rect(new Vector2((0f - container.ContainerSize.x) / 2f, (0f - container.ContainerSize.z) / 2f), new Vector2(container.ContainerSize.x * 2f, container.ContainerSize.z * 2f));
Vector3 position = (cameraTarget = new Vector3(container.ContainerSize.x / 2f, (container.ContainerSize.x + container.ContainerSize.z) / 4f, container.ContainerSize.z / 2f));
base.transform.position = position;
lastpos = position;
base.enabled = true;
PanSpeed = container.Scale.x * 2f;
ZoomSpeed = container.Scale.x * 300f;
MinMaxZoom.x = 40f;
MinMaxZoom.y = (container.ContainerSize.x + container.ContainerSize.z) / 2f;
}
}
}