271 lines
10 KiB
C#
271 lines
10 KiB
C#
|
|
using UnityEngine;
|
||
|
|
using System.Collections;
|
||
|
|
using System.Collections.Generic;
|
||
|
|
|
||
|
|
public class RealCamera : MyCoroutine
|
||
|
|
{
|
||
|
|
|
||
|
|
[Header("Camera Properties")]
|
||
|
|
private float DistanceAway; //how far the camera is from the player.
|
||
|
|
|
||
|
|
public float minDistance = 1; //min camera distance
|
||
|
|
public float maxDistance = 2; //max camera distance
|
||
|
|
|
||
|
|
public float DistanceUp = -2; //how high the camera is above the player
|
||
|
|
public float smooth = 4.0f; //how smooth the camera moves into place
|
||
|
|
public float rotateAround = 70f; //the angle at which you will rotate the camera (on an axis)
|
||
|
|
|
||
|
|
public Vector3 m_LookAt = Vector3.up;
|
||
|
|
public Vector3 m_BackOffSet = new Vector3(0f, 0.1f, -0.2f);
|
||
|
|
|
||
|
|
[HideInInspector] public bool m_BackMove;
|
||
|
|
|
||
|
|
[Header("Player to follow")]
|
||
|
|
public Transform target; //the target the camera follows
|
||
|
|
|
||
|
|
[Header("Layer(s) to include")]
|
||
|
|
public LayerMask CamOcclusion; //the layers that will be affected by collision
|
||
|
|
|
||
|
|
[Header("Map coordinate script")]
|
||
|
|
// public worldVectorMap wvm;
|
||
|
|
public float cameraHeight = 55f;
|
||
|
|
public float cameraPan = 0f;
|
||
|
|
float camRotateSpeed = 180f;
|
||
|
|
Vector3 camPosition;
|
||
|
|
Vector3 camMask;
|
||
|
|
|
||
|
|
float OriminDistance, OrimaxDistance, OriDistanceUp, OricameraHeight;
|
||
|
|
private float HorizontalAxis, VerticalAxis;
|
||
|
|
int CamStatus = 1; // 0 초기, 1 평소, 2 건물 내부
|
||
|
|
float DragEndTime;
|
||
|
|
GameObject godummy, gowitch;
|
||
|
|
List<Transform> list_tfCamactionTarget = new List<Transform>();
|
||
|
|
bool RunUpdate = false;
|
||
|
|
|
||
|
|
private void Awake()
|
||
|
|
{
|
||
|
|
OriminDistance = minDistance;
|
||
|
|
OrimaxDistance = maxDistance;
|
||
|
|
OriDistanceUp = DistanceUp;
|
||
|
|
OricameraHeight = cameraHeight;
|
||
|
|
}
|
||
|
|
|
||
|
|
public bool IsEnter() { return CamStatus == 0; }
|
||
|
|
public void Set_Target(Transform _target, float _camrot)
|
||
|
|
{
|
||
|
|
if (InGameInfo.Ins.Get_GameMode() == eGameMode.Lobby)
|
||
|
|
{
|
||
|
|
RunUpdate = false;
|
||
|
|
transform.position = new Vector3(-14.77f, 12.07f, 14.54f);
|
||
|
|
transform.eulerAngles = new Vector3(32.05f, 135.08f, 0f);
|
||
|
|
GetComponent<Camera>().fieldOfView = 34;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
GetComponent<Camera>().fieldOfView = 60;
|
||
|
|
|
||
|
|
RunUpdate = true;
|
||
|
|
CamStatus = 0;
|
||
|
|
target = _target;
|
||
|
|
Add_CamActionTarget(_target);
|
||
|
|
rotateAround = _camrot;
|
||
|
|
|
||
|
|
//cameraHeight = 55f;
|
||
|
|
DistanceUp = OriDistanceUp;
|
||
|
|
VerticalAxis = maxDistance = OrimaxDistance;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
public void Set_InsideBuilding(bool _active)
|
||
|
|
{
|
||
|
|
if (_active)
|
||
|
|
{
|
||
|
|
OriminDistance = minDistance;
|
||
|
|
OrimaxDistance = maxDistance;
|
||
|
|
OriDistanceUp = DistanceUp;
|
||
|
|
OricameraHeight = cameraHeight;
|
||
|
|
|
||
|
|
maxDistance = minDistance = 2f;
|
||
|
|
DistanceUp = 1.5f;
|
||
|
|
cameraHeight = 25f;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
minDistance = OriminDistance;
|
||
|
|
VerticalAxis = maxDistance = OrimaxDistance;
|
||
|
|
DistanceUp = OriDistanceUp;
|
||
|
|
cameraHeight = OricameraHeight;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
public void Add_CamActionTarget(Transform _target) { list_tfCamactionTarget.Add(_target); }
|
||
|
|
public void Set_TargetShow(Transform _target)
|
||
|
|
{
|
||
|
|
if (CamStatus != 0 && target != null)
|
||
|
|
{
|
||
|
|
// 매개변수 타겟을 보게 카메라 회전
|
||
|
|
if (godummy == null) godummy = new GameObject("CamDummy");
|
||
|
|
godummy.transform.position = target.position;
|
||
|
|
godummy.transform.LookAt(_target);
|
||
|
|
Set_Coroutine(() => { rotateAround = godummy.transform.eulerAngles.y - 45f; }, 0.1f);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
public void Set_Axis(bool _horizontal, float _value)
|
||
|
|
{
|
||
|
|
DragEndTime = 1f;
|
||
|
|
if (_horizontal) HorizontalAxis = _value;
|
||
|
|
else VerticalAxis = _value;
|
||
|
|
NewGameUI.Ins.m_GuideQuestUI.Add_GuideQuest(ePurpose.ScreenRot);
|
||
|
|
}
|
||
|
|
public void Set_AutoCam_byMyPC()
|
||
|
|
{
|
||
|
|
if (DragEndTime <= 0f)
|
||
|
|
{
|
||
|
|
if (gowitch == null) gowitch = new GameObject("witchDummy");
|
||
|
|
gowitch.transform.position = MyValue.MyPC.Get_position() + MyValue.MyPC.transform.forward;
|
||
|
|
Set_TargetShow(gowitch.transform);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Use this for initialization
|
||
|
|
void Start()
|
||
|
|
{
|
||
|
|
//the statement below automatically positions the camera behind the target.
|
||
|
|
//rotateAround = target.eulerAngles.y - 45f;
|
||
|
|
}
|
||
|
|
|
||
|
|
void LateUpdate()
|
||
|
|
{
|
||
|
|
if (!RunUpdate) return;
|
||
|
|
if (DragEndTime > 0f) DragEndTime -= Time.deltaTime;
|
||
|
|
if (target == null) return;
|
||
|
|
|
||
|
|
// 캐릭터의 이동 방향 계산
|
||
|
|
Vector3 direction = target.position - previousPosition;
|
||
|
|
|
||
|
|
//// 이동 방향이 존재할 때 캐릭터가 보는 방향으로 카메라 회전
|
||
|
|
//if (direction.sqrMagnitude > 0.01f)
|
||
|
|
//{
|
||
|
|
// // 캐릭터가 움직이고 있는 방향으로 회전 목표 각도 계산
|
||
|
|
// float targetRotationAngle = Mathf.Atan2(direction.x, direction.z) * Mathf.Rad2Deg;
|
||
|
|
|
||
|
|
// // 현재 회전 각도에서 목표 회전 각도로 부드럽게 보간
|
||
|
|
// rotateAround = Mathf.LerpAngle(rotateAround, targetRotationAngle, rotationSpeed * Time.deltaTime);
|
||
|
|
//}
|
||
|
|
|
||
|
|
// 카메라를 설정된 로직에 따라 업데이트
|
||
|
|
if (CamStatus == 0)
|
||
|
|
{
|
||
|
|
var camTarget = list_tfCamactionTarget[0];
|
||
|
|
Vector3 lTargetDir = camTarget.position - transform.position;
|
||
|
|
transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(lTargetDir + m_LookAt), Time.deltaTime * 2.5f);
|
||
|
|
|
||
|
|
Vector3 targetOffset = target.position;
|
||
|
|
Quaternion rotation = Quaternion.Euler(cameraHeight, rotateAround, cameraPan);
|
||
|
|
Vector3 vectorMask = Vector3.one;
|
||
|
|
Vector3 rotateVector = rotation * vectorMask;
|
||
|
|
DistanceAway = Mathf.Clamp(DistanceAway += VerticalAxis, minDistance, maxDistance);
|
||
|
|
camPosition = targetOffset + Vector3.up * DistanceUp - rotateVector * DistanceAway;
|
||
|
|
transform.position = Vector3.Lerp(transform.position, camPosition, Time.deltaTime * 2.5f);
|
||
|
|
|
||
|
|
if (Vector3.Distance(transform.position, camPosition) < 0.05f)
|
||
|
|
{
|
||
|
|
list_tfCamactionTarget.RemoveAt(0);
|
||
|
|
if (list_tfCamactionTarget.Count <= 0)
|
||
|
|
{
|
||
|
|
CamStatus = 1;
|
||
|
|
Start_Game();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else if (CamStatus == 1)
|
||
|
|
Update_Cam();
|
||
|
|
|
||
|
|
// 이전 위치 업데이트
|
||
|
|
previousPosition = target.position;
|
||
|
|
}
|
||
|
|
private Vector3 previousPosition; // 이전 프레임에서 캐릭터의 위치를 저장할 변수
|
||
|
|
public float rotationSpeed = 1.25f; // 카메라 회전 속도 조절 변수
|
||
|
|
|
||
|
|
void Start_Game()
|
||
|
|
{
|
||
|
|
Time.timeScale = MyValue.Get_GameSpeed();
|
||
|
|
// TODO 정인호 : 게임 시작 시 컨텐츠 등 체크 주석 처리
|
||
|
|
//GameUI.Ins.Set_AllUI(true);
|
||
|
|
//var chapter = InGameInfo.Ins.Get_CurStageData().Chapter;
|
||
|
|
//if (chapter == 101 || chapter == 103 || chapter == 104)
|
||
|
|
// GameUI.Ins.IngameUI.m_StageTimeUI.Set_Start();
|
||
|
|
//if (chapter < 101 && ServerInfo.Ins.m_ServerData.PC.Get_Lv(4) > 0)
|
||
|
|
// GameUI.Ins.IngameUI.m_SelectSkillUI.Set(null);
|
||
|
|
//else
|
||
|
|
{
|
||
|
|
ActorInfo.Ins.All_Stop(false);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
void Update_Cam()
|
||
|
|
{
|
||
|
|
//Offset of the targets transform (Since the pivot point is usually at the feet).
|
||
|
|
Vector3 targetOffset = target.position;
|
||
|
|
Quaternion rotation = Quaternion.Euler(cameraHeight, rotateAround, cameraPan);
|
||
|
|
Vector3 vectorMask = Vector3.one;
|
||
|
|
Vector3 rotateVector = rotation * vectorMask;
|
||
|
|
//this determines where both the camera and it's mask will be.
|
||
|
|
//the camMask is for forcing the camera to push away from walls.
|
||
|
|
camPosition = targetOffset + Vector3.up * DistanceUp - rotateVector * DistanceAway;
|
||
|
|
camMask = targetOffset + Vector3.up * DistanceUp - rotateVector * DistanceAway;
|
||
|
|
|
||
|
|
//occludeRay(ref targetOffset);
|
||
|
|
transform.position = Vector3.Lerp(transform.position, camPosition, Time.deltaTime * smooth);
|
||
|
|
if (m_BackMove)
|
||
|
|
{
|
||
|
|
Vector3 backOffsetDirection = -transform.forward.normalized * m_BackOffSet.z;
|
||
|
|
transform.position += new Vector3(backOffsetDirection.x, 0f, backOffsetDirection.z);
|
||
|
|
}
|
||
|
|
|
||
|
|
transform.LookAt(target.position + m_LookAt);
|
||
|
|
|
||
|
|
#region wrap the cam orbit rotation
|
||
|
|
if (rotateAround > 360)
|
||
|
|
{
|
||
|
|
rotateAround = 0f;
|
||
|
|
}
|
||
|
|
else if (rotateAround < 0f)
|
||
|
|
{
|
||
|
|
rotateAround = (rotateAround + 360f);
|
||
|
|
}
|
||
|
|
#endregion
|
||
|
|
|
||
|
|
rotateAround += HorizontalAxis * camRotateSpeed * Time.deltaTime;
|
||
|
|
|
||
|
|
|
||
|
|
//rotateAround = 145;
|
||
|
|
|
||
|
|
|
||
|
|
if (HorizontalAxis >= -0.1f || HorizontalAxis <= 0.1f) HorizontalAxis = 0f;
|
||
|
|
//DistanceUp = Mathf.Clamp(DistanceUp += VerticalAxis, -0.79f, 2.3f);
|
||
|
|
DistanceAway = Mathf.Clamp(DistanceAway += VerticalAxis, minDistance, maxDistance);
|
||
|
|
if (VerticalAxis >= -0.1f || VerticalAxis <= 0.1f)
|
||
|
|
VerticalAxis = 0f;
|
||
|
|
}
|
||
|
|
|
||
|
|
void occludeRay(ref Vector3 targetFollow)
|
||
|
|
{
|
||
|
|
#region prevent wall clipping
|
||
|
|
//declare a new raycast hit.
|
||
|
|
//linecast from your player (targetFollow) to your cameras mask (camMask) to find collisions.
|
||
|
|
if (Physics.Linecast(targetFollow, camMask, out RaycastHit wallHit, CamOcclusion))
|
||
|
|
{
|
||
|
|
if (wallHit.collider.tag == "Untagged" && wallHit.collider.GetComponent<Actor>() == null &&
|
||
|
|
(wallHit.collider.GetComponent<BoxCollider>() != null || wallHit.collider.GetComponent<MeshCollider>() != null || wallHit.collider.GetComponent<TerrainCollider>() != null))
|
||
|
|
{
|
||
|
|
//the smooth is increased so you detect geometry collisions faster.
|
||
|
|
//smooth = 10f;
|
||
|
|
//the x and z coordinates are pushed away from the wall by hit.normal.
|
||
|
|
//the y coordinate stays the same.
|
||
|
|
camPosition = new Vector3(wallHit.point.x + wallHit.normal.x * 0.5f, camPosition.y, wallHit.point.z + wallHit.normal.z * 0.5f);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
//else
|
||
|
|
// smooth = 4f;
|
||
|
|
#endregion
|
||
|
|
}
|
||
|
|
}
|