본문 바로가기
Article/CODING AND SCRIPTS

Understanding CFrames

by Roblox_개발자 2021. 4. 10.

Coordinate Frame의 줄임말인 CFrame 3D객체를 회전시키거나 이동시킬때 사용되는 데이터 타입이다. CFrame은 글로벌 X, Y, Z 좌표, 각 축에 대한 회전 데이터를 포함한다. 또한 CFrame에는 3D 공간의 객체 작업에 유용한 기능이 포함되어 있다.

 

게임 내 CFrame 애플리케이션의 몇가지 예는 다음과 같다:

  • 플레이어의 총이 목표로 삼은 적의 위치와 같이, 발사체의 먼 목표 지점을 찾는다.
  • 플레이어가 특정 NPC와 상호작용할 수 있도록 카메라를 NPC가 있는 곳으로 이동시킨다. 
  • 플레이어의 체력, 마력과 같은 정보를 보여주기 위해 그들의 머리 바로 위에 상태 표시바를 위치시킨다.

[CFrame Basics]

Positioning a CFrame

CFrame.new()를 통해 게임 월드안에서 기본 위치가 (0, 0, 0)인 빈 CFrame을 생성할 수 있다. 특정한 위치에 CFrame이 생성되길 원한다면, X, Y, Z 파라미터를 CFrame.new()에 건네줘야한다. 다음 예제는, (-2, 2, 4)의 위치값을 저장한 새 CFrame을 만든 후, 기존 redBlock에 덮어씌우는 것을 통해 redBlock의 위치를 이동시키는 예제이다.

local redBlock = game.Workspace.RedBlock
 
-- 새 CFrame 생성
local newCFrame = CFrame.new(-2, 2, 4)
 
-- red block의 현재 CFrame을 새 CFrame으로 overwrite한다.
redBlock.CFrame = newCFrame

 

 

또는 당신은 CFrame.new()에 Vector3 위치를 제공함으로써 같은 결과를 얻을 수 있다.

local redBlock = game.Workspace.RedBlock
 
-- Create new CFrame
local newVector3 = Vector3.new(-2, 2, 4)
local newCFrame = CFrame.new(newVector3)
 
-- Overwrite red block's current CFrame with new CFrame
redBlock.CFrame = newCFrame

 

Rotating a CFrame

회전된 CFrame을 생성하기 위해선, 원하는 축에 대해 라디안 단위로 회전각을 제공하는 CFrame.Angles()  생성자를 사용해라:

local redBlock = game.Workspace.RedBlock 
 
-- Create new rotated CFrame
local newCFrame = CFrame.Angles(0, math.rad(45), 0)
 
-- Overwrite red block's current CFrame with new CFrame
redBlock.CFrame = newCFrame

 

위에서 언급된 바와 같이, CFrame.Angles()의 파라미터는 각도가 아니라 radians으로 지정해야 한다. 당신이 각도를 원한다면, 위의 예에서 보여지는 것과 같이 math.rad() converter를 사용하도록 해라

 

Facing Toward a Point

CFrame.new()의 가장 강력한 사용법은 CFrame의 앞쪽 면을 맵의 특정 포인트로 지정하는 것이다. 

redBlock을 0, 3, 0으로 배치한 다음 blueCube 에서 전면 표면(흰색 원으로 표시)을 가리키는 다음 예를 보도록 하자.

local redBlock = game.Workspace.RedBlock
local blueCube = game.Workspace.BlueCube
 
-- Create a Vector3 for both the start position and target position
-- 시작 위치와 타겟위치를 생성
local startPosition = Vector3.new(0, 3, 0)
local targetPosition = blueCube.Position
 
-- 시작위치(startPosition)와 앞면이 어느 위치를 향할지(targetPosition)를 설정한 새 CFrame 생성 
local newCFrame = CFrame.new(startPosition, targetPosition)

-- redBlock CFrame을 새 CFrame으로 변경
redBlock.CFrame = newCFrame

 

Offsetting a CFrame

경우에 따라 당신은 현재 위치에서 특정 수의 스터드로 객체를 상쇄시킬 필요가 있다. 이는 객체의 위치에서 생성된 새로운 CFrame Vector3를 추가하거나 빼는 방식으로 수행될 수 있다. 

local redBlock = game.Workspace.RedBlock
 
redBlock.CFrame = CFrame.new(redBlock.Position) + Vector3.new(0, 1.25, 0)

 

같은 기술이 다른 객체의 포지션으로부터 어떤 객체를 상쇄시키기 위해 사용될 수 있다. 이번에는 blueCube 포지션에 생성된 CFrame에 Vector3를 추가해보도록 하자.

local redBlock = game.Workspace.RedBlock
local blueCube = game.Workspace.BlueCube
 
redBlock.CFrame = CFrame.new(blueCube.Position) + Vector3.new(0, 2, 0)

 

Dynamic CFrame Orientation

CFrame.new()CFrame.Angles() 생성자는 그들 자체로 아주 훌륭하지만 또한 아주 제한적이다. 그들은 단지 맵안에서 특정 방향으로 객체를 위치시키거나 회전시키는 역할만 하기 때문이다. 이는 몇몇 경우에는 유용할 수 있지만, 당신이 맵의 고정된 위치나 회전각도에 의존할 수 없는 경우는 어떨까? 예를 들어:

 

  • 맵 이곳 저곳을 돌아다니는 플레이어의 바로 앞에 떠다니는 보물을 위치시키고자 하는 경우
  • 플레이어의 오른쪽 어깨 바로 위에 마법 지니를 만들고자 하는 경우

이러한 경우, CFrame 함수들이 제한된 생성자들보다 더 강력하다.

Relative Position

CFrame:ToWorldSpace() 함수는 객체의 CFrame (자체 로컬 방향에 따라)을 새로운 표준 방향으로 변환한다.

이렇게 하면 현재 위치/회전 방식에 관계없이 자기 자신이나 다른 물체에 상대적인 part을 상쇄하는 데 이상적이다.

 

아래 코드에서, redblock은 bluecube의 Y축에 대해 상대적으로 2만큼 이동하게 된다. (맵 내의 글로벌 Y축이 아닌 bluecube의 Y축에 대해 2만큼 이동한다는 것에 유의해라)

local redBlock = game.Workspace.RedBlock
local blueCube = game.Workspace.BlueCube
 
local offsetCFrame = CFrame.new(0, 2, 0)
redBlock.CFrame = blueCube.CFrame:ToWorldSpace(offsetCFrame)

 

Relative Rotation

또한 CFrame:ToWorldSpace()은 객체를 상대적으로 회전시킬때도 유용하다. 예를 들어, 어떤 물체를 물체의 현재 Y축으로 반시계방향으로 70도만큼, 시계방향으로 물체의 현재 Z축으로 20도만큼 회전 시키는 경우를 생각해보자

local redBlock = game.Workspace.RedBlock
 
local rotatedCFrame = CFrame.Angles(0, math.rad(70), math.rad(20))
redBlock.CFrame = redBlock.CFrame:ToWorldSpace(rotatedCFrame)

 

Facing a Specific Surface Toward a Point

아까 설명했듯이, 당신은 CFrame.new()의 두번째 파라미터값으로 Vector3를 제공함으로써, 어떤 물체가 다른 물체를 바라보게 만들 수 있다. 하지만 이것은 제한적이다. 왜냐하면 물체의 앞부분만 바라보도록 할 수 있기 때문이다. (만약 물체의 왼쪽 부분이 특정 지점을 바라보게 하고 싶을 경우에는?)

 

다행히도, 당신은 relative rotation를 사용해서 물체의 어느 면이라도 Vector3 지점을 바라보게 할 수 있다. 

두 번의 연속적인 CFrame 작업을 수행하는 이 예제를 보도록 하자.

 

1. 물체의 앞쪽면이 타겟을 가리키도록 한다.

2. 물체의 위쪽면이 타겟을 가리키도록 CFrame을 회전시킨다. 

local redBlock = game.Workspace.RedBlock
local blueCube = game.Workspace.BlueCube
 
-- 타겟위치를 위한 Vector3를 생성한다. 
local targetPosition = blueCube.Position
 
-- red block의 앞면이 타겟위치를 향하도록 한다.
redBlock.CFrame = CFrame.new(redBlock.Position, targetPosition)
 
-- red block의 윗면이 타겟을 향할 수 있도록 자신을 회전시킨다.
local rotatedCFrame = CFrame.Angles(math.rad(-90), 0, 0)
redBlock.CFrame = redBlock.CFrame:ToWorldSpace(rotatedCFrame)

 

Finding a Point Between Points

선형 보간법(linear interpolation)으로 알려진 방법을 사용하여 두 지점 사이에 CFrame을 배치할 수 있다.  

 

예를 들어 다음 코드는 0.7의 값을 사용하여 greenCube에서 70% 떨어진 거리임과 동시에 greenCubecyanCube 사이에 redBlock을 직접 배치한다.

local redBlock = game.Workspace.RedBlock
local greenCube = game.Workspace.GreenCube
local cyanCube = game.Workspace.CyanCube
 
redBlock.CFrame = greenCube.CFrame:Lerp(cyanCube.CFrame, 0.7)

 

이 글을 통해 당신이 CFrame 생성자와 함수를 통해 객체들을 이동시키는 방법을 알려주었다. 이 글에서 나온 개념들에 대해 확실히 이해를 했다면 CFrame Math Operations 글을 통해 숙련된 CFrame 조작법에 대해 알아보도록 하자.

 


참고 링크

developer.roblox.com/en-us/articles/Understanding-CFrame

 

Understanding CFrames

This Platform uses cookies to offer you a better experience, to personalize content, to provide social media features and to analyse the traffic on our site. For further information, including information on how to prevent or manage the use of cookies on t

developer.roblox.com

추가적으로 공부할 부분

CFrame Math Operations - CFrame 심화

'Article > CODING AND SCRIPTS' 카테고리의 다른 글

Roblox Client-Server Model  (0) 2021.04.10
BodyPosition  (0) 2021.04.06
BodyMovers  (0) 2021.04.06
Basic String Patterns (정규식)  (0) 2021.04.06
Argument와 Parameter  (0) 2021.04.06

댓글