플레이어들은 종종 자신이 현재 들어가 있는 공간을 직접 만드는 느낌을 좋아합니다. SurfaceArt 개발자 모듈은 플레이어가 말 그대로 체험에 흔적을 남길 수 있게 해줍니다.
모듈 사용
설치
체험에서 SurfaceArt 모듈을 사용하는 방법
보기 탭에서 도구 상자를 열고 마켓플레이스 탭을 선택합니다.
모델 정렬이 선택되었는지 확인한 다음 카테고리에서 모두 보기 버튼을 클릭합니다.
DEV MODULES 타일을 찾아 클릭합니다.
표면 아트 모듈을 찾아 클릭하거나 3D 보기로 끌어다 놓습니다.
탐색기 창에서 전체 SurfaceArt 모델을 ServerScriptService로 이동합니다. 체험을 실행하면 모듈이 다양한 서비스에 배포되고 실행되기 시작합니다.
캔버스 위치 지정
모듈은 크리에이터가 3D 월드에 배치할 수 있는 한 개의 SurfaceCanvas 모델과 함께 제공됩니다. 플레이어는 이 모델과 상호 작용하면서 표면에 아트를 배치합니다.
모듈의 기본 폴더에서 Workspace 안의 SurfaceCanvas 메시를 찾습니다.
최상위 Workspace 계층으로 옮긴 다음 원하는 위치에 놓습니다.
테스트 세션을 게시/실행하면 플레이어들은 ProximityPrompt를 통해 개체와 상호 작용하면서 지정된 표면 위에 아트를 배치할 수 있습니다.
캔버스 표면 변경
후드 아래에서, 모듈은 SurfaceGui를 사용하여 아트 아이템을 표시합니다. 아트가 표시될 표면을 구성하는 방법은 다음과 같습니다.
SurfaceCanvas 메시를 선택합니다.
속성 창의 하단에서 기본 값이 Right인 SurfaceCanvasFace 속성을 찾습니다.
이 속성을 클릭하고 Enum.NormalId를 설명하는 6개 값 중 하나를 입력합니다.
속성 값 | 해당되는 Normal ID |
---|---|
앞 | Enum.NormalId.Front |
뒤 | Enum.NormalId.Back |
오른쪽 | Enum.NormalId.Right |
왼쪽 | Enum.NormalId.Left |
상단 | Enum.NormalId.Top |
하단 | Enum.NormalId.Bottom |
사용자 지정 아트 애셋 사용
기본적으로 제공되는 애셋 대신 체험의 주제에 더 잘 맞도록 본인의 사용자 지정 애셋을 사용할 수 있습니다. 이 작업은 ServerScriptService의 Script에서 호출되는 configure 함수를 통해 수행할 수 있습니다.
Script
local ReplicatedStorage = game:GetService("ReplicatedStorage")local SurfaceArt = require(ReplicatedStorage:WaitForChild("SurfaceArt"))local customAssets = {CustomAsset1 = {name = "Custom Asset 1",assetId = "rbxassetid://7322508294",},CustomAsset2 = {name = "Custom Asset 2",assetId = "rbxassetid://7322547665",},}SurfaceArt.configure({assets = customAssets,})
모든 캔버스 지우기
월드의 모든 캔버스에서 기존 아트를 모두 삭제하려면 Script에서 removeAllArt 함수를 호출하세요.
Script
local ReplicatedStorage = game:GetService("ReplicatedStorage")local SurfaceArt = require(ReplicatedStorage:WaitForChild("SurfaceArt"))SurfaceArt.removeAllArt()
사용자 지정 효과 표시
아트 작품을 배치할 때 시각적 효과를 추가하고 싶은 경우도 있을 수 있습니다. 이 모듈은 클라이언트에 artChanged라는 이벤트를 노출함으로써 크리에이터가 연결하여 본인의 논리를 직접 추가할 수 있게 해줍니다.
LocalScript
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local SurfaceArt = require(ReplicatedStorage:WaitForChild("SurfaceArt"))
local function createParticleEmitter(canvas, position)
local attachment = Instance.new("Attachment")
attachment.Position = canvas.CFrame:PointToObjectSpace(position)
attachment.Axis = Vector3.new(0, 0, 1)
attachment.SecondaryAxis = Vector3.new(1, 0, 0)
attachment.Parent = canvas
local particleEmitter = Instance.new("ParticleEmitter")
particleEmitter.Speed = NumberRange.new(50)
particleEmitter.Rate = 50
particleEmitter.Color = ColorSequence.new(Color3.fromRGB(128, 254, 7))
particleEmitter.SpreadAngle = Vector2.new(35, 35)
particleEmitter.Parent = attachment
return attachment
end
SurfaceArt.artChanged:Connect(function(canvas, spot, spotPosition, artId, ownerId)
if artId then
-- Show some sparkles for 3 seconds
task.spawn(function()
local emitterAttachment = createParticleEmitter(canvas, spotPosition)
task.wait(3)
emitterAttachment:Destroy()
end)
end
end)
API 참조
유형
SurfaceArtAsset
캔버스에 아트로 사용할 이미지는 두 개의 값이 들어 있는 테이블로 표현됩니다.
키 | 설명 |
---|---|
name | 메타데이터 표시 이름입니다. |
assetId | 포함할 이미지의 애셋 ID입니다. |
함수
구성
configure(config:table):nil
config 테이블의 다음 키/값을 통해 기본 구성 옵션을 무효화합니다. 해당 함수는 Script에서만 호출할 수 있습니다.
일반
키 | 설명 | 기본 |
---|---|---|
enabled | 모듈의 기능을 켜거나 끄도록 토글합니다. | true |
assets | SurfaceArtAsset 유형의 목록입니다. | (코드 참조) |
quotaPerPlayer | 각 플레이어가 배치할 수 있는 아트의 최대 개수입니다. | 2 |
외형
키 | 설명 | 기본 |
---|---|---|
rowsPerCanvas | 캔버스 그리드에서 행의 개수입니다. | 2 |
colsPerCanvas | 캔버스 그리드에서 열의 개수입니다. | 5 |
itemsPerPage | 페이지를 왼쪽과 오른쪽으로 이동할 때 건너뛸 아이템의 개수입니다. | 3 |
canvasPaddingLeft | 표면 캔버스의 왼쪽 패딩입니다(UDim). | (0, 8) |
canvasPaddingRight | 표면 캔버스의 오른쪽 패딩입니다(UDim). | (0, 8) |
canvasPaddingTop | 표면 캔버스의 상단 패딩입니다(UDim). | (0, 8) |
canvasPaddingBottom | 표면 캔버스의 하단 패딩입니다(UDim). | (0, 8) |
promptImage | 아트 선택 보기를 입력하도록 근접 프롬프트에 표시되는 아이콘입니다. | "rbxassetid://8076723774" |
leftArrowPageImage | 이전 페이지로 넘어가는 왼쪽 화살표에 대한 이미지입니다. | "rbxassetid://6998633654" |
leftArrowItemImage | 이전 아트 아이템을 선택하는 왼쪽 화살표에 대한 이미지입니다. | "rbxassetid://8072765021" |
rightArrowPageImage | 다음 페이지로 넘어가는 오른쪽 화살표에 대한 이미지입니다. | "rbxassetid://6998635824" |
rightArrowItemImage | 다음 아트 아이템을 선택하는 오른쪽 화살표에 대한 이미지입니다. | "rbxassetid://8072764852" |
인터랙션
키 | 설명 | 기본 |
---|---|---|
promptKeyCode | 아트 선택을 입력하도록 프롬프트를 활성화하는 데 사용하는 키보드 단축키입니다(Enum.KeyCode). | E |
promptRequiresLineOfSight | 근접 프롬프트가 사용자와 캔버스 사이의 일직선상에 있어야 하는지 결정하는 부울 값입니다. | true |
promptMaxActivationDistance | 프롬프트 표시를 위해 플레이어의 캐릭터와 캔버스 사이에 가능한 최대 거리입니다. | 10 |
promptExclusivity | Enum.ProximityPromptExclusivity 동시에 표시할 수 있는 프롬프트를 지정합니다. | OnePerButton |
usePageHotkeys | 페이지 핫키를 사용할지 여부입니다. true일 경우, nextPageKey 및 prevPageKey를 사용하여 페이지 간에 이동합니다. | true |
nextPageKey | 다음 페이지의 아트 작품으로 넘어가는 데 사용하는 키입니다(Enum.KeyCode). | E |
nextItemKey | 다음 아트 작품 아이템으로 넘어가는 데 사용하는 키입니다(Enum.KeyCode). | Right |
prevPageKey | 이전 페이지의 아트 작품으로 넘어가는 데 사용하는 키입니다(Enum.KeyCode). | Q |
prevItemKey | 이전 아트 작품 아이템으로 넘어가는 데 사용하는 키입니다(Enum.KeyCode). | Left |
Script
local ReplicatedStorage = game:GetService("ReplicatedStorage")local SurfaceArt = require(ReplicatedStorage:WaitForChild("SurfaceArt"))SurfaceArt.configure({quotaPerPlayer = 4,promptKeyCode = Enum.KeyCode.T,promptMaxActivationDistance = 8,})
getCanvases
getCanvases():table
SurfaceCanvas 태그가 지정된 모든 캔버스를 반환합니다.
Script
local ReplicatedStorage = game:GetService("ReplicatedStorage")local SurfaceArt = require(ReplicatedStorage:WaitForChild("SurfaceArt"))local canvases = SurfaceArt.getCanvases()
placeArt
placeArt(player:Player, canvas:BasePart):nil
플레이어를 대신해 프로그래밍 방식으로 아트를 배치합니다. 서버를 초기화할 때 반드시 canvas 개체에 SurfaceCanvas 태그를 지정해야 합니다. 이 함수는 getCanvases에서 반환된 캔버스에만 사용하는 것이 좋습니다.
Script
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local SurfaceArt = require(ReplicatedStorage:WaitForChild("SurfaceArt"))
local remoteEvent = ReplicatedStorage:WaitForChild("SurfaceArtRemoteEvent")
remoteEvent.OnServerEvent:Connect(function(player)
-- Place the Bloxy Award from default art assets into the first canvas
local canvases = SurfaceArt.getCanvases()
SurfaceArt.placeArt(player, canvases[1], "BloxyAward")
end)
removeAllArt
removeAllArt():nil
모든 표면에서 모든 아트 작품을 삭제합니다.
Script
local ReplicatedStorage = game:GetService("ReplicatedStorage")local SurfaceArt = require(ReplicatedStorage:WaitForChild("SurfaceArt"))SurfaceArt.removeAllArt()
이벤트
artChanged
artChanged(canvas:BasePart, spot:Frame, spotPosition:Vector3, artId:string, ownerUserId:number): RBXScriptSignal
캔버스의 특정 위치에서 아트 작품이 변경되면 발생합니다. 아트 작품이 삭제되면 artId는 nil이 됩니다. 아트 작품을 배치할 정확한 위치에 사용자 지정 효과를 놓을 수 있도록 Vector3 값이 이벤트 핸들러에 세 번째 매개변수로 전달됩니다. 해당 이벤트는 LocalScript에서만 연결할 수 있습니다.
매개변수 | |
---|---|
canvas: BasePart | 아트 작품이 변경된 캔버스입니다. |
spot: Frame | 아트 작품 ImageLabel이 들어 있는 내부 Frame입니다. |
spotPosition: Vector3 | 아트 작품이 놓인 정확한 위치입니다. |
artId: string | 새로운 아트 작품의 애셋 ID입니다. |
ownerUserId: number | 아트를 배치한 플레이어의 UserId입니다. |
LocalScript
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local SurfaceArt = require(ReplicatedStorage:WaitForChild("SurfaceArt"))
SurfaceArt.artChanged:Connect(function(canvas, spot, spotPosition, artId, ownerId)
print("Art placed at:", spotPosition)
print("Art asset ID:", artId)
print("Art placed by:", ownerId)
end)
promptShown
promptShown(canvas:BasePart): RBXScriptSignal
캔버스 인터랙션 프롬프트가 플레이어에게 표시될 때 발생합니다. 연결된 함수는 이 프롬프트가 표시되는 캔버스를 수신합니다. 해당 이벤트는 LocalScript에서만 연결할 수 있습니다.
매개변수 | |
---|---|
canvas: BasePart | 프롬프트가 표시되는 캔버스입니다. |
LocalScript
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local SurfaceArt = require(ReplicatedStorage:WaitForChild("SurfaceArt"))
SurfaceArt.promptShown:Connect(function(canvas)
print(Players.LocalPlayer, canvas)
end)
promptHidden
promptHidden(canvas:BasePart): RBXScriptSignal
캔버스 인터랙션 프롬프트가 숨겨지면 발생합니다. 연결된 함수는 이 프롬프트가 표시되었던 캔버스를 수신합니다. 해당 이벤트는 LocalScript에서만 연결할 수 있습니다.
매개변수 | |
---|---|
canvas: BasePart | 프롬프트가 표시되었던 캔버스입니다. |
LocalScript
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local SurfaceArt = require(ReplicatedStorage:WaitForChild("SurfaceArt"))
SurfaceArt.promptClosed:Connect(function(canvas)
print(Players.LocalPlayer, canvas)
end)
selectorShown
selectorShown(): RBXScriptSignal
표면 아트 선택기 UI가 플레이어에게 표시될 때 발생합니다. 해당 이벤트는 LocalScript에서만 연결할 수 있습니다.
LocalScript
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local SurfaceArt = require(ReplicatedStorage:WaitForChild("SurfaceArt"))
SurfaceArt.selectorShown:Connect(function()
print(Players.LocalPlayer, "opened surface art selector")
end)
selectorHidden
selectorHidden(): RBXScriptSignal
표면 아트 선택기 UI가 플레이어에게 숨겨질 때 발생합니다. 해당 이벤트는 LocalScript에서만 연결할 수 있습니다.
LocalScript
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local SurfaceArt = require(ReplicatedStorage:WaitForChild("SurfaceArt"))
SurfaceArt.selectorHidden:Connect(function()
print(Players.LocalPlayer, "closed surface art selector")
end)