경험 내의 모든 환경에서 이동 생성 도구는 몰입감 있고 현실감 있는 세계를 즉시 만들 수 있습니다, 여기에는 환경 나무 이동, 플레이어 상호 작
폭풍 생성
The Mystery of Duvall Drive의 라이브 영역에 대해 결정하기 전에 폭풍은 여러 반복을 거쳐 왔습니다. 처음에는 폭풍을 거대한 흑요석 기둥으로 생각했고, 나중에는 그것을 복손 공간의 거대한 포털로 생각했습니다. 다양한 폭풍을
- 폭풍은 플레이어에게 이 이벤트가 세계에 미치는 영향 을 포함하여 나무가 날리고 쓰레기가 날아오는 것과 같은 세계의 모습을 제공해야 합니다.
- 구름 자체의 회전 소용돌이는 플레이어에게 모든 것을 보이지 않고 센터 포털을 살펴보게 해야 합니다 . 이렇게 하면 플레이어가 무슨 일이 일어나는지 더 조사하도록 장려합니다.
- 더 좁게 빛을 잡으면 집의 구성을 더 집중할 수 있습니다 집의 주요 캐릭터 및 게임 플레이 대부분이 위치한 곳.
폭풍이 환경 내에서 다이내믹, 공격적이고 항상 변화하는 느낌을 주기 위해 다음 시스템과 기능을 사용했습니다.
- TweenService > - 클라우드 이동을 위해.
- 조명 변경 사항 - 클라우드에서 번개를 생성하는 구름을 만듭니다.
- 광선 > - 음향 효과 및 번개 낚싯대에 대해.
- 입자 방출기 > - 풍으로 인해 포털에 날아가고 주변을 날아 다니는 경우.
- 애니메이션 > - 바람에 날리는 나무에 대해.
텍스처를 사용하여 구름 추가
정적 구름은 일반적인 고해상도 현실적인 구름에 적합하지만, 우리는 더 많은 것을
집을 완전히 둘러싸고 폭풍이 얼마나 거대한지 전달하기 위해 각 클라우드 메쉬가 필요했기 때문에 우리는 클라우드 메쉬를 타일하여 메쉬 표면 전체에 걸쳐 중복되도록 할 필요가 있음을 알았습니다. 우리는 이 간단한 부품에 대해 클라우드에서 테스트한
입자 방출기 또는 빔과는 달리, 메쉬는 각 메쉬에서 빛을 반사하여 클라우드 간 번개를 구현할 수 있게 했습니다. 또한 클라우드 간 번개를 구현하기 위해 트위스트에 모델링되었습니다. 특히 성능이 경험의 표면 모양 개체의 품질을 떨어��
회전 클라우드 메쉬
구름의 전반적인 시각적 모양에 대해 만족하면 이제 구름을 움직여야 했습니다! 우리는 각 구름 레이어의 일반적인 모양을 가지고 있었지만, 회전 효과가 클라우드를 실제로 드라이브하는지 확인하기 위해 몇
클라우드나 작은 픽셀과 같이 게임 플레이/물리학에 중요하지 않지만 클라이언트 서버 대역�
데모의 많은 경우에는 LocalSpaceRotation 태그를 사용하여 스튜디오에서 영향을 받는 인스턴스를 관리할 수 있었습니다. 인스턴스 태그 플러그인을 사용하여 Studio에서 모든 영향을 받는 인스턴스를 관리했습니다. 개발 프로세스 전반에 ��
local function Init()
for _, obj in CollectionService:GetTagged("LocalSpaceRotation") do
if obj:IsDescendantOf(workspace) then
SetupObj(obj)
end
end
end
CollectionService:GetInstanceAddedSignal("LocalSpaceRotation"):Connect(function(obj)
objInfoQueue[obj] = true
end)
CollectionService:GetInstanceRemovedSignal("LocalSpaceRotation"):Connect(function(obj)
if objInfo[obj] then
objInfo[obj] = nil
if objInfoQueue[obj] then
objInfoQueue[obj] = nil
end
end
end)
Init()
objInfo
우리는 심박 기능에 연결된 Update 함수에서 인스턴스를
local parentTransformif parentObj:IsA("Model") thenif not parentObj.PrimaryPart then-- 주요 부품은 아직 스트림되지 않을 수 있습니다.continue -- 주 부품 복제를 위해 대기endparentTransform = parentObj.PrimaryPart.CFrameelseparentTransform = parentObj.CFrameendcurObjInfo.curAngle += dT * curObjInfo.timeToAnglelocal rotatedLocalCFrame = curObjInfo.origLocalCFrame * CFrame.Angles( curObjInfo.axisMask.X * curObjInfo.curAngle, curObjInfo.axisMask.Y * curObjInfo.curAngle, curObjInfo.axisMask.Z * curObjInfo.curAngle )if obj:IsA("Model") thenobj.PrimaryPart.CFrame = parentTransform * rotatedLocalCFrameelseobj.CFrame = parentTransform * rotatedLocalCFrameend
스트리밍을 처리할 유효한 Model.PrimaryPart 을 확인했습니다. 업데이트가 우리 개체에 호출되었으며 Model.PrimaryPart (자식 메쉬에 지정될 수 있음)가 아직 스트리밍
번개 공격 디자인
Studio는 상자에서 번개 생성기를 제공하지 않으며 입자 시스템이 영웅 번개 공격에 작동하지 않는 한 영웅 번개 공격을 위한 솔루션을 만들어야 했습니다. 우리는 영웅 번개 공격을 위해 영웅 번개 공격을 위한
텍스처링 빔
일반적으로 시퀀서나 타이밍 도구를 사용하여 이와 같은 조명 볼트 타이밍 효과의 타이밍을 드라이브하지만 Studio는 아직 이 기능을 제공하지 않기 때문에 조명 볼트 타이밍을 제어하는 스크립트를 작성했습니다. 이 효과의 스크립트는 간단하지만 다음과 같은 중요한 목표를 달성합니다
- 번개 충격의 요소, 예를 들어 텍스처, 밝기 및 지연,은 모든 번개 충격에 랜덤화됩니다.
- 오디오 및 포스트 FX 변경은 스트라이크 FX와 동기화됩니다.
- 플레이어가 실내에 있거나 손상된 지역에 있는 경우 시각적 또는 청각적으로 그들을 볼 수 없습니다.
우리는 서버 사이드 Script 이 있습니다. 다양한 매개 변수 및 타이밍을 계산하고 모든 클라이언트에 보내고 랜덤 시간을 기다립니다.
local function LightningUpdate()
while true do
task.wait(rand:NextNumber(3.0, 10.0))
local info = CreateFXData()
lightningEvent:FireAllClients(info)
end
end
CreateFXData 내에서 구조를 채우고, 모든 클라이언트가 동일한 매개 변수를 가져옵니다.
클라이언트 측( LightningVFXClient ), 우리는 이 클라이언트가 FX를 실행해야 하는지 확인합니다.
local function LightningFunc(info)
…
-- 실내에는 FX가 없습니다
if inVolumesCheckerFunc:Invoke() then
return
end
-- 일반 세계에 있지 않을 때는 no FX
if not gameStateInfoFunc:Invoke("IsInNormal") then
return
end
…
또한 텍스처, 위치 및 밝기를 설정하기 위해 시퀀스를 실행하고, 트위ン을 실행하고, task.wait(number) 을 사용합니다. 일부 숫자는 서버로부터 수신한 정보 구조체에서 나온 랜덤 매개 변수이며, 일부 숫자는 고정되어 있습니다.
beam.Texture = textures[info.textIdx]beamPart.Position = Vector3.new(info.center.X + og_center.X, og_center.Y, info.center.Y + og_center.Z)-- 지우기beam.Brightness = 10ppCC.Brightness = maxPPBrightnessppBloom.Intensity = 1.1bottom.Position = top.PositiontweenBrightness:Play()tweenPPBrightness:Play()tweenPPBrightness:Play()tweenBottomPos:Play()tweenBrightness.Completed:Wait()-- 오디오if audioFolder and audioPart thenif audioFolder.Value and audioPart.Value thenaudioUtils.PlayOneShot(audioObj, audioFolder.Value, audioPart.Value)endendtask.wait(info.waitTillFlashes)-- and so on
플레이어가 실내에 있는지 확인하려면 도우미 기능 inVolumesCheckerFunc 를 사용하여, 실내 영역에 해당하는 미리 설정된 볼륨을 검사하고 플레이어 위치가 해당 볼륨 중 하나에 있는지
플레이어가 부패 영역에 있는지 여부를 확인하려면 도우미 기능 gameStateInfoFunc 을 호출하여 현재 게임 상태를 확인합니다. 폴더에서 랜덤 사운드를 재생하려면 도우미 기능 PlayOneShot 을 사용했습니다. 라이트��
입자 방출기 시스템 사용
영웅 번개 폭은 배경에 구름 층을 만들고 멀리 번개를 생성하거나 구름 간 조명을 통해 멀리 번개를 생성하는 것과 같은 먼 번개를 지원하는 입자 시스템에 의해 지원됩니다. 이 효과는 매우 간단한 입자 시스템을 통해 구름 배지를 번쩍이게 하
바람에 나무를 불어 넣기
구름과 번개가 원하는 대로 작동하는 방식을 가지고 있으면 우리는 또한 풍과 비를 추가해야 했습니다. 이 요소는 물리 및 특수 효과 시스템의 현재 제한을 초과하여 작동해야 하기 때문에 몇 가지 도전을 발생시�
우리는 바람과 비의 효과를 정말로 판매하기 위해 나무 자체를 움직이는 것이 필요했습니다. 나무를 움직이는 데 사용되는 몇 가지 방법이 있습니다. 플러그인을 사용하여 나무를 움직이거나 직
종료 모델 팩 - 숲 자산 에서 몇 그루의 나무를 스킨했습니다. 이 나무는 이미 존재했기 때문에 우리의 경험은 황량한 북부 동부에서 발생했습니다. 각 나무 모델을 생성해야 할 시간을 절약했습니다.
나무를 선택한 후, 우리는 그것들을 피부에 적용해야 한다는 것을 알았습니다. 메쉬를 스킨하는 것은 3D 모델링 애플리케이션에서 메쉬에 연결(또는 뼈)를 추
우리는 시간을 절약하고 동일한 애니메이션을 재사용하려는 것을 알았으므로 첫 번째 트리 리그를 구축하고 공동 이름이 일반적인지 확인했습니다. 우리는 또한
우리의 관절/뼈를 만든 후, 테스트 애니메이션을 만들어 스튜디오의 모든 관절 및 뼈를 이동하여 원하는 방식으로 이동하는지 확인하기 위해 테스트 애니메이션을
그 나무의 결과에 만족한 후, 다른 나무에서 동일한 애니메이션을 테스트할 시간이 왔습니다! 우리는 이미 각 나무 입력대해 동일한 애니메이션이 있음을 알고 있었기 때문에 높은 레드우드와 견고한 베치나무 나무 사이의 다른 망가트리기 위해 애니메이션이 일관되어
이를 위해 숲 팩에서 벌목한 벌목 나무를 가져와 비슷한 리그를 구축했습니다. 이 리그는 동일한 이름을 사용하여 관절을 모두 조인하는 동일한 리그를 사용합니다. 이렇게 하면 이전에 가져온 애니메이션이 이 나무에도 적용될 수 있습니다. 애니메이션
벌목 및 스킨 후에 벌목 및 스킨 나무를 리그하고 적용하면 우리는 정확히 동일한 애니메이션을 가져올 수 있고 이동하여 적용할 수 있습니다. 이는 단일 파일에서만 반복하고 편집해야 하는 의미를 나타내며 경험을 실행할 때 성능에 대해 적용되는 적은 애니메이션을 저장합니다.
모든 트리 유형을 모두 애니메이션을 원했으므로 각각을 패키지로 만들어 우리는 애니메이션을 편집하고 업데이트하면서 계속할 수 있었습니다. 성능 비용이 있기 때문에 집에서 효과가 가장 가치가 있는 곳에 더 많은 스컬 메�
폭풍 잔해 만들기
우리는 비가 힘들게 보이고, 안개와 잔해가 나무에 부딪히도록 하기 위해 몇 가지 투명한 부품을 설정했습니다. 이를 하려면 Studio의 입자 제한 한도 때문에 플레이어가 전체 공간에 입자를
비는 새로운 입자 생성기 속성 ParticleEmitter.Squash 를 사용하여 입자를 더 길게 또는 더 많이 만들
안개, 안개 및 잎사리가 휘몰리는 경우, 단일 큰 부품 볼륨을 추가하는 것이 훨씬 더 간단했습니다. 우리는 한 번에 많은 입자를 실행할 필요가 없기 때문에 단일 큰 부품 볼륨을 설정하고 원하는 위치에 입자 횟수를 설정했습니다. 시작하려면 볼륨을 설정하고 원하는
그 후, 우리는 잎사귀 흐림 및 바람 텍스처를 만들고 모든 입자를 다른 속도로 회전/이동하고 시작하도록 설정했습니다. 이것은 더 큰 안개 입자가 더 자연스럽게 상호 작용하지 않고 반복 텍스처가 아닌 속도로 시작하기 때문에 더 큰 텍스처가 더 자연스럽게 보이지 않았습니다.
결과는 나무가 움직이고, 창문이 부서지고, 번개가 번개를 만드는 동안의 몇 가지 대단한 작업으로 스톰 주변의 중심 눈을 묘사하는 효과를 만드는 것이었습니다.
폭풍의 눈 설정
빛나는 핵심이 있는 갈라진 돌 눈은 플레이어에게 집에서 무언가 사악하고 신비한 일이 발생하고 있다는 첫 번째 힌트를 제공하기 위한 것입니다. 우리의 씬이
플레이어로부터의 거리는 또한 눈의 표면 세부 정보를 위해 일반 맵에 완전히 의존할 수 있음을 의미했습니다. 그래서 메쉬는 단순한 캔버스입니다! 우리는 세부 정보를 높은 폴리 메쉬로 조각했고 일반 맵을 훨씬 더 낮은 폴리 메쉬에 베이킵니
눈에 슈퍼 자연스러운 느낌을 추가하고 그 존재를 강조하기 위해, 우리는 그것이 갈라진 곳을 통해 ��
눈을 만드는 데 사용된 다른 도전은 플레이어의 시야에서 눈의 거리를 결합한 스트리밍 기
눈과 그 반지에 이동 메쉬를 추가할 수 있었던 것은 같은 스크립트 때문입니다 클라우드 메쉬를 회전
확장 식량 창고 만들기
가장 재미있는 것은 플레이어의 기대를 완전히 변경하여 현실을 왜곡시키는 것이었습니다. 예를 들어, 아버지의 퍼즐에서 우리는 악몽처럼 빨리 달리는 것처럼 보이는 방을 완전히 변경하여 플레이어의 기대를 충족시
벽을 단순하게 이동하고 창고에서 양쪽에 나타나는 방의 지능적인 레이아웃으로 이것을 설정했습니다. 벽은 평소 상태에서 복도 양쪽에 나타나는 단순한 복도였지만, 손상된 공간에서는 여러 개의 날개와 가짜 벽으로 훨씬 더 길게 나타났습니다!
가짜 벽은 플레이어가 트리거 볼륨에 들어갈 때 다시 이동할 모델 그룹이었습니다. 그것은 공장에서 걸어갈 수 있는 투명한 부분이었습니다. 그 트리거는 또한 모든 문에 사용된 스크립트와 비슷한 스크립
Class.TweenService는 모든 벽 데이터 모델에 동일한 구성 요소가 포함되어 있어야 합니다. 예를 들어, 다음 이미지는 하단의 "Grow_Wall" 모델에 정의된 사운드를 호출하는 일반 문 스크립트의 예입니다.
이 코드 샘플에 대한 몇 가지 수정을 통해 동일한 스크립트가 또한 창고 이동에 대한 오디오를 트리거했습니다. 이것은 이동에 많은 것을 추가했습니다!
local Players = game:GetService("Players")
local TweenService = game:GetService("TweenService")
local model = script.Parent
local sound = model.Sound.Value
local trigger = model.Trigger
local left = model.TargetL_Closed
local right = model.TargetR_Closed
local tweenInfo = TweenInfo.new(
model.Speed.Value, --문 트윈의 시간/속도
Enum.EasingStyle.Quart, --부드러운 스타일
Enum.EasingDirection.InOut, --쉬운 방향
0, --카운트 반복
false, --Reverse true
0 --지연
)
local DoorState = {
["Closed"] = 1,
["Opening"] = 2,
["Open"] = 3,
["Closing"] = 4,
}
local doorState = DoorState.Closed
local playersNear = {}
local tweenL = TweenService:Create(left, tweenInfo, {CFrame = model.TargetL_Open.CFrame})
local tweenR = TweenService:Create(right, tweenInfo, {CFrame = model.TargetR_Open.CFrame})
local tweenLClose = TweenService:Create(left, tweenInfo, {CFrame = model.TargetL_Closed.CFrame})
local tweenRClose = TweenService:Create(right, tweenInfo, {CFrame = model.TargetR_Closed.CFrame})
local function StartOpening()
doorState = DoorState.Opening
sound:Play()
tweenL:Play()
tweenR:Play()
end
local function StartClosing()
doorState = DoorState.Closing
--모델 ["Door"]:Play()
tweenLClose:Play()
tweenRClose:Play()
end
local function tweenOpenCompleted(playbackState)
if next(playersNear) == nil then
StartClosing()
else
doorState = DoorState.Open
end
end
local function tweenCloseCompleted(playbackState)
if next(playersNear) ~= nil then
StartOpening()
else
doorState = DoorState.Closed
end
end
tweenL.Completed:Connect(tweenOpenCompleted)
tweenLClose.Completed:Connect(tweenCloseCompleted)
local function touched(otherPart)
if otherPart.Name == "HumanoidRootPart" then
local player = Players:GetPlayerFromCharacter(otherPart.Parent)
if player then
--print("触摸")
playersNear[player] = 1
if doorState == DoorState.Closed then
StartOpening()
end
end
end
end
거짓 벽이 방의 뒷면으로 움직이면 나머지 콘텐츠를 움직일 필요가 있었습니다. 이를 하려면 저장소에서 모든 유사한 항목을 벽과 함께 붙여야 했습니다. 웨일 제약 을
타락한 나무 집을 만드는 것
Studio는 모든 것을 스윙 게이트에서 회전 플랫폼으로 만들 수 있는 완전히 물리적 기반 엔진입니다. 데모를 통해 우리는 물리를 사용하여 현실적이지 않은 집합의 환경에 실제감을 주기 위해 모든 것을 만들 수 있습니다! Studio에서 몇 가지 제한 사항을 사용하여 흥미
제약 조건 은 물리적으로 기반한 모터 그룹입니다. 예를 들어, 낚싯대 제약 조건 을 사용하여 개체를
플레이어가 퍼즐의 메인 영역에 도착하자, Roblox에서 친숙한 모습을 맞이했습니다. 장애물 코스는 여러 개의 회전 플랫폼과 회전 벽으로 구성되었습니다. "안전 영역"은 스토리를 진행하는 데 도움이 되는 요소입니다. 우리는 회전/회전 요소에 집중합니다.
왜 여기에 제한자를 사용했나요? 왜냐하면 TweenService 또는 다른 메서드가 플레이어가 서 있을 때 플레이어를 이동하지 않았기 때문입니다. 플레이어가 서 있을 때 플레이어
이것을 하기 위해서는 먼저 현재 키트의 자산을 사용하여 시각적 효과용 콘텐츠를 추가해야 했습니다. 몇 가지 미완성된 벽과 플랫폼을 만들었습니다. 이 이야기는 나무 오두막을 지은 할머니에 대한 이야기입니다. 독특
제약 조건을 사용하기 때문에 이러한 메쉬를 앵커로 사용할 수 없다는 것을 알고 있었습니다
이제 섬유 제한 구의 실제 동작을 설정하고 부품과 제한 구의 방향을 함께 작동하는 부착물을 추가할 때입니다. 우리는 부품을 부착하기 위해
플랫폼이 일정한 속도로 회전하도록 하려면 HingeConstraint.AngularVelocity, HingeConstraint.MotorMaxAcceleration, HingeConstraint.MotorMaxTorque 속성을 값으로 설정하여 플레이어가 플랫폼에 점프하더라도 이동을 허용하고 방해를 방
이제 우리는 회전하는 벽을 만들어야 했습니다. 벽은 중심에 회전해야 했고, 우리는 레벨 나머지에 대해 모든 방향을 처리할 수 있도록 하기를 원했습니다. 플랫폼과 마찬가지로 이 모든 벽을 고정하지 않고 접합하여 모터_턴을 처리할 수 있도록 했습니다.
우리는 기본 재료에 변화를 주기 위해 Texture 개체 위에 SurfaceAppearance 개체를 사용했습니
몇 개의 플랫폼과 회전 벽을 테스트한 후 우리는 몇 가지 변형을 만들고 그들의 배치를 조정하여 장애 코스가 도전적이고 마음에 남는 지 확인했습니다! 플랫폼과 벽이 서로 충돌하거나 환경과 충
물리적 개체가 충돌하는 것이 확실하지 않은 경우, 시각화 옵션 위젯에서 충돌 정확도를 토글하여 3D 뷰포트의 왼쪽 상단 모서리에서 충돌 펠리티를 활성화할 수 있습니다.
아래 문/창 구멍에 보이는 것은 바로 알 수 있듯이, 하지만 하위 패널, 즉 하단 판 패널은 보이지 않습니다. 이는 벽의 CollisionFidelity 속성이 상자로 설정되었기