471 lines
14 KiB (Stored with Git LFS)
C#
471 lines
14 KiB (Stored with Git LFS)
C#
using System;
|
|
using System.Collections.Generic;
|
|
using Superlazy;
|
|
using UnityEngine;
|
|
|
|
public abstract class CameraOperation
|
|
{
|
|
public virtual Vector3 CenterDelta { get; } = Vector3.zero;
|
|
public virtual Vector3 OffsetDelta { get; } = Vector3.zero;
|
|
public virtual float DistDelta { get; } = 0;
|
|
public virtual float LatitudeDelta { get; } = 0;
|
|
|
|
public virtual float OffsetRotationDelta { get; } = 0;
|
|
public abstract bool IsEnd { get; }
|
|
|
|
public abstract void Play();
|
|
}
|
|
|
|
public class CameraZoom : CameraOperation
|
|
{
|
|
private readonly float fadeTime;
|
|
private readonly float fadeDelay;
|
|
private readonly float targetDist;
|
|
private float currentTime;
|
|
private float currentZoom;
|
|
private float zoomDelta;
|
|
|
|
public CameraZoom(float targetDist, float fadeTime, float fadeDelay)
|
|
{
|
|
this.fadeTime = fadeTime;
|
|
this.fadeDelay = fadeDelay;
|
|
currentTime = 0.0f;
|
|
|
|
targetDist = targetDist + SLGame.Session["CameraView"]["DestDistance"] - SLGame.Session["CameraView"]["DestDistance"];
|
|
|
|
this.targetDist = targetDist;
|
|
|
|
SLGame.Session["CameraView"]["DestDistance"] += targetDist;
|
|
}
|
|
|
|
public override float DistDelta => zoomDelta;
|
|
public override bool IsEnd => currentTime > fadeTime + fadeDelay;
|
|
|
|
public override void Play()
|
|
{
|
|
currentTime += Time.smoothDeltaTime;
|
|
|
|
if (currentTime - fadeDelay > 0 && currentTime - fadeDelay < fadeTime)
|
|
{
|
|
var t = Mathf.SmoothStep(0, 1, (currentTime - fadeDelay) / fadeTime);
|
|
|
|
zoomDelta = t * targetDist - currentZoom;
|
|
currentZoom = t * targetDist;
|
|
}
|
|
else if (currentTime - fadeDelay >= fadeTime)
|
|
{
|
|
zoomDelta = targetDist - currentZoom;
|
|
currentZoom = targetDist;
|
|
}
|
|
}
|
|
}
|
|
|
|
public class CameraMove : CameraOperation
|
|
{
|
|
private readonly Vector3 direction;
|
|
private readonly float fadeTime;
|
|
private readonly float fadeDelay;
|
|
private float currentTime;
|
|
private Vector3 currentCenter;
|
|
private Vector3 centerDelta;
|
|
|
|
public CameraMove(Vector3 direction, float fadeTime, float fadeDelay)
|
|
{
|
|
this.fadeTime = fadeTime;
|
|
this.fadeDelay = fadeDelay;
|
|
currentTime = 0.0f;
|
|
currentCenter = Vector3.zero;
|
|
|
|
this.direction = direction;
|
|
var cameraView = SLGame.Session["CameraView"];
|
|
var dest = cameraView["Dest"].ToVector3() + direction;
|
|
dest.x = Mathf.Clamp(dest.x, cameraView["MinX"], cameraView["MaxX"]);
|
|
dest.z = Mathf.Clamp(dest.z, cameraView["MinZ"], cameraView["MaxZ"]);
|
|
SLGame.Session["CameraView"]["Dest"] = dest.ToEntity();
|
|
}
|
|
|
|
public override Vector3 CenterDelta => centerDelta;
|
|
public override bool IsEnd => currentTime > fadeTime + fadeDelay;
|
|
|
|
public override void Play()
|
|
{
|
|
currentTime += Time.deltaTime;
|
|
|
|
if (currentTime - fadeDelay > 0 && currentTime - fadeDelay < fadeTime)
|
|
{
|
|
var t = (currentTime - fadeDelay) / fadeTime;
|
|
|
|
var newCenter = Vector3.Lerp(Vector3.zero, direction, t);
|
|
|
|
centerDelta = newCenter - currentCenter;
|
|
|
|
currentCenter = newCenter;
|
|
}
|
|
else if (currentTime - fadeDelay >= fadeTime)
|
|
{
|
|
centerDelta = direction - currentCenter;
|
|
|
|
currentCenter = direction;
|
|
}
|
|
}
|
|
}
|
|
|
|
public class CameraOffset : CameraOperation
|
|
{
|
|
private readonly Vector3 direction;
|
|
private readonly float fadeTime;
|
|
private readonly float fadeDelay;
|
|
private float currentTime;
|
|
private Vector3 currentCenter;
|
|
private Vector3 centerDelta;
|
|
|
|
public CameraOffset(Vector3 direction, float fadeTime, float fadeDelay)
|
|
{
|
|
this.fadeTime = fadeTime;
|
|
this.fadeDelay = fadeDelay;
|
|
currentTime = 0.0f;
|
|
currentCenter = Vector3.zero;
|
|
|
|
this.direction = direction;
|
|
|
|
var dest = SLGame.Session["CameraView"]["DestOffset"].ToVector3() + direction;
|
|
SLGame.Session["CameraView"]["DestOffset"] = dest.ToEntity();
|
|
}
|
|
|
|
public override Vector3 OffsetDelta => centerDelta;
|
|
public override bool IsEnd => currentTime > fadeTime + fadeDelay;
|
|
|
|
public override void Play()
|
|
{
|
|
currentTime += Time.smoothDeltaTime;
|
|
|
|
if (currentTime - fadeDelay > 0 && currentTime - fadeDelay < fadeTime)
|
|
{
|
|
var t = (currentTime - fadeDelay) / fadeTime;
|
|
|
|
var newCenter = Vector3.Slerp(Vector3.zero, direction, t);
|
|
|
|
centerDelta = newCenter - currentCenter;
|
|
|
|
currentCenter = newCenter;
|
|
}
|
|
else if (currentTime - fadeDelay >= fadeTime)
|
|
{
|
|
centerDelta = direction - currentCenter;
|
|
|
|
currentCenter = direction;
|
|
}
|
|
}
|
|
}
|
|
|
|
public class CameraShake : CameraOperation
|
|
{
|
|
private readonly Vector3 direction;
|
|
private readonly float fadeTime;
|
|
private readonly float fadeDelay;
|
|
private float currentTime;
|
|
private Vector3 currentCenter;
|
|
private Vector3 centerDelta;
|
|
private readonly int count;
|
|
|
|
public CameraShake(Vector3 direction, int count, float fadeTime, float fadeDelay)
|
|
{
|
|
this.fadeTime = fadeTime;
|
|
this.fadeDelay = fadeDelay;
|
|
this.count = count;
|
|
currentTime = 0.0f;
|
|
currentCenter = Vector3.zero;
|
|
|
|
this.direction = direction;
|
|
}
|
|
|
|
public override Vector3 CenterDelta => centerDelta;
|
|
public override bool IsEnd => currentTime > fadeTime + fadeDelay;
|
|
|
|
public override void Play()
|
|
{
|
|
currentTime += Time.smoothDeltaTime;
|
|
|
|
if (currentTime - fadeDelay > 0 && currentTime - fadeDelay < fadeTime)
|
|
{
|
|
var t = (currentTime - fadeDelay) / fadeTime * count;
|
|
|
|
var shakeAmount = direction.magnitude * (count - t);
|
|
var shakeDir = direction.normalized;
|
|
|
|
var shakeValue = Mathf.Cos((1 - t) * 360 * 2) * shakeAmount * shakeDir;
|
|
|
|
centerDelta = shakeValue - currentCenter;
|
|
|
|
currentCenter = shakeValue;
|
|
}
|
|
else if (currentTime - fadeDelay >= fadeTime)
|
|
{
|
|
centerDelta = direction - currentCenter;
|
|
|
|
currentCenter = direction;
|
|
}
|
|
}
|
|
}
|
|
|
|
public class CameraRotation : CameraOperation
|
|
{
|
|
private readonly float fadeTime;
|
|
private readonly float fadeDelay;
|
|
private float currentTime;
|
|
private float current;
|
|
private float currentDelta;
|
|
private readonly float delta;
|
|
|
|
public CameraRotation(float delta, float fadeTime, float fadeDelay)
|
|
{
|
|
this.fadeTime = fadeTime;
|
|
this.fadeDelay = fadeDelay;
|
|
currentTime = 0.0f;
|
|
this.delta = delta;
|
|
|
|
SLGame.Session["CameraView"]["DestOffsetRotation"] += delta;
|
|
}
|
|
|
|
public override float OffsetRotationDelta => current;
|
|
public override bool IsEnd => currentTime > fadeTime + fadeDelay;
|
|
|
|
public override void Play()
|
|
{
|
|
currentTime += Time.smoothDeltaTime;
|
|
|
|
if (currentTime - fadeDelay > 0 && currentTime - fadeDelay < fadeTime)
|
|
{
|
|
var t = (currentTime - fadeDelay) / fadeTime;
|
|
var tv = Mathf.Sin(t * Mathf.PI - Mathf.PI / 2) * 0.5f + 0.5f;
|
|
if (t < 0.5f)
|
|
{
|
|
t = Mathf.Pow(tv, 3);
|
|
}
|
|
else
|
|
{
|
|
t = 1 - Mathf.Pow(1 - tv, 3);
|
|
}
|
|
|
|
current = t * delta - currentDelta;
|
|
|
|
currentDelta = t * delta;
|
|
}
|
|
else if (currentTime - fadeDelay >= fadeTime)
|
|
{
|
|
current = delta - currentDelta;
|
|
|
|
currentDelta = current;
|
|
}
|
|
}
|
|
}
|
|
|
|
public class CameraLatitude : CameraOperation
|
|
{
|
|
private readonly float latitude;
|
|
private readonly float fadeTime;
|
|
private readonly float fadeDelay;
|
|
private readonly float targetLatitude;
|
|
|
|
private float currentTime;
|
|
private float currentLatitude;
|
|
private float latitudeDelta;
|
|
|
|
public CameraLatitude(float latitude, float fadeTime, float fadeDelay)
|
|
{
|
|
this.fadeTime = fadeTime;
|
|
this.fadeDelay = fadeDelay;
|
|
currentTime = 0.0f;
|
|
|
|
targetLatitude = latitude;
|
|
|
|
SLGame.Session["CameraView"]["DestLatitude"] += targetLatitude;
|
|
}
|
|
|
|
public override float LatitudeDelta => latitudeDelta;
|
|
|
|
public override bool IsEnd => currentTime > fadeTime + fadeDelay;
|
|
|
|
public override void Play()
|
|
{
|
|
currentTime += Time.smoothDeltaTime;
|
|
|
|
if (currentTime - fadeDelay > 0 && currentTime - fadeDelay < fadeTime)
|
|
{
|
|
var t = Mathf.SmoothStep(0, 1, (currentTime - fadeDelay) / fadeTime);
|
|
|
|
latitudeDelta = t * targetLatitude - currentLatitude;
|
|
currentLatitude = t * targetLatitude;
|
|
}
|
|
else if (currentTime - fadeDelay >= fadeTime)
|
|
{
|
|
latitudeDelta = targetLatitude - currentLatitude;
|
|
currentLatitude = targetLatitude;
|
|
}
|
|
}
|
|
}
|
|
|
|
public class SLCamera : MonoBehaviour
|
|
{
|
|
public static float minCameraDist = 0;
|
|
public static float maxCameraDist = 900;
|
|
|
|
public float latitude = 40;
|
|
public int longtitude = 40;
|
|
public float distance = 900;
|
|
public Vector3 center = Vector3.zero;
|
|
public Vector3 offset = Vector3.zero;
|
|
public float offsetRotation = 0;
|
|
|
|
private readonly List<CameraOperation> operations = new List<CameraOperation>();
|
|
|
|
private float cameraDist;
|
|
private Camera[] cams;
|
|
private readonly Transform background;
|
|
|
|
private string positionBind = string.Empty;
|
|
private int stopDist;
|
|
private int moveDist;
|
|
|
|
private Camera[] Cams
|
|
{
|
|
get
|
|
{
|
|
if (cams == null)
|
|
{
|
|
cams = GetComponentsInChildren<Camera>();
|
|
cameraDist = cams[0].farClipPlane;
|
|
}
|
|
|
|
return cams;
|
|
}
|
|
}
|
|
|
|
private void LateUpdate()
|
|
{
|
|
foreach (var op in operations)
|
|
{
|
|
op.Play();
|
|
center += op.CenterDelta;
|
|
distance += op.DistDelta;
|
|
latitude += op.LatitudeDelta;
|
|
offset += op.OffsetDelta;
|
|
offsetRotation += op.OffsetRotationDelta;
|
|
}
|
|
|
|
operations.RemoveAll(op => op.IsEnd);
|
|
|
|
if (operations.Count == 0)
|
|
{
|
|
center = SLGame.Session["CameraView"]["Dest"].ToVector3();
|
|
distance = SLGame.Session["CameraView"]["DestDistance"];
|
|
latitude = SLGame.Session["CameraView"]["DestLatitude"];
|
|
offset = SLGame.Session["CameraView"]["DestOffset"].ToVector3();
|
|
offsetRotation = SLGame.Session["CameraView"]["DestOffsetRotation"];
|
|
}
|
|
|
|
if (string.IsNullOrEmpty(positionBind) == false)
|
|
{
|
|
var destCenter = SLGame.SessionGet(positionBind).ToVector3();
|
|
|
|
var targetDist = moveDist;
|
|
if (destCenter == center) targetDist = stopDist;
|
|
|
|
center = destCenter;
|
|
SLGame.Session["CameraView"]["Dest"] = destCenter.ToEntity();
|
|
}
|
|
|
|
{
|
|
var mainCam = Cams[0];
|
|
var dist = distance;
|
|
if (mainCam.aspect < 1.77f/*16.0f/9.0f*/)
|
|
{
|
|
foreach (var cam in Cams)
|
|
{
|
|
cam.farClipPlane = 1.7777f / mainCam.aspect * cameraDist;
|
|
}
|
|
|
|
dist = dist * 1.7777f / mainCam.aspect;
|
|
}
|
|
else
|
|
{
|
|
foreach (var cam in Cams)
|
|
{
|
|
cam.farClipPlane = cameraDist;
|
|
}
|
|
}
|
|
|
|
{
|
|
var safeWidthtRate = Screen.width / Screen.safeArea.width;
|
|
var safeHeightRate = Screen.height / Screen.safeArea.height;
|
|
|
|
dist *= Mathf.Max(safeWidthtRate, safeHeightRate);
|
|
}
|
|
|
|
transform.SetPositionAndRotation(Quaternion.Euler(latitude, longtitude, 0) * Vector3.back * dist - transform.rotation * offset + center, Quaternion.Euler(latitude, longtitude + offsetRotation, 0));
|
|
|
|
SLGame.Session["CameraView"]["Center"] = center.ToEntity();
|
|
SLGame.Session["CameraView"]["Distance"] = distance;
|
|
SLGame.Session["CameraView"]["Offset"] = offset.ToEntity();
|
|
SLGame.Session["CameraView"]["Latitude"] = latitude;
|
|
SLGame.Session["CameraView"]["OffsetRotation"] = offsetRotation;
|
|
}
|
|
}
|
|
|
|
public void Play(CameraOperation op)
|
|
{
|
|
operations.Add(op);
|
|
}
|
|
|
|
private void Clear()
|
|
{
|
|
operations.Clear();
|
|
}
|
|
|
|
public void InitCamera(int latitude, int distance, Vector3 center, Vector3 offset)
|
|
{
|
|
Clear();
|
|
this.latitude = latitude;
|
|
this.distance = distance;
|
|
this.center = center;
|
|
this.offset = offset;
|
|
|
|
SLGame.Session["CameraView"]["Dest"] = this.center.ToEntity();
|
|
SLGame.Session["CameraView"]["Center"] = this.center.ToEntity();
|
|
SLGame.Session["CameraView"]["DestDistance"] = this.distance;
|
|
SLGame.Session["CameraView"]["Distance"] = this.distance;
|
|
SLGame.Session["CameraView"]["DestOffset"] = this.offset.ToEntity();
|
|
SLGame.Session["CameraView"]["Offset"] = this.offset.ToEntity();
|
|
SLGame.Session["CameraView"]["DestLatitude"] = this.latitude;
|
|
SLGame.Session["CameraView"]["Latitude"] = this.latitude;
|
|
SLGame.Session["CameraView"]["DestOffsetRotation"] = 0;
|
|
SLGame.Session["CameraView"]["OffsetRotation"] = 0;
|
|
SLGame.Session["CameraView"]["MinX"] = float.MinValue;
|
|
SLGame.Session["CameraView"]["MinZ"] = float.MinValue;
|
|
SLGame.Session["CameraView"]["MaxX"] = float.MaxValue;
|
|
SLGame.Session["CameraView"]["MaxZ"] = float.MaxValue;
|
|
}
|
|
|
|
public void AnchorBind(string anchorPosition, int stopDist, int moveDist, float zoomSpeed)
|
|
{
|
|
if (string.IsNullOrEmpty(anchorPosition))
|
|
{
|
|
positionBind = null;
|
|
}
|
|
else
|
|
{
|
|
positionBind = anchorPosition;
|
|
|
|
this.stopDist = stopDist;
|
|
this.moveDist = moveDist;
|
|
}
|
|
}
|
|
|
|
public void SetBound(float minX, float minZ, float maxX, float maxZ)
|
|
{
|
|
SLGame.Session["CameraView"]["MinX"] = minX;
|
|
SLGame.Session["CameraView"]["MinZ"] = minZ;
|
|
SLGame.Session["CameraView"]["MaxX"] = maxX;
|
|
SLGame.Session["CameraView"]["MaxZ"] = maxZ;
|
|
}
|
|
} |