# 카메라

## 개요

게임에서 카메라(Camera)는 플레이어가 게임 세계를 관찰하고 상호작용할 수 있도록 하는 **가상적인 시점이나 관점**을 제공합니다. 현실 세계의 카메라처럼, 게임 카메라는 플레이어에게 가상 환경과 캐릭터의 동작 및 이벤트를 전달하는 중요한 도구이며, 게임의 몰입도와 재미를 크게 좌우합니다

카메라는 단순히 장면을 비추는 것을 넘어, **이동**이나 **회전**과 같은 다양한 연출 기법으로 플레이어에게 풍부한 경험을 전달합니다. 시각적인 효과를 강조하거나, 특정 이벤트를 극적으로 보여줌으로써 게임의 분위기와 **몰입감**을 극대화시킬 수 있습니다. 게임 내 캐릭터나 환경의 상호작용은 물론, 다양한 의도된 **경험을 효과적으로 전달하는 도구**로 활용됩니다.

게임에서 카메라의 시점은 게임 플레이의 방식 자체를 완전히 변화시킬 수 있습니다. 예를 들어, **슈팅 게임**에서는 카메라 시점에 따라 전혀 다른 게임 플레이 경험을 제공합니다:

* **탑뷰(TOP-View)** 시점: 조준과 발사 등이 간단하며, 빠르게 진행되는 액션에 적합합니다.
* **TPS(3인칭 시점) / FPS(1인칭 시점)**: 더 정교한 시야와 전술적 플레이가 요구되며, 적과의 전투에 몰입감을 더합니다.

따라서 카메라의 시점은 단순한 시각적 연출을 넘어, 게임의 **본질적인 재미와 전략성**까지 변화시키는 중요한 요소로 작용합니다.

## 속성

<table><thead><tr><th width="246.6666259765625">속성</th><th>설명</th></tr></thead><tbody><tr><td>CFrame</td><td>카메라의 위치 및 방향</td></tr><tr><td>Focus</td><td>현재 지원되지 않습니다.</td></tr><tr><td>FieldOfView</td><td>카메라의 시야각 ( 0 &#x3C; 시야각 &#x3C; 180)</td></tr><tr><td>ViewportSize</td><td>카메라로 보고 있는 화면의 크기</td></tr><tr><td>CameraSubject</td><td>카메라의 피사제 오브젝트</td></tr><tr><td>CameraType</td><td>카메라의 타입</td></tr></tbody></table>

## 카메라의 사용 방법

### 카메라 속성의 변경

카메라를 직접적으로 조정하기 위해서는 반드시 **스크립트를 통한 설정**이 요구됩니다. 에디터에서 제공하는 프로퍼티를 사용하여 값을 변경할 수 있지만, 이러한 변경은 일시적인 것으로 **실제 카메라의 설정은 코드(Script)를 통해 이루어져야 효과를 반영**할 수 있습니다.

### 카메라 타입 지정

카메라는 현재 **Custom**과 **Scriptable** 타입에 대해서만 조작이 가능합니다.

* **CFrame**은 Scriptable 타입이 아닌 경우에는 수정되지 않으며, 기본 카메라 타입에 의해 자동으로 결정됩니다.
* Scriptable 타입을 사용하면 보다 세부적인 조정과 제어가 가능합니다.

### 화각(FieldOfView)과 카메라 CFrame을 이용한 줌인/줌아웃 처리

FieldOfView는 카메라의 시야각을 조정하는 주요 속성입니다. 이를 사용하여 사용자 정의의 다양한 카메라 효과를 구현할 수 있습니다:

* 시야각을 줄이는 경우, **줌인(Zoom-In)** 효과를 제공합니다.
* 시야각을 늘리는 경우, **광각(Wide-Angle)** 카메라로 촬영한 듯한 효과를 줄 수 있습니다.

나의 피사체(예: 플레이어)를 대상으로 줌인과 줌아웃을 구현하는 데는 두 가지 방식이 존재합니다:

* **카메라 위치 조정 방식**: 카메라 자체를 앞뒤로 이동하여 줌인/줌아웃 효과를 얻는 방법입니다.
* **FieldOfView 조정 방식**: 시야각을 변경하여 줌인 및 줌아웃 효과를 구현하는 방식으로, 상대적으로 **화면 왜곡** 효과가 발생합니다.

두 방식은 각각의 특성이 다르므로, 구현의 목표에 따라 적절한 방식을 선택해야 합니다. 예를 들어, 왜곡을 최소화하고 싶다면 카메라의 이동 방식을 사용하고, 스타일리시한 연출이 필요하다면 화각 조정 방식을 채택할 수 있습니다.

🎥 아래는 동일한 피사체를 대상으로 두 가지 방식으로 줌 효과를 적용한 결과 화면을 보여줍니다:

* **카메라 이동 방식**: 자연스러운 확대 및 축소
  * 줌인/줌아웃 시, 카메라로 부터 가까운 물체는 확대/축소 비율이 크지만, 멀리 있는 물체는 크기 비율 변화가 크지 않습니다.
* **화각 조정 방식**: 왜곡된 공간감이 포함된 확대 및 축소.
  * 줌인/줌아웃 시, 카메라로부터 가까이 있는 물체의 크기 변화와, 멀리 있는 물체의 크기 변화가 비슷한 비율로 변화 합니다.
  * 줌인 했을 때, 멀리 있는 물체가 가까이 있는 것 같은 왜곡이 일어납니다.

<figure><img src="https://2697870212-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FhRPi87oM9ttlk5nyu7L7%2Fuploads%2Fgit-blob-f5a463c6f95e1033438bdacaa585e20ad1c8a5e0%2Fimage%201.png?alt=media" alt=""><figcaption><p>기본 피사체 화면</p></figcaption></figure>

<figure><img src="https://2697870212-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FhRPi87oM9ttlk5nyu7L7%2Fuploads%2Fgit-blob-ba0caf86aff1ece9ad6ad862a9b77b57f82d9c3e%2FGroup%209.png?alt=media" alt=""><figcaption><p>좌즉은 카메라를 캐릭터 가까이 이동한 모습. 우측은 카메라의화각을 30도로 지정한 상태</p></figcaption></figure>

* 줌 인 상태를 보면, 카메라 이동 방식의 경우, 캐릭터 뒤의 나무 배경의 크기는 큰 변화가 없는 반면, 화각을 조정한 방식은 뒷 배경의 나무가 엄청 크고 가깝게 보입니다.

<figure><img src="https://2697870212-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FhRPi87oM9ttlk5nyu7L7%2Fuploads%2Fgit-blob-fad812f4e43df1d573fbf728a6b3cb04c954413a%2FGroup%2010.png?alt=media" alt=""><figcaption><p>좌즉은 카메라를 캐릭터로부터 멀리 이동한 모습. 우측은 카메라의 화각을 120도로 지정한 상태</p></figcaption></figure>

* 줌 아웃 상태를 보면, 카메라를 이동시킨 경우, 나무배경의 크기 변화가 눈에 띄지 않는 반면, 화각 변경 시에는 배경의 크기가 많이 줄어든 모습을 확인 할 수 있습니다.

<figure><img src="https://2697870212-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FhRPi87oM9ttlk5nyu7L7%2Fuploads%2Fgit-blob-01e2eec8837aa3cc6b3483c00d54e32cbfa55594%2Fimage%204.png?alt=media" alt=""><figcaption><p>카메라의 화각을 160도로 설정한 모습</p></figcaption></figure>

* 극단적으로 화각을 늘릴 경우 어안렌즈(Fish-eye) 처럼 화면의 주변부 왜곡이 심해지는 것을 볼 수 있습니다.

### CameraSubject 지정

카메라의 **Subject**는 카메라가 초점을 맞출 피사체를 지정하는 속성입니다.

* **기본값**은 플레이어 캐릭터로 설정됩니다.
* 필요에 따라 특정 오브젝트를 Subject로 지정하여 다양한 효과를 연출할 수 있습니다.

<figure><img src="https://2697870212-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FhRPi87oM9ttlk5nyu7L7%2Fuploads%2Fgit-blob-5b53c217306cd8d623a918123029373a4b7ae57c%2Fimage.png?alt=media" alt=""><figcaption><p>빨간 박스모양Part로 Subject를 변경하면, 큐브위치에서 고정된 카메라 효과를 얻을 수 있습니다.</p></figcaption></figure>

{% embed url="<https://files.gitbook.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FhRPi87oM9ttlk5nyu7L7%2Fuploads%2FTeVg52BtOt8RLam6NJou%2F2025-03-10%2014-40-24.mp4?alt=media&token=5d829807-2e84-49a0-8983-0af65c4d4de2>" %}

Part 위치에 고정 된 카메라 동작. 카메라가 더 이상 캐릭터를 따라 다니지 않습니다.

## 활용 예시

### 탑 다운 뷰 카메라

{% embed url="<https://files.gitbook.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FhRPi87oM9ttlk5nyu7L7%2Fuploads%2FZrhMCxcBDz3fLJO4WH3H%2F2025-03-10%2017-27-23.mp4?alt=media&token=4951133c-2b00-445b-a03f-6f0b3826c01f>" %}

탑 다운 뷰 카메라는 다음과 같은 특징을 같습니다.

* 위에서 아래로 내려다 보는 각도로, 마치 하늘에서 캐릭터를 바라보는 효과를 줍니다.
* 카메라는 항상 캐릭터를 따라다니면서 화면 가운데 또는 화면 특정위치에 캐릭터가 고정되어보이는 효과를 제공합니다.
* 캐릭터 이동에 상관없이 카메라는 회전하지 않습니다. 따라서 멀미와 같은 피로감이 덜합니다.
* 넓은 시야를 제공하고, 전술적이고 전략적인 게임에 어울리는 장면을 제공합니다. 반면
* 단조로운 게임 화면으로 지루해 질 수 있습니다.
* 일반적으로 화면 위에 있는 사람은 벽 뒤에 캐릭터를 숨길 수 있고, 아래에 있는 사람은 이를 발견하기 어렵습니다.

탑다운 뷰를 구성하기 위해선 다음과 같은 기능을 완성해야 합니다.

* 스크립터블 카메라로, 항상 플레이어 캐릭터의 위치를 획득하는 기능
* 캐릭터 위치를 기준으로 카메라의 위치와 바라보는 각도를 업데이트

```lua
local Workspace = game:GetService("Workspace")
local RunService= game:GetService("RunService")
local Players = game:GetService("Players")

local Camera = Workspace.CurrentCamera
Camera.CameraType = Enum.CameraType.Scriptable

-- 플레이어 캐릭터 획득
local Character = Players.LocalPlayer.Character
Camera.CameraSubject = Character

-- RunService의 렌더스텝마다, 캐릭터 위치에 따라 카메라의 CFrame을 조정하도록 함.
RunService.RenderStepped:Connect(function()
    local cameraPos = Character.HumanoidRootPart.Position + (Vector3.new(0, 0.5, 1) * 1200)	
    Camera.CFrame = CFrame.new(cameraPos.X, cameraPos.Y, cameraPos.Z) * CFrame.Angles(math.rad(-30), 0, 0)	
end)
```

### TPS 카메라

{% embed url="<https://files.gitbook.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FhRPi87oM9ttlk5nyu7L7%2Fuploads%2FlaNy401W9EPpWtRV3Oqp%2F2025-03-10%2015-07-29.mp4?alt=media&token=7b623c15-5042-4633-813d-f0ceb1bd86da>" %}

* 캐릭터 가까이서 1인칭에 가까운 몰입감을 제공하면서, 내 캐릭터를 함께 볼 수 있습니다.
* 캐릭터의 몸이 사물에 의해 가려지더라도 시야는 캐릭터 밖에 있기때문에 시야는 막히지 않아 개방감을 제공합니다.
* TPS 보다 넓은 시야를 제공하면서, 자유로운 카메라 회전을 지원합니다.
* 긴 거리의 시야를 제공하여 멀리 있는 사물도 볼 수 있습니다.

반면

* 캐릭터의 방향(또는 총구의 방향)과 카메라의 방향이 일치 하지 않아, 슈팅게임에서 사격에 관한 별도의 처리가 필수적입니다.
* (카메라의 크로스헤어에는 적이 바로 보이지만, 캐릭터의 위치에선 벽 이나 사물 등으로 인해 사선에 타겟이 가려질 수 있음)
* 나는 벽에 숨어 상대의 시야에서는 숨겨지지만, 내 시야에서는 상대를 볼 수 있는 등 정보의 비대칭으로 PvP에서 불공정한 경기가 진행될 수 있습니다.

<figure><img src="https://2697870212-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FhRPi87oM9ttlk5nyu7L7%2Fuploads%2Fgit-blob-e6784d94bc1f57c33b41598e19b33a50bed4ef8d%2Fimage%20(12).png?alt=media" alt=""><figcaption><p>기본 Custom 타입 카메라는 카메라 정 중앙에 캐릭터가 위치하여 크로스헤어를 캐릭터가 가리게 된다</p></figcaption></figure>

<figure><img src="https://2697870212-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FhRPi87oM9ttlk5nyu7L7%2Fuploads%2Fgit-blob-4d38d227eff29fa6a97288055af980d301732c5e%2Fimage%20(13).png?alt=media" alt=""><figcaption><p>TPS 슈터로 동작하기 위해선 카메라중앙이 캐릭터로부터 비껴있어야 한다</p></figcaption></figure>

TPS 카메라는 Camera의 **CameraOffset** 속성을 이용하여 쉽게 표현할 수 있습니다.

```lua
local Workspace = game:GetService("Workspace")
local Camera = Workspace.CurrentCamera

Camera.CameraOffset = Vector3.new(90, 90, -120)
```
