본문 바로가기
유니티 프로젝트/Team Project3 - 대난투

MULTIPLE TARGET CAMERA 3D

by SUGI_ 2022. 9. 12.

여러 표적 주위를 따라가는 카메라를 만들고 플레이어에 맞게 카메라를 확대 및 축소

Update()
: 프레임마다 한번씩 호출이 되는 기본적인 업데이트
FixedUpdate()
: 물리엔진에 의해 고정된 간격으로 호출 
기본적으로 모든 물리 관련 기능 (트리거, 충돌)에 좋음
LateUpdate()
: Update 후 프레임마다 한번씩 호출
Update에서 계산이 완료되면 해당 LateUpdate가 실행
특정 행동이 끝난 후 실행하고 싶은 행동이 있다면 해당 LateUpdate를 이용하는 것이 좋음
(EX) 3인칭 카메라가 캐릭터를 따라 움직일 시
Update에서 캐릭터 이동방향계산 / LateUpdate에서 카메라에 대한 계산

1. 중심점 구하는 방법 Bounds

 

2. Vector3.SmoothDamp

부드러운 이동을 구현하기 위해 손쉽게 활용하는 함수

주로 Target 을 부드럽게 따라가는 카메라의 LookAt 혹은 Position계산에 활용

 

3. Zoom/Out

 

 

최종 코드

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[RequireComponent(typeof(Camera))]
public class CameraMove3D_LHS : MonoBehaviour
{
    public List<Transform> targets;

    // 중심점에서 카메라 조절하기위해
    public Vector3 offset;
    public float smoothTime = 0.5f;

    // 줌아웃 크기
    public float minZoom = 40f;
    public float maxZoom = 10f;
    // 확대/축소 제한기
    public float zoomLimiter = 50f;

    // 이동속도
    private Vector3 velocity;
    private Camera cam;

    Vector3 newPosition;

    private void Start()
    {
        cam = GetComponent<Camera>();
    }

    private void LateUpdate()
    {
        // 만약 타겟이 0이라면 아무것도 하지 않는다
        if (targets.Count == 0)
            return;

        Move();
        Zoom();
    }

    void Zoom()
    {
        // 최대거리 설정
        //Debug.Log(GetGreatestDistance());
        float newZoom = Mathf.Lerp(maxZoom, minZoom, GetGreatestDistance() / zoomLimiter);
        cam.fieldOfView = Mathf.Lerp(cam.fieldOfView, newZoom, Time.deltaTime);
    }

    float GetGreatestDistance()
    {
        var bounds = new Bounds(targets[0].position, Vector3.zero);
        for (int i = 0; i < targets.Count; i++)
        {
            // 캡슐화
            bounds.Encapsulate(targets[i].position);
        }
        // 상자의 너비
        return bounds.size.x;
    }

    // 카메라 움직임
    void Move()
    {
        // 카메라 위치 = 모든 목표의 중심으로 설정
        Vector3 centerPoint = GetCenterPoint();

        // 중심점에서 + 내가 위치 조절
        Vector3 newPosition = centerPoint + offset;

        // 내 위치 = 중심점
        //transform.position = newPosition;
        // 부드럽게 움직이기 위해 
        transform.position = Vector3.SmoothDamp(transform.position, newPosition, ref velocity, smoothTime);
    }

    // 중심점 찾기
    Vector3 GetCenterPoint()
    {
        // 만약 타겟이 한명이라면
        if(targets.Count == 1)
        {
            return targets[0].position;
        }

        // 여러개의 대상의 중심점을 구하는 방법
        // BOUNDS 여러개체를 캡슐화하는 데 사용할 수 있는 클래스

        // 첫번째 대상 중심에서 시작, 크기는 0으로
        var bounds = new Bounds(targets[0].position, Vector3.zero);
        for(int i = 0; i < targets.Count; i++)
        {
            bounds.Encapsulate(targets[i].position);
        }
        return bounds.center;
    }

}

 

[참고 영상]

\ttps://youtu.be/aLpixrPvlB8

 

728x90

'유니티 프로젝트 > Team Project3 - 대난투' 카테고리의 다른 글

MULTIPLE TARGET CAMERA 2D  (0) 2022.09.12