You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

235 lines
6.8 KiB

using DG.Tweening;
using DG.Tweening.Core;
using DG.Tweening.Plugins.Options;
using UnityEngine;
#if UNITY_EDITOR
[ExecuteInEditMode]
//[RequireComponent(typeof(Camera))]
#endif
public class IVCameraController : MonoBehaviour
{
protected static IVCameraController curMgr = null;
protected Transform trfWrapper;
protected Transform trfCamera;
protected Camera cameraControl;
protected bool isShake;
[SerializeField]
private int _vibatro = 1;
// Set this to the in-world distance between the left & right edges of your scene.
[SerializeField]
protected float sceneWidth = 40f;
[SerializeField]
protected float[] minZooms = new float[3] { 6.5f, 8f, 9.5f };
[SerializeField]
protected float[] maxZooms = new float[3] { 9.5f, 12f, 13.5f };
[SerializeField]
protected float maxX = 25f;
[SerializeField]
protected float maxY = 25f;
protected static float[] cameraSize = new float[3] { 10f, 10f, 10f };
protected static float[] fClampXMin = new float[3] { -5f, -5f, -5f };
protected static float[] fClampXMax = new float[3] { 5f, 5f, 5f };
protected static float[] fClampYMin = new float[3] { -20f, -20f, -20f };
protected static float[] fClampYMax = new float[3] { 20f, 20f, 20f };
//protected static Vector3 v3ClampMin = new Vector3(-5f, -20f, -20f);
//protected static Vector3 v3ClampMax = new Vector3(5f, 20f, -20f);
#if UNITY_EDITOR
private bool bInitNeed = true;
#endif
protected Transform trfTarget;
protected bool bTraceTarget = false;
protected int iZoom = 1;
protected bool isShaking = false;
protected float saveStrength;
TweenerCore<Vector3, Vector3, VectorOptions> twcMove = null;
protected Vector3 v3MoveTo = Vector3.zero;
void Start()
{
curMgr = this;
trfWrapper = transform;
trfCamera = trfWrapper.GetChild(0);
cameraControl = trfCamera.GetComponent<Camera>();
#if UNITY_EDITOR
bInitNeed = false;
#endif
InitCamera();
}
void LateUpdate()
{
if (cameraControl == null || trfWrapper == null)
return;
#if UNITY_EDITOR
bInitNeed = false;
if (bInitNeed)
InitCamera();
#endif
if (bTraceTarget && trfTarget != null)
MoveCamera(trfTarget.position);
}
// 카메라 초기화.
protected void InitCamera()
{
if (cameraControl == null || trfWrapper == null)
return;
float unitsPerPixel = sceneWidth / Screen.width;
float aspectRatio = (float)Screen.width / Screen.height;
cameraSize[1] = 0.5f * unitsPerPixel * Screen.height;
cameraSize[0] = cameraSize[1] * 0.8f;
cameraSize[2] = cameraSize[1] * 1.2f;
for (int i = 0; i < cameraSize.Length; i++)
{
if (cameraSize[i] > maxZooms[i])
cameraSize[i] = maxZooms[i];
else if (cameraSize[i] < minZooms[i])
cameraSize[i] = minZooms[i];
float fx = maxX - (cameraSize[i] * aspectRatio);
fClampXMax[i] = fx;
fClampXMin[i] = fx * -1f;
float fy = maxY - cameraSize[i];
fClampYMax[i] = fy - 1.5f; // CameraWrapper 안의 mainCamera 위치 고려.
fClampYMin[i] = fClampYMax[i] * -1f - 1.5f;
}
iZoom = ES3.Load(Global.ES3_Zoom, 1);
cameraControl.orthographicSize = cameraSize[iZoom];
}
// 추적 타겟 설정.
public static void SSetTarget(Transform trftarget)
{
if (curMgr == null)
return;
curMgr.trfTarget = trftarget;
}
// 추적 On/Off.
public static void SSetTrace(bool btrace)
{
if (curMgr == null)
return;
curMgr.bTraceTarget = btrace;
}
// 카메라 흔들기.
public static void SShakeCamera(float fduration, float strength, int ivibrato = 100)
{
if (curMgr == null || curMgr.trfCamera == null || !curMgr.isShake)// || !curMgr.isShake
return;
//curMgr.StartCoroutine(curMgr.Shake(fduration, strength));
if(strength > curMgr.saveStrength)
{
curMgr.isShaking = true;
curMgr.saveStrength = strength;
curMgr.trfCamera.DOShakePosition(fduration, strength, ivibrato, randomnessMode: ShakeRandomnessMode.Harmonic).OnComplete(curMgr.setFalseShake); // vibrato : 1000,
}
}
public void setFalseShake()
{
trfCamera.localPosition = Global.V3_Camera;
isShaking = false;
saveStrength = 0;
}
public static void SSetShake(bool value)
{
curMgr.isShake = value;
}
public static bool SgetShake()
{
return curMgr.isShake;
}
public static int SChangeZoom()
{
if (curMgr == null)
return 1;
return curMgr.ChangeZoom();
}
// 줌 변경.
protected int ChangeZoom()
{
// MoveToCamera로 이동중일 경우.
if (twcMove != null && twcMove.IsPlaying())
return iZoom;
iZoom++;
if (iZoom >= cameraSize.Length)
iZoom = 0;
ES3.Save(Global.ES3_Zoom, iZoom);
cameraControl.orthographicSize = cameraSize[iZoom];
if (bTraceTarget)
{
//MoveCamera(trfTarget.position);
}
else
{
MoveCamera(trfWrapper.position);
}
return iZoom;
}
public static int SGetZoom()
{
if (curMgr == null)
return 1;
return curMgr.iZoom;
}
public static void SMoveToCamera(float fduration, Vector3 v3worldpos)
{
if (curMgr == null || curMgr.trfWrapper == null)
return;
curMgr.MoveToCamera(fduration, v3worldpos);
}
// 일정 시간에 걸쳐서 특정 위치로 이동.
protected void MoveToCamera(float fduration, Vector3 v3worldpos)
{
v3MoveTo = v3worldpos;
v3worldpos.x = Mathf.Clamp(v3worldpos.x, fClampXMin[iZoom], fClampXMax[iZoom]);
v3worldpos.y = Mathf.Clamp(v3worldpos.y, fClampYMin[iZoom], fClampYMax[iZoom]);
v3worldpos.z = trfWrapper.position.z;
twcMove = trfWrapper.DOMove(v3worldpos, fduration);
}
public static void SMoveCamera(Vector3 v3worldpos)
{
if (curMgr == null || curMgr.trfWrapper == null)
return;
curMgr.MoveCamera(v3worldpos);
}
// 특정 위치로 바로 이동.
protected void MoveCamera(Vector3 v3worldpos)
{
v3worldpos.x = Mathf.Clamp(v3worldpos.x, fClampXMin[iZoom], fClampXMax[iZoom]);
v3worldpos.y = Mathf.Clamp(v3worldpos.y, fClampYMin[iZoom], fClampYMax[iZoom]);
v3worldpos.z = trfWrapper.position.z;
trfWrapper.position = v3worldpos;
}
public static void CameraXRangeChange(int x)
{
curMgr.maxX = x;
curMgr.InitCamera();
}
}