Phát triển một thế giới di chuyển

*Nội dung này được dịch bằng AI (Beta) và có thể có lỗi. Để xem trang này bằng tiếng Anh, hãy nhấp vào đây.

Tạo chuyển động trong bất kỳ môi trường nào trong trải nghiệm giúp nó ngay lập tức cảm thấy sâu sắc và thực tế hơn với thế giới của chúng ta, cho dù đó là từ sự di chuyển của cây môi trường, cửa phản ứng từ tương tác của người chơi, hoặc thậm chí là hộp di chuyển khi chúng va chạm vào chúng.Studio có nhiều phương pháp độc đáo để tạo chuyển động nhằm giúp thế giới cảm thấy sống động hơn, bao gồm một hệ thống vật lý, TweenService , và hoạt hình, và phân tích nhu cầu cụ thể của trải nghiệm của bạn có thể giúp bạn xác định cái nào để sử dụng.Trong phần này, chúng tôi sẽ minh họa cách chúng tôi xác định loại chuyển động mà chúng tôi muốn tạo ra trong Studio, và các công cụ chúng tôi sử dụng để hoàn thành các mục tiêu riêng biệt này.

Tạo bão

Cơn bão đã trải qua nhiều lần lặp lại trước khi chúng tôi đi đến những gì đang sống trong Bí ẩn của Duvall Drive.Sớm, chúng tôi nghĩ về cơn bão như một cột đá núi lửa khổng lồ, và trong các lần lặp lại sau, chúng tôi xem nó là một cổng lớn đến không gian bị hỏng.Sau khi thử nghiệm với nhiều cơn bão khác nhau với cái nhìn và cảm giác độc đáo cho chúng, chúng tôi đã quyết định vào một cơn bão có "mắt" trung tâm nhỏ hơn bởi vì:

  • Bão nên cho người chơi cảm giác về tác động của sự kiện này đối với thế giới , bao gồm cả cây thổi và vật thể bay quanh.
  • Vòng xoáy quay của chính đám mây sẽ cho người chơi một cái nhìn vào cổng trung tâm mà không tiết lộ mọi thứ .Điều này sẽ khuyến khích người chơi điều tra gần hơn để xem những gì đang xảy ra.
  • Điểm sáng chặt chẽ hơn sẽ cho phép chúng tôi tập trung vào bố trí của ngôi nhà , đó là cả nhân vật chính và nơi hầu hết các hoạt động chơi game diễn ra.

Để làm cho bão cảm thấy năng động, hung hăng và luôn thay đổi trong môi trường của nó, chúng tôi đã sử dụng các hệ thống và tính năng sau:

  1. TweenService - Dành cho di chuyển đám mây.
  2. Thay đổi ánh sáng - Để tạo ra tia sét từ đám mây sang đám mây.
  3. Chùm tia - Dành cho "ánh sáng khối lượng" và các tia sét.
  4. Máy phát hạt > - Đối với chất thải bay lên cổng và bay xung quanh do gió thổi.
  5. Hoạt hình > - Đối với những cây đang thổi theo gió.

Thêm đám mây với kết cấu

Trong khi đám mây năng động tuyệt vời cho những đám mây thực tế bình thường, cao độ cao, chúng tôi cần một cái gì đó cảm thấy gay cấn và chúng tôi có thể chỉ đạo và tùy chỉnh nhiều hơn.Để làm điều này, chúng tôi áp dụng hiệu ứng bề mặt của đối tượng với độ trong suốt một phần đến một loạt lưới đám mây được xếp chồng và phân tầng nặng nề nhằm làm giả phủ đám mây.Tại sao chúng tôi xếp chồng chúng và phân tầng chúng nặng nề như vậy? Bởi vì khi mỗi lưới đám mây di chuyển với tốc độ khác nhau, chúng chồng lên nhau và tạo ra các hình dạng đám mây đi vào và ra khỏi nhau.Quá trình này làm cho các đám mây cảm thấy hơi thêm năng động và tự nhiên, mặc dù chỉ là những đĩa quay.Nó cũng quan trọng là những đám mây phải bán trong suốt, bởi vì chúng tôi muốn người chơi có thể nhìn xuyên qua chúng để nhìn thấy điều gì đó sáng bên trong trước khi đến nhà!

Một lưới đám mây duy nhất.
>

Lưới đám mây lớp nhau mà không có kết cấu của chúng!
>

Vì mỗi lưới đám mây cần phải lớn để hoàn toàn bao quanh ngôi nhà và thể hiện mức độ lớn của bão, chúng tôi biết rằng chúng tôi cần phải lát lại kết cấu mà chúng tôi muốn sử dụng trên các lưới đám mây riêng lẻ để nó sẽ lặp lại rất nhiều trên bề mặt của lưới.Chúng tôi đã kiểm tra các vật liệu chúng tôi tạo cho đám mây trên những phần đơn giản này, sau đó áp dụng chúng vào vortex!

Không giống như các phát xạ viên hoặc chùm tia, lưới cho phép chúng tôi có thể phản xạ ánh sáng khỏi mỗi lưới, điều này rất quan trọng khi chúng tôi muốn triển khai sấm sét từ đám mây sang đám mây.Chúng tôi cũng mô hình hóa trong khi quay vòng để ánh sáng phản xạ khỏi nó trông giống như nó có độ sâu! Điều này là quan trọng đặc biệt trong những tình huống mà yêu cầu về hiệu suất của trải nghiệm làm giảm các cấp độ chất lượng của các đối tượng xuất hiện trên bề mặt của chúng tôi.

Khi chúng tôi bắt đầu thêm ánh sáng vào nó, chúng tôi cần phải thêm chi tiết vào lưới để làm cho chúng phản ứng tốt hơn với ánh sáng!

Xoay lưới đám mây

Sau khi chúng tôi hài lòng với sự xuất hiện hình thị giác tổng thể của các đám mây, chúng tôi cần phải di chuyển nó! Chúng tôi có các hình dạng chung của mỗi lớp đám mây trong địa điểm, nhưng nó đã mất một số thử nghiệm và sai lầm để đảm bảo hiệu ứng quay xoay trông tốt trong thực tế.Chúng tôi ban đầu đã thử sử dụng hạn chế để giới thiệu tốc độ sẽ vật lý dẫn các đám mây di chuyển.Điều này khó hơn chúng tôi muốn nó được lặp lại sau này, và người chơi sẽ không bao giờ tương tác với nó, vì vậy chúng tôi không cần nó phải chính xác trong chuyển động của nó.

Chúng tôi muốn một phương pháp dễ sử dụng để xoay các thực thể có quá xa để tương tác, chẳng hạn như đám mây, hoặc quá nhỏ hoặc trang trí để quan trọng cho trò chơi/vật lý, chẳng hạn như đồ nội thất nhỏ như đèn nhỏ.Chúng tôi quyết định sử dụng một LocalScript để giảm băng thông khách-máy chủ, cho phép di chuyển mượt hơn và mỗi khối lưới đám mây có thể có tốc độ xoay và trì hoãn khác nhau.Để làm cho nó trở nên chung chung hơn, chúng tôi cũng đã làm cho nó có thể xác định trục xoay.Bạn có thể sử dụng 3 thuộc tính, nhưng trong trường hợp của chúng tôi chúng tôi đã sử dụng 3 giá trị: Axis , DelaySpeed .

Như trong nhiều trường hợp trong phần trình diễn, chúng tôi đã sử dụng một thẻ LocalSpaceRotation để có thể quản lý các ví dụ bị ảnh hưởng trong Studio bằng cách sử dụng một plugin đánh dấu ví dụ.Chúng tôi chỉ sử dụng một đơn vị LocalScript duy nhất xử lý tất cả các ví dụ được gắn thẻ bằng cách sử dụng CollectionService để chúng tôi không có quá nhiều kịch bản để duy trì trong suốt quá trình phát triển.

Trong bản trình bày của chúng tôi, một phần của thế giới được sao chép từ ServerStorage vào không gian làm việc theo yêu cầu, vì vậy chúng tôi cần xử lý các trường hợp mà các đối tượng được gắn thẻ đã được tạo và phá hủy.Với LocalScripts, chúng ta cũng phải lưu ý đến việc phát trực tiếp, nơi mà lưới và giá trị con của chúng có thể được phát trong và ra ngoài.Chúng tôi xử lý ban đầu đặt các đối tượng trong chức năng Init() và kết nối với CollectionService.GetInstanceAddedSignalCollectionService.GetInstanceRemovedSignal đối với các đối tượng được gắn thẻ để xử lý các đối tượng được tạo mới/bị xóa.Chức năng tương tự SetupObj đã được sử dụng để khởi tạo các đối tượng mới trong Init() và trong CollectionService.GetInstanceAddedSignal .


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 là một bản đồ có thông tin cho tất cả các đối tượng liên quan, chẳng hạn như tốc độ quay và trục của chúng.Lưu ý rằng chúng tôi không gọi SetupObj từ CollectionService.GetInstanceAddedSignal ngay lập tức, nhưng chúng tôi đã thêm một đối tượng vào objInfoQueue . Với việc phát trực tuyến và sao chép các đối tượng trên máy chủ, khi CollectionService.GetInstanceAddedSignal được gọi, chúng ta có thể chưa có chúng tôi Axis , DelaySpeed giá trị, vì vậy chúng tôi thêm đối tượng vào hàng đợi và gọi SetupObj vào các khung tiếp theo từ chức năng Update cho đến khi các giá trị có được và chúng tôi có thể đọc chúng vào cấu trúc "info" mỗi đối tượng.

Chúng tôi đã xoay các thời gian trong chức năng Update kết nối với nhịp tim.Chúng tôi có transform cha (parentTransform), tích lũy một góc xoay mới ( curObjInfo.curAngle ) dựa trên tốc độ xoay của đối tượng này, tính toán transform địa phương ( rotatedLocalCFrame) , và cuối cùng đặt nó vào CFrame .Lưu ý rằng cả cha và đối tượng có thể là một Model hoặc MeshPart, vì vậy chúng tôi phải kiểm tra IsA("Mô hình") và sử dụng một trong hai PrimaryPart.CFrame hoặc CFrame.


local parentTransform
if parentObj:IsA("Model") then
if not parentObj.PrimaryPart then
-- phần chính có thể chưa được phát trực tiếp
continue -- chờ phần chính để sao chép
end
parentTransform = parentObj.PrimaryPart.CFrame
else
parentTransform = parentObj.CFrame
end
curObjInfo.curAngle += dT * curObjInfo.timeToAngle
local rotatedLocalCFrame = curObjInfo.origLocalCFrame * CFrame.Angles( curObjInfo.axisMask.X * curObjInfo.curAngle, curObjInfo.axisMask.Y * curObjInfo.curAngle, curObjInfo.axisMask.Z * curObjInfo.curAngle )
if obj:IsA("Model") then
obj.PrimaryPart.CFrame = parentTransform * rotatedLocalCFrame
else
obj.CFrame = parentTransform * rotatedLocalCFrame
end

Chúng tôi kiểm tra có một Model.PrimaryPart hợp lệ để được đặt để xử lý phát trực tiếp.Nếu một bản cập nhật được gọi trên đối tượng của chúng tôi trong khi một Model.PrimaryPart (có thể chỉ ra một khối lượng con) chưa được phát trực tiếp, chúng tôi sẽ bỏ qua bản cập nhật.Hệ thống hiện tại là lần lặp lại thứ hai của việc xoay đối tượng, và hệ thống trước đó hoạt động khác nhau: các giá trị khác nhau 12 lần! Để giữ cùng một dữ liệu, chúng tôi chuyển đổi nó trong kịch bản của chúng tôi, như "12 * obj.Speed.Value".

Thiết kế sấm sét

Bởi vì Studio không cung cấp một máy phát sét ra khỏi hộp, và hệ thống hạt có một số hạn chế sẽ không hoạt động đối với các trận sét anh hùng, chúng tôi phải sáng tạo với một giải pháp cho các trận sét anh hùng.Chúng tôi quyết định trên hai hệ thống chính để tạo ra sấm sét: các tia có kết cấu cho các đòn sấm sét anh hùng đến từ mắt bão là các tia có kết cấu khai thác và đồng bộ với hiệu ứng âm thanh và hiệu ứng xử lý hình ảnh, và một hiệu ứng hạt đơn giản cho sấm sét xa từ đám mây đến đám mây.

Dải kết cấu

Thông thường, chúng tôi sẽ sử dụng công cụ sequencer hoặc công cụ timeline để điều khiển thời gian của một hiệu ứng đánh sáng như thế này, nhưng vì Studio chưa cung cấp chức năng này, chúng tôi quyết định viết các kịch bản sẽ kiểm soát thời gian đánh sáng.Viết kịch bản cho hiệu ứng này khá đơn giản, nhưng nó hoàn thành các mục tiêu quan trọng sau:

  1. Các yếu tố của tia sét, chẳng hạn như kết cấu, độ sáng và thời gian trì hoãn, được ngẫu nhiên hóa với mỗi cú đánh.
  2. Thay đổi âm thanh và hình ảnh sau FX đồng bộ với đánh FX.
  3. Người chơi ở trong nhà hoặc trong khu vực bị hư hỏng sẽ không thể nhìn thấy hoặc nghe thấy chúng.

Chúng tôi có một bên máy chủ Script tính toán các tham số và thời gian khác nhau, gửi chúng cho tất cả các khách hàng và chờ đợi một số thời gian ngẫu nhiên:


local function LightningUpdate()
while true do
task.wait(rand:NextNumber(3.0, 10.0))
local info = CreateFXData()
lightningEvent:FireAllClients(info)
end
end

Bên trong CreateFXData , chúng tôi lấp đầy cấu trúc thông tin, để tất cả các khách hàng nhận được các tham số tương tự.

Ở phía khách hàng ( LightningVFXClient ), chúng tôi kiểm tra xem khách hàng này có nên chạy FX:


local function LightningFunc(info)
-- không có FX khi ở trong nhà
if inVolumesCheckerFunc:Invoke() then
return
end
-- không có FX khi không ở trong thế giới "bình thường"
if not gameStateInfoFunc:Invoke("IsInNormal") then
return
end

Ngoài ra, chúng tôi chạy chuỗi để đặt kết cấu, vị trí và độ sáng, chạy tweens, và sử dụng task.wait(number).Các tham số ngẫu nhiên là từ cấu trúc thông tin mà chúng tôi nhận được từ máy chủ, và một số số được cố định.


beam.Texture = textures[info.textIdx]
beamPart.Position = Vector3.new(info.center.X + og_center.X, og_center.Y, info.center.Y + og_center.Z)
-- Xóa bỏ
beam.Brightness = 10
ppCC.Brightness = maxPPBrightness
ppBloom.Intensity = 1.1
bottom.Position = top.Position
tweenBrightness:Play()
tweenPPBrightness:Play()
tweenPPBrightness:Play()
tweenBottomPos:Play()
tweenBrightness.Completed:Wait()
-- âm thanh
if audioFolder and audioPart then
if audioFolder.Value and audioPart.Value then
audioUtils.PlayOneShot(audioObj, audioFolder.Value, audioPart.Value)
end
end
task.wait(info.waitTillFlashes)
-- and so on

Để kiểm tra xem một người chơi có ở trong nhà không, chúng tôi sử dụng chức năng trợ giúp inVolumesCheckerFunc, đi qua các khối được đặt trước không gian nội thất và kiểm tra xem vị trí người chơi có nằm trong bất kỳ khối nào không (PointInABox).Chúng tôi có thể đã sử dụng dò xét dựa trên cảm ứng, nhưng chúng tôi phát hiện ra rằng khi một người chơi ngồi vào khối lượng, họ không còn "chạm" vào khối lượng nữa.Thử nghiệm một điểm trong vài hộp đơn giản hơn, và chúng tôi chỉ làm điều đó khi một người chơi di chuyển xa đủ từ vị trí đã kiểm tra trước đó.

Để kiểm tra xem một người chơi có ở trong các khu vực bị hư hỏng không, chúng tôi kích hoạt chức năng trợ giúp gameStateInfoFunc, kiểm tra tình trạng trò chơi hiện tại.Để chơi một âm thanh ngẫu nhiên từ một thư mục, chúng tôi cũng sử dụng chức năng trợ giúp PlayOneShot .Đối với các tia sét riêng, chúng rất dễ dàng tạo ra trong Photoshop; chúng tôi vẽ một dòng cong, sau đó thêm một hiệu ứng lớp "Ánh sáng bên ngoài".

Sử dụng hệ thống phát hạt

Các cuộc tấn công sét anh hùng được hỗ trợ bởi một hệ thống hạt cố gắng gợi lên tia sét xa bằng cách tạo ấn tượng về một lớp mây trên nền bắt ánh sáng từ các đòn tấn công xa, hoặc ánh sáng từ đám mây đến đám mây.Chúng tôi đạt được hiệu ứng này thông qua một hệ thống hạt rất đơn giản chiếu một biển quảng cáo trên đám mây bão chính.Hệ thống phát ra một khoảng thời gian hạt mây định kỳ với một đường cong minh bạch ngẫu nhiên:

Làm cho cây thổi theo gió

Sau khi chúng tôi có đám mây và sấm sét hoạt động theo cách chúng tôi muốn, chúng tôi sau đó cần thêm hai thành phần chính khác của một cơn bão: gió và mưa! Những yếu tố này đã đặt ra một vài thách thức, bao gồm cả việc cần phải làm việc trong giới hạn hiện tại của hệ thống vật lý và hiệu ứng đặc biệt của Studio.Ví dụ, làm cho cây di chuyển theo gió thực tế không thể thực hiện được trong động cơ ngày nay, vì vậy chúng tôi đã sử dụng hiệu ứng phát hạthoạt hình nhân vật tùy chỉnh cho cây.

Chúng tôi biết thực sự bán hiệu ứng của gió và mưa, chúng tôi cần cây tự di chuyển.Có một vài cách bạn có thể thực hiện điều này trong động cơ, bao gồm di chuyển các bộ phận bằng cách sử dụng plugin công khai, sử dụng TweenService , hoặc diễn hoạ mô hình trực tiếp.Vì mục đích của chúng tôi, các hoạt hình đã cho chúng tôi khả năng kiểm soát chuyển động mà chúng tôi muốn ra khỏi cây của chúng tôi, và nó cho phép chúng tôi sử dụng một hoạt hình duy nhất mà chúng tôi có thể chia sẻ giữa tất cả các cây trong trải nghiệm.

Chúng tôi bắt đầu bằng cách tách vỏ một số cây từ Endorse Model Pack - Forest Assets.Bởi vì những cây này đã tồn tại, và trải nghiệm của chúng tôi diễn ra ở Vùng Bắc Tây Thái Bình Dương, nó đã tiết kiệm cho chúng tôi một chút thời gian sớm từ việc phải tạo mỗi mô hình cây.

Gói Rừng bao gồm nhiều loại cây, có thể tiết kiệm thời gian trong trải nghiệm của riêng bạn.

Sau khi chúng tôi chọn cây của mình, chúng tôi biết rằng chúng tôi cần phải bóc chúng. Skinning một mesh là hành động thêm khớp (hoặc xương) vào một mesh trong ứng dụng mô hình 3D khác, như Blender hoặc Maya, sau đó áp dụng ảnh hưởng đến các khớp/xương để di chuyển mesh.Điều này được sử dụng phổ biến nhất trong nhân vật hình người , nhưng với nhân vật tùy chỉnh , bạn có thể làm mờ được hầu hết mọi thứ.

Chúng tôi biết chúng tôi muốn tiết kiệm thời gian và tái sử dụng cùng một hoạt hiệu ứng động, vì vậy chúng tôi xây dựng giàn cây đầu tiên của mình và chắc chắn các tên liên kết là chung chung bởi vì chúng tôi muốn sử dụng các tên tương tự này trong các giàn cây khác.Chúng tôi cũng biết rằng chúng tôi cần bao gồm các khớp/xương chính, thứ cấp và thứ ba để các thân cây uốn theo gió, cành cây xoay và lá như thể chúng đang rung đáp ứng.Đối với quá trình này, chúng tôi cần tạo một chuyển động thứ cấp , đó là một khái niệm hoạt hình mà bất kỳ hành động nào gây ra sẽ khiến các phần khác của đối tượng phản ứng với hành động đó và xuất hiện để theo kịp chuyển động ban đầu.

Cây có các khớp chính, thứ cấp và thứ ba để chúng ta có thể có chuyển động tin cậy từ việc bị thổi bay bởi gió.

Khi chúng tôi đã tạo xong khớp/xương, đã đến lúc tạo một hoạt hình thử để di chuyển xung quanh tất cả các khớp và xương trong Studio để xem nó di chuyển theo cách chúng tôi muốn.Để làm điều này, chúng tôi phải nhập cây vào Studio thông qua cài đặt Rig tùy chỉnh trong Trình nhập khẩu 3D , sau đó di chuyển/hoạt hình khối bằng Trình chỉnh sửa hoạt hình .Chúng tôi thiết lập các vật liệu và kết cấu sau các bài kiểm tra này, nhưng bạn có thể xem kết quả dưới đây.

Cùng một cấu trúc bên trong Studio.

Sau khi chúng tôi hài lòng với kết quả trên cây đó, đã đến lúc kiểm tra cùng một hoạt hình trên một cây khác! Chúng tôi đã biết nó sẽ là hoạt hình giống nhau giữa các loại cây khác nhau, vì vậy chúng tôi chỉ chắc chắn rằng hoạt hình của chúng tôi trông giống như nó là đủ để hoạt động giữa một cây Redwood cao và một cây Beechwood chắc chắn!

Hoạt hình chúng tôi nhập vào cây Redwood.

Để làm điều này, chúng tôi lấy cây Beechwood từ Gói Rừng đó và xây dựng một cấu hình tương tự, sử dụng cùng tên chính xác cho các khớp.Điều này là để hoạt hình mà chúng tôi đã nhập trước đây có thể được áp dụng cho cây này cũng.Vì tất cả các hoạt hình đều dựa trên các khớp xoay, không quan trọng cây có lớn, nhỏ, cao hay rộng như thế nào!

Cây Beechwood có cùng tên chính xác cho các khớp của nó, chỉ không giống nhau về số lượng.Điều này không sao vì hệ thống hoạt hình chỉ áp dụng hoạt hình cho những khớp cụ thể phù hợp với tên trong nó! Vì lý do này, chúng tôi có thể áp dụng cùng một hoạt hình cho bất kỳ thứ gì phù hợp với tên khớp!

Sau khi chúng tôi thiết lập và làm mới cây Beechwood, chúng tôi có thể nhập nó và áp dụng hoạt hiệu ứng độngtương tự chính xác.Điều này có nghĩa là chỉ cần lặp lại và chỉnh sửa cần được thực hiện trên một tập tin, và nó cũng được lưu trên hiệu suất với ít hoạt hình hơn khi chạy trải nghiệm.

Sử dụng Trình biên tập hoạt hình, chúng tôi có thể áp dụng cùng một hoạt hình cây Redwood cho cây Beechwood!

Một khi chúng tôi có tất cả các loại cây mà chúng tôi muốn hoạt hình, chúng tôi đã biến tất cả thành gói để chúng tôi có thể tiếp tục chỉnh sửa và cập nhật trong khi chơi một số hoạt hình xung quanh khu vực chính của trải nghiệm.Vì chúng tôi biết rằng chúng có chi phí hiệu suất, chúng tôi sử dụng chúng một cách tiết kiệm xung quanh ngôi nhà nơi hiệu ứng có giá trị nhất! Trong tương lai khi điều này trở nên hiệu quả hơn, bạn sẽ có thể thêm ngày càng nhiều ví dụ mesh da!

Chúng tôi sử dụng cây hoạt hình ngay lập tức xung quanh nhà nơi vortex mạnh nhất và hiệu ứng hình ảnh sẽ là tác động lớn nhất đối với người chơi.

Làm vụn bão

Chúng tôi muốn mưa xuất hiện nặng nề, và để sương mù và chất thải thổi qua các cây.Để làm điều này, chúng tôi thiết lập một vài phần vô hình để hoạt động như khối lượng hạt với trẻ em phát xạ hạt ngay bên dưới những đám mây bão lớn.Vì giới hạn số lượng hạt trong Studio, chúng tôi không thể sử dụng một máy phát hạt cho toàn bộ không gian.Thay vào đó, chúng tôi đã thêm một vài cái có cùng kích cỡ nhau trong một mẫu lưới trên không gian chơi có thể, bởi sự có mặt của cây có nghĩa là người chơi sẽ không thể nhìn thấy rất xa.

Chúng tôi đã sử dụng nhiều tập lệnh để cả hai có được lượng mưa, và phạm vi mưa cụ thể mà chúng tôi muốn.

Các hạt mưa đã sử dụng một tính năng phát hạt mới ParticleEmitter.Squash cho phép bạn làm cho một hạt lâu hơn hoặc rải rác.Nó rất hữu ích cho mưa bởi vì nó có nghĩa là chúng tôi không cần một kết cấu mưa lớn, chỉ cần căng ra khỏi cái đã có.Chỉ cần biết rằng nếu bạn tăng giá trị của ParticleEmitter.Squash , bạn có thể cần phải tăng giá trị tổng thể ParticleEmitter.Size để nó không quá mỏng manh! Tổng thể, nó chỉ là vấn đề chơi xung quanh với các giá trị cho đến khi chúng tôi có đủ mưa, nhưng không quá nhiều để chặn tầm nhìn của trải nghiệm!

Giá trị Squash 3 bắt đầu kéo dài hơn kết cấu.
>

Giá trị Squash của 20 kéo dài các hạt lâu hơn, nhưng chúng tôi cũng cần tăng giá trị Kích thước nữa.
>

Đối với sương mù, sương mù và lá thổi qua, thật đơn giản hơn nhiều để thêm một phần lớn hơn duy nhất bao phủ ít khu vực hơn vì chúng tôi không cần một tấn hạt chạy cùng một lúc.Chúng tôi bắt đầu bằng cách thiết lập một khối lượng và có được tần suất của các hạt mà muốn chúng.

Cuối cùng có một vài khối lượng hạt nên chúng tôi đã không có hạt vào nhà, và vì chúng tôi không cảm thấy họ cần phải di chuyển qua các cây như sương mù đã làm.
>

Phần khối lượng hạt sương mù lớn hơn nhiều kể từ khi các hạt lớn, và chúng tôi không cần phải chính xác với vị trí.
>

Sau đó, chúng tôi tạo các bông lá thổi và kết cấu gió, và đặt các hạt cùng quay/di chuyển với tốc độ khác nhau và bắt đầu tại các tốc độ khác nhau.Điều này có nghĩa là các hạt sương lớn hơn sẽ tương tác tự nhiên hơn và không trông giống như một kết cấu lặp lại, đặc biệt là do kích thước của chúng.

Hạt sương mù
>

Hạt lá

Kết quả là một số hành động tuyệt vời giữa cây di chuyển, cửa sổ thổi, và sấm sét tạo ra hiệu ứng của cơn bão xung quanh mắt trung tâm của cơn bão.

Thiết lập con mắt của bão

Con mắt đá nứt với lõi phát sáng có nghĩa là cung cấp cho người chơi gợi ý đầu tiên rằng có điều gì đó bị lừa đảo và bí ẩn xảy ra tại ngôi nhà mà họ nên khám phá thêm.Vì cảnh của chúng tôi tối và mắt ở rất xa trên bầu trời, nên quan trọng để tạo một hình ảnh phá vỡ đá có thể tin cậy, nhưng không quan trọng để tạo chi tiết bề mặt đá có thể tin cậy vì người chơi sẽ không thể nhìn thấy được.Biết những gì là thực tế đối với người chơi để xem trong ánh sáng của cảnh của bạn trước khi bỏ ra rất nhiều thời gian vào chi tiết không cần thiết có thể tiết kiệm nhiều tài nguyên trong quá trình phát triển.

Thiết lập ánh sáng cuối cùng trong cảnh của bạn sớm có thể tiết kiệm rất nhiều công việc không cần thiết.Bạn sẽ không thể nhìn thấy chi tiết bề mặt trên các vòng với ánh sáng cuối cùng của cảnh của chúng tôi nên không cần phải dành thời gian để đặt chúng ở đó!

Khoảng cách từ người chơi cũng có nghĩa là chúng tôi có thể hoàn toàn dựa vào bản đồ bình thường cho chi tiết bề mặt của mắt để lưới chỉ là một cạnh tròn đơn giản! Chúng tôi đã chạm khắc chi tiết vào một lưới cao poly và nướng bản đồ bình thường của nó lên một lưới poly thấp hơn nhiều để chúng tôi có thể nhận được tất cả những chi tiết đẹp đẽ đó mà không có chi phí hiệu suất lớn!

Chạm cao cấp

Lưới poly thấp
>

Kết cấu lưới thấp với thông tin bình thường từ khối đúc cao poly được nướng trong
>

Để thêm một cảm giác siêu nhiên vào mắt và nhấn mạnh sự hiện diện của nó, chúng tôi quyết định tạo ra một dung nham phát sáng, neon để thấm qua các kẽ nứt của nó.Mặc dù không có kênh phát ra cho sự xuất hiện bề mặt, chúng tôi vượt qua chướng ngại vật này bằng cách tạo ra con mắt từ 2 quả cầu: một cho bề mặt đá sừng và một thứ thứ hai, nhỏ hơn một chút cho dung nham phát sáng.Trong Nghệ sĩ chất liệu, chúng tôi đã tạo một kết cấu màu cơ bản cho vùng tròn ngoài với độ trong suốt ở những khu vực mà chúng tôi muốn lõi bên trong đi qua.Trong Máy xay sinh tố, chúng tôi "vertex painted" các cạnh tròn bên trong theo cách rẻ và dễ dàng để có được một số biến thể màu trên nó.

Bức vẽ đỉnh trên bề mặt tròn bên trong.Chúng tôi đã tạo ra một độ dốc nhẹ xung quanh mắt để tạo ra cảm giác sâu hơn và sự quan tâm hình ảnh.

Một thử thách khác chúng tôi gặp phải khi tạo ra con mắt là do sự sử dụng của chúng tôi về phát trực tiếp kết hợp với khoảng cách của mắt từ người chơi.Vì sự trung tâm của cấu trúc này, chúng tôi muốn nó luôn luôn hiển thị bất chấp khoảng cách của nó nhưng, không có bất kỳ hack nào vào lưới của nó, người chơi không thể nhìn thấy mắt trừ khi họ ở trong solarium.Chúng tôi đã có thể buộc sự hiện diện liên tục của con mắt trong cảnh bằng cách thêm một số hình học vào con mắt và các vòng của nó.Geometría này nằm ngay dưới bề mặt của địa hình, và điều này là đủ để lừa đối động cơ nghĩ rằng cầu tròn ở gần người chơi hơn nó và luôn luôn phát trực tiếp nó vào.Tuy nhiên, việc này nên được thực hiện khá tiết kiệm vì việc buộc quá nhiều đối tượng lớn được phát trực tuyến có thể phủ nhận lợi ích của việc phát trực tuyến được bật và ảnh hưởng tiêu cực đến hiệu hiệu lựctrò chơi.

Chúng tôi đã có thể thêm chuyển động vào mắt và các vòng của nó nhờ vào cùng một kịch bản chúng tôi đã sử dụng để xoay các khối mây .Đối với một chạm cuối cùng, chúng tôi quyết định thêm một lời nhắc nhở về sự hiện diện của một thế giới khác ngoài các đám mây, nhưng chúng tôi phải có một tiếp cận sáng tạo để tránh thêm nhiều hình học vào cảnh và ngoài ra phải đối phó với những trở ngại đã được đề cập trước đó bởi việc bật phát trực tiếp được bật.Chúng tôi đã tạo ra một cảnh có rất nhiều chiều sâu do kích thước và khoảng cách tương đối của các đối tượng, hiển thị hình ảnh của cảnh này, sau đó sử dụng hình ảnh này như một nhãn dán trên một phần được đặt ngay sau mắt bão.Chúng tôi đã sử dụng cùng một phương pháp để xoay phần này như chúng tôi đã sử dụng cho mắt và các vòng của nó.

Hình ảnh chúng tôi từng sử dụng để tạo ra ảo giác về một thế giới vượt xa những đám mây.Khi người chơi ở xa một cái gì đó, một hình ảnh đơn giản có thể đủ để tạo ra ảo giác về sự sâu và phức tạp hơn trong cảnh của bạn!

Làm cho kho lưu trữ mở rộng

Một trong những thứ thú vị nhất để sản xuất là các không gian bị hỏng, nơi chúng tôi có thể lật đổ những mong đợi của người chơi về thực tại bằng cách thay đổi nó theo nghĩa đen xung quanh họ.Ví dụ, trong câu đố của cha, chúng tôi muốn làm lại một khoảnh khắc tương tự như một cơn ác mộng mà bất kể bạn chạy nhanh đến đâu, phòng vẫn cảm thấy như nó ngày càng dài hơn.Chúng tôi quyết định tạo một kho lưu trữ mở rộng mà sẽ trốn khỏi các người chơi khi họ đang tìm kiếm các nguyên liệu để biến phòng trở lại trạng thái bình thường.

Chúng tôi thiết lập điều này với một chuyển động đơn giản của các bức tường, và một bố trí thông minh của các phòng của chúng tôi sẽ xuất hiện ở cả hai bên của kho lưu trữ.Trong trạng thái bình thường của phòng, kho lưu trữ là một hành lang đơn giản, nhưng trong không gian bị hỏng, nó thực sự dài hơn với một vài cánh và một bức tường giả!

Tình trạng bị hỏng của kho bếp.
>

Bức tường giả di chuyển xa khỏi người chơi.
>

Tường giả là một nhóm mô hình mà chúng tôi sẽ quay lại lúc người chơi bước vào một âm lượng kích hoạt, đó là một phần trong suốt trước đó trong kho lưu trữ mà họ sẽ đi qua.Cái kích hoạt đó cũng được sử dụng trong một kịch bản tương tự như những kịch bản được sử dụng trên tất cả các cửa của chúng tôi, mà gọi TweenService để di chuyển từ một mục tiêu sang một mục tiêu khác.Chúng tôi đã sử dụng khối lượng phần để cho biết hoạt động tweening nơi vị trí bắt đầu và kết thúc là cho bức tường.

Phần tương tác kích hoạt một bức tường giả phía sau nó để di chuyển đến điểm cuối của nó.Nó được hiển thị rõ ràng trong hình ảnh này với một màu vàng nhạt.
Target_Closed là một phần mục tiêu chung chúng tôi sử dụng trên tất cả các cửa của chúng ta để chúng nên quay về đâu.Ở đây nó được tái sử dụng để cho bức tường hành lang biết nơi đi.

Bởi vì TweenService là một hệ thống chung như vậy, tất cả các mô hình dữ liệu tường của chúng tôi phải chứa cùng một thành phần.Ví dụ, một kịch bản chung "Door_Script" phát ra một âm thanh được xác định bởi một "giá trị" bên dưới mô hình "Grow_Wall".Cùng một kịch bản, với một số thay đổi trong ví dụ mã tiếp theo, cũng kích hoạt âm thanh cho việc di chuyển kho lưu.Điều này đã thêm rất nhiều cho sự di chuyển!


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, --Thời gian/Tốc độ của Cửa Tween
Enum.EasingStyle.Quart, --Kiểu dễ dàng
Enum.EasingDirection.InOut, --Hướng dễ dàng
0, --Lặp lại số lần
false, --Lập lại thật
0 --Trì hoãn
)
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
--mô hình ["Cửa"]:Chơi()
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
--in("chạm")
playersNear[player] = 1
if doorState == DoorState.Closed then
StartOpening()
end
end
end
end

Khi chúng tôi có bức tường giả di chuyển về phía sau của phòng, chúng tôi cần phần còn lại của nội dung di chuyển cùng với nó.Để làm điều đó, chúng tôi cần tất cả các vật phẩm lỏng trong kho lưu trữ được hàn vào tường khi nó di chuyển.Sử dụng Giới hạn hàn, chúng tôi nhanh chóng có thể hàn tất cả các đối tượng vào tường kho lưu để di chuyển như một đối tượng duy nhất.Làm như vậy có nghĩa là chúng tôi có lựa chọn để gỡ bỏ các mục này để người chơi có thể va chạm vào chúng và đập chúng xung quanh!

Làm cho ngôi nhà trên cây bị hỏng

Studio là một động cơ dựa trên vật lý tuyệt vời mà bạn có thể sử dụng để tạo mọi thứ từ một cổng lắc cho đến một nền tảng quay.Với bản trình diễn của chúng tôi, chúng tôi muốn sử dụng vật lý để tạo ra cảm giác thực tế trong một bộ môi trường không thực tế khác.Chỉ cần sử dụng một vài hạn chế , bạn có thể tạo một số khóa chướng ngại vui và thách thức trong trải nghiệm của riêng bạn!

Giới hạn là một nhóm các động cơ dựa trên vật lý mà xếp hạng các đối tượng và hạn chế hành vi.Ví dụ, bạn có thể sử dụng một giới hạn trục để kết nối với các đối tượng để giữ chúng cách nhau một khoảng cách cố định, hoặc giới hạn dây để có một ngọn đèn treo ở cuối dòng.Đối với câu đố của con trai mà người chơi được vận chuyển đến trạng thái bị hỏng của nghiên cứu, chúng tôi muốn lật thế giới theo nghĩa đen.Làm như vậy sẽ lật đổ những mong đợi của người chơi về thực tế và các quy tắc ở đó, trong khi vẫn sử dụng hệ thống vật lý như dự định!

Câu đố của con trai bắt đầu với người chơi trong cùng một phòng, nhưng mọi thứ đều lệch sang một bên.

Một khi người chơi làm việc xuống khu vực chính của câu đố, họ được chào đón với một cảnh quen thuộc trên Roblox: một khóa chướng.Khóa chướng ngại vật đặc biệt này bao gồm một số nền tảng quay và tường quay, cùng với "khu vực an toàn" mà tiến trình câu chuyện tiến triển.Chúng tôi sẽ tập trung vào các yếu tố quay/xoay.

Sự xuất hiện khiến tâm trí che giấu thực tế là gameplay ở đây rất đơn giản.

Tại sao chúng tôi sử dụng hạn chế ở đây? Bởi vì TweenService hoặc các phương pháp khác sẽ không di chuyển người chơi trong khi họ đứng trên chúng.Không có vật di chuyển người chơi, ai đó có thể nhảy lên một nền tảng và nó sẽ quay ra khỏi dưới chân họ.Thay vào đó, chúng tôi muốn người chơi di chuyển qua một nền tảng xoay tròn trong khi cố gắng thực hiện nhảy của họ lên nền tảng tiếp theo.Vì cách tiếp cận này, người chơi cảm thấy có nguồn gốc nơi họ đứng khi đưa ra quyết định với cách tiến hành thông qua khóa học, và chúng tôi không cần phải làm bất cứ điều gì đặc biệt để đảm bảo họ di chuyển với một bề mặt xoay!

Bạn có thể xem bạn bè của bạn quay vòng trong khi cố gắng điều hướng khóa học chướng ngại vật cũng.

Để làm điều này, chúng tôi cần phải sử dụng tài sản từ bộ dụng cụ hiện tại của chúng tôi và thêm bất kỳ nội dung mới nào cho một hiệu ứng hình ảnh.Chúng tôi đã tạo một vài bức tường và nền tảng không hoàn chỉnh với các lỗ trong đó để kể câu chuyện về bà ngoại xây nhà trên cây.Bởi vì chúng tôi không muốn tạo một loạt các nền tảng duy nhất, chúng tôi đã tạo 4 mảnh cơ sở và mảnh lan can riêng biệt.Điều này cho phép chúng tôi trộn và kết hợp các mảnh cơ sở và lan can riêng lẻ để có nhiều sự đa dạng.

Chúng tôi biết rằng vì chúng tôi đang sử dụng các hạn chế, chúng tôi sẽ không thể neo các khối lượng này vì chúng sẽ không di chuyển ngay cả khi có sự hiện diện của một hạn chế/động cơ lái chúng.Yêu cầu giới hạn cần phải là con của một thứ gì đó được neo để nền tảng không chỉ rơi ra khỏi thế giới.Chúng tôi giải quyết vấn đề này thông qua một phần mà chúng tôi đặt tên là Motor_Anchorhạn chế khớp để lái toàn bộ chuyển động của nền tảng.Sau đó, chúng tôi cần hai lưới di chuyển như một, vì vậy chúng tôi tạo một phần chúng tôi gọi là Motor_Turn , sau đó chúng tôi hàn hai lưới vào nó.Theo cách này, giới hạn sẽ có thể hoạt động trên một phần duy nhất, so với nhiều khớp làm việc với nhiều phần.

Bây giờ đã đến lúc thiết lập hành vi thực sự của hạn chế khớp, và thêm các phụ kiện sẽ hoạt động như hướng của phần và hạn chế cùng nhau.Chúng tôi đặt phụ kiện quay vào Motor_Turn, mà các khối đi bộ được hàn vào, và một phụ kiện khác cho hành vi neo trên Motor_Anchor chính, bên cạnh hạn chế khớp.Vì điều này cần phải xoay trên sở hữunó, thay vì bị ảnh hưởng bởi người chơi (như một bản lề cửa), chúng tôi đặt HingeConstraint.ActuatorType để Động cơ , xử lý hạn chế như một động cơ tự di chuyển.

Để giữ cho các nền tảng quay với tốc độ không thay đổi, chúng tôi sau đó thiết lập các thuộc tính HingeConstraint.AngularVelocity , HingeConstraint.MotorMaxAccelerationHingeConstraint.MotorMaxTorque ở mức giá trị cho phép di chuyển và ngăn chặn sự gián đoạn nếu một người chơi nhảy vào nó.

Phụ lục 0 là về cơ bản là neo cho khớp và Phụ lục 1 đại diện cho khớp chính.Chúng tôi đã có khớp xoay liên tục, nhưng bạn cũng có thể sử dụng hạn chế khớp cho cửa.

Bây giờ chúng tôi cần phải làm các bức tường quay.Các bức tường cần quay trên trung tâm rõ ràng của chúng, và chúng tôi biết chúng tôi muốn chúng có thể xử lý bất kỳ hướng nào so với phần còn lại của cấp độ.Giống như các nền tảng, chúng tôi xây dựng chúng để tất cả các bức tường không neo và được hàn vào Motor_Turn.

Chúng tôi muốn tái sử dụng càng nhiều khối lượng lưới nhà trên cây thực tế để tiết kiệm hiệu hiệu lực, vì vậy chúng tôi đã theo một con đường tương tự như các nền tảng.Nhiều loại tường đã được tạo ra có thể dính chặt với nhau theo những kết hợp khác nhau cho một số biến thể.

Chúng tôi đã sử dụng Texture đối tượng trên cùng của SurfaceAppearance đối tượng để thêm một số biến thể cho các vật liệu cơ bản của chúng tôi.Kết cấu , tương tự như Decal, cho phép bạn đặt một hình ảnh trên một máy bay của một lưới.Điều này có thể hữu ích nếu bạn muốn thêm bụi vào tường gạch, hoặc làm cho gỗ trông cũ kỹ khi sử dụng cùng một loại vật liệu gỗ cơ bản. Texture các đối tượng có hành vi khác nhau một chút so với Decal các đối tượng trong đó bạn có thể chia nhỏ và xóa hình ảnh theo cách bạn muốn, rất hữu ích nếu bạn muốn có thể thay đổi kích thước kết cấu overlay của bạn và không quan tâm nó lặp lại!

Bạn có thể xem cả hành vi tương tự và thiết lập cho hạn chế khớp, cũng như cách chúng tôi sử dụng Texture đối tượng.

Một khi chúng tôi đã kiểm tra một vài nền tảng và tường xoay, chúng tôi đã thực hiện một số biến thể và chơi với vị trí của chúng để đảm bảo khóa chướng ngại vật là thách thức, khiến tâm trí, và cũng rõ ràng nơi người chơi cần đi! Phải mất một số điều chỉnh cho cả giá trị và vị trí của chúng để chúng chạy tốt.Chúng tôi đã có một số điểm mà các nền tảng và bức tường đang đánh vào nhau hoặc môi trường xung quanh, nhưng với một số di chuyển xung quanh và kiểm tra thường xuyên, chúng tôi đã có thể hạ cánh vào các cài đặt mà chúng tôi có trong demo!

Nếu bạn không chắc chắn về các đối tượng vật lý mà bạn đang tấn công, bạn có thể bật chính xác va chạm từ widget Tùy chọn hiển thị ở góc trên bên phải của cửa sổ 3D.

A close up view of the 3D viewport with the Visualization Options button indicated in the upper-right corner.

Khi hiển thị hình ảnh va chạm bị vô hiệu hóa, bạn có thể xem bản đại diện hình học bình thường hiển thị trong trò chơi.
>

Khi hiển thị va chạm được bật, bạn có thể thấy lá cây không có va chạm, vì vậy chúng sẽ không làm gián đoạn các bệ xoay hoặc tường.
>

Như bạn có thể thấy dưới đây, các lỗ cửa/cửa sổ có thể nhìn thấy, nhưng các chi tiết nhỏ hơn như sub-paneling không.Điều này là do thuộc tính CollisionFidelity của tường được đặt thành Hộp .Chúng tôi không cần độ chính xác cho các tấm này, vì vậy để tiết kiệm chi phí hiệu suất, điều này đã chi tiết đủ để người chơi nhảy vào.Với các nền tảng và bức tường quay xong, chúng tôi chỉ cần thêm các tài sản chi tiết như hộp và đèn, sau đó nó đã sẵn sàng để chơi!