Project_WL/Assets/Script/Util/RealCamera.cs

260 lines
9.8 KiB
C#
Raw Normal View History

2024-12-15 01:39:39 +00:00
using System.Collections.Generic;
2024-12-23 00:36:04 +00:00
using UnityEngine;
using static UnityEngine.GraphicsBuffer;
2024-12-15 01:39:39 +00:00
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
Actor m_Target;
bool isTarget;
2024-12-15 01:39:39 +00:00
[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>();
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)
{
2024-12-23 00:36:04 +00:00
CamStatus = 0;
target = _target;
isTarget = target;
if (isTarget)
{
m_Target = target.GetComponent<Actor>();
Add_CamActionTarget(_target);
}
2024-12-23 00:36:04 +00:00
rotateAround = _camrot;
//cameraHeight = 55f;
2025-01-05 02:37:53 +00:00
Set_DistanceUp(false);
2024-12-23 00:36:04 +00:00
VerticalAxis = maxDistance = OrimaxDistance;
2024-12-15 01:39:39 +00:00
}
2025-01-05 02:37:53 +00:00
public void Set_DistanceUp(bool vertical)
{
DistanceUp = vertical ? 0f : OriDistanceUp;
}
2024-12-15 01:39:39 +00:00
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;
2025-01-05 02:37:53 +00:00
Set_DistanceUp(false);
2024-12-15 01:39:39 +00:00
cameraHeight = OricameraHeight;
}
}
public void Add_CamActionTarget(Transform _target) { list_tfCamactionTarget.Add(_target); }
public void Set_TargetShow(Transform _target)
{
if (CamStatus != 0 && isTarget)
2024-12-15 01:39:39 +00:00
{
// 매개변수 타겟을 보게 카메라 회전
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 (DSUtil.CheckNull(gowitch)) gowitch = new GameObject("witchDummy");
2024-12-15 01:39:39 +00:00
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 (DragEndTime > 0f) DragEndTime -= Time.deltaTime;
if (!isTarget) return;
//if (m_Target.Get_CurAnim() == eAnim.Attack) return;
2024-12-15 01:39:39 +00:00
// 캐릭터의 이동 방향 계산
//Vector3 direction = target.position - previousPosition;
2024-12-15 01:39:39 +00:00
//// 이동 방향이 존재할 때 캐릭터가 보는 방향으로 카메라 회전
//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()
{
ActorInfo.Ins.All_Stop(false);
NewGameUI.Ins.go_Camera.SetActive(true);
2024-12-15 01:39:39 +00:00
Time.timeScale = MyValue.Get_GameSpeed();
DungeonInfo.Ins.Start_Dungeon(true);
2024-12-15 01:39:39 +00:00
}
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;
2024-12-15 01:39:39 +00:00
//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;
2024-12-15 01:39:39 +00:00
#endregion
}
}