Đã đến lúc mang tất cả công việc này lại với nhau! Bây giờ bạn đã tạo ra các thành phần chùm và hạt, bạn sẽ thêm vào ba kịch bản được tạo sẵn.Các kịch bản này quản lý hướng dẫn bằng cách cho thành phần biết khi nào nên làm gì.Ví dụ, các kịch bản sẽ tạo chùm tia cho người chơi mới và phát ra các hạt mỗi khi họ tương tác với mục tiêu.
Lưu trữ chùm và hạt
Trước khi thêm các kịch bản, chùm và hạt cần được di chuyển đến nơi các kịch bản có thể tạo bản sao của chúng theo yêu cầu.
Trong ReplicatedStorage , tạo một thư mục mới có tên là PlayerTutorial . Di chuyển TutorialBeam ra khỏi TestPlayer, và vào thư mục mới.
Trong ServerStorage , tạo một thư mục có tên là TutorialParticles .Di chuyển hạt Nổ ra khỏi TestPlayer vào thư mục đó.
Khi chùm và hạt phát xạ được di chuyển, bạn không còn cần đến TestPlayer. Xóa TestPlayer kể từ khi kịch bản sẽ hoạt động với người chơi thực khi hoàn thành.
Tạo sự kiện
Mỗi khi người chơi tương tác với một mục tiêu, kịch bản hướng dẫn sẽ cần phải biết để có thể cập nhật tiến trình của người chơi đó và phát ra hiệu ứng hạt.Để thông báo các kịch bản, tín hiệu có thể được gửi bằng cách sử dụng sự kiện .
Trong ReplicatedStorage > PlayerTutorial, tạo hai đối tượng Sự kiện từ xa . Hãy đặt tên cho chúng là NextGoal và TutorialEnd .
Thêm các kịch bản
Các kịch bản ba bên dưới sẽ tìm kiếm các hạt phát và vật thể chùm được tạo trước đó và quản lý hệ thống hướng dẫn.
Trong ReplicatedStorage > PlayerTutorial > tạo một mới ModuleScript có tên TutorialManager .
Thay thế mã mặc định bằng cách sao chép và dán toàn bộ mã bên dưới.
local TutorialManager = {}local ReplicatedStorage = game:GetService("ReplicatedStorage")local tutorialFolder = ReplicatedStorage:WaitForChild("PlayerTutorial")local TutorialEndEvent = tutorialFolder:WaitForChild("TutorialEnd")local NextGoalEvent = tutorialFolder:WaitForChild("NextGoal")-- Các phần mục tiêu phải được đặt hàng trong bảng, nếu không thì lệnh mục tiêu có thể khác nhau trong trò chơilocal goalParts = {workspace.TutorialGoals.GoalPart1,workspace.TutorialGoals.GoalPart2}local function checkTutorialEnd(player, goalParts)local currentIndex = player:WaitForChild("GoalProgress")return currentIndex.Value >= #goalPartsendlocal function finishTutorial(player)local playerBeam = player.Character.HumanoidRootPart:FindFirstChildOfClass("Beam")playerBeam:Destroy()print(player.Name .. " finished the tutorial")-- Chỗ trống cho mã tiếp theo. Ví dụ: nếu bạn muốn gửi tin nhắn đến máy chủ để thực hiện các nhiệm vụ khácendfunction TutorialManager.interactGoal(player)NextGoalEvent:FireServer()endfunction TutorialManager.getTutorialGoals()return goalPartsendfunction TutorialManager.nextGoal(player, goalParts)if checkTutorialEnd(player, goalParts) thenfinishTutorial(player)else-- Tăng trình theo dõi mục tiêu của người chơilocal currentGoalIndex = player:WaitForChild("GoalProgress")currentGoalIndex.Value += 1endend-- Tạo một giá trị int để theo dõi tiến trình của người chơi thông qua các mục tiêu hướng dẫnfunction TutorialManager.setupPlayerProgress(player)local currentGoalProgress = Instance.new("IntValue")currentGoalProgress.Name = "GoalProgress"currentGoalProgress.Value = 1currentGoalProgress.Parent = playerendreturn TutorialManagerTập lệnh này chạy mã để quản lý tiến trình của người chơi trong hướng dẫn.Điều này bao gồm các nhiệm vụ như chạy mã để tương tác với mục tiêu, hoặc xảy ra điều gì khi hướng dẫn kết thúc.
Trong ServerScriptService , tạo một Tập lệnh mới có tên TutorialParticles .
Sao chép mã bên dưới.
local Players = game:GetService("Players")local ReplicatedStorage = game:GetService("ReplicatedStorage")local ServerStorage = game:GetService("ServerStorage")local tutorialFolder = ReplicatedStorage:WaitForChild("PlayerTutorial")local NextGoalEvent = tutorialFolder:WaitForChild("NextGoal")local EMIT_RATE = 50local function playParticleBurst(player)local character = player.Character or player.CharacterAdded:Wait()local humanoidRootPart = character:WaitForChild("HumanoidRootPart")local particleAttachment = humanoidRootPart:WaitForChild("ParticleAttachment")-- Đi qua các hạt trên phụ lục và chơi chúng theo loại hạtfor _, particle in particleAttachment:GetChildren() doif particle:IsA("ParticleEmitter") thenparticle:Emit(EMIT_RATE)endendendlocal function setupPlayerParticles(player)player.CharacterAdded:Connect(function(character)local humanoidRootPart = character:WaitForChild("HumanoidRootPart")local playerParticleAttachment = Instance.new("Attachment")playerParticleAttachment.Name = "ParticleAttachment"playerParticleAttachment.Parent = humanoidRootPart-- Nhân bản các hạt trong thư mục, ngay cả khi có nhiều hơn một và gắn vào người chơifor _, emitter in ServerStorage.TutorialParticles:GetChildren() doemitter:Clone().Parent = playerParticleAttachmentendend)endPlayers.PlayerAdded:Connect(setupPlayerParticles)NextGoalEvent.OnServerEvent:Connect(playParticleBurst)Tập lệnh này phát các hạt nổ mỗi khi người chơi tương tác với các mục tiêu.Cũng có một biến có tên là EMIT_RATE để xác định số lượng hạt xuất hiện trong quá trình tương tác.
Trong StarterPlayer > StarterPlayerScripts, tạo một LocalScript mới có tên là TutorialScript .
Sau đó, dán mã bên dưới. Các mã này tạo và quản lý chùm tia được sử dụng để hướng dẫn người chơi.
local Players = game:GetService("Players")local ReplicatedStorage = game:GetService("ReplicatedStorage")local tutorialFolder = ReplicatedStorage:WaitForChild("PlayerTutorial")local TutorialManager = require(tutorialFolder:WaitForChild("TutorialManager"))local TutorialEndEvent = tutorialFolder:WaitForChild("TutorialEnd")local player = Players.LocalPlayerlocal goalParts = TutorialManager.getTutorialGoals()local playerBeam = nillocal goalIndex = nillocal function getTargetAttachment()local currentTarget = goalParts[goalIndex.Value]local interactionPart = currentTarget:FindFirstChild("InteractionPart")local attachment = interactionPart and interactionPart:FindFirstChildOfClass("Attachment")if not attachment thenattachment = Instance.new("Attachment")attachment.Name = "BeamAttachment"attachment.Parent = currentTargetendreturn attachmentendlocal function updateBeamTarget()playerBeam = player.Character.HumanoidRootPart:FindFirstChildOfClass("Beam")local targetBeamAttachment = getTargetAttachment()if targetBeamAttachment thenplayerBeam.Attachment1 = targetBeamAttachmentelsewarn("Attachment not found in a goal. Check that goals have attachments or they're included under the InteractionPart")endendlocal function setupGoals()for _, part in goalParts dolocal interactionPart = part:FindFirstChild("InteractionPart")local proximityPrompt = interactionPart and interactionPart:FindFirstChild("ProximityPrompt")if proximityPrompt thenproximityPrompt.Triggered:Connect(function(player)proximityPrompt.Enabled = falseTutorialManager.nextGoal(player, goalParts)TutorialManager.interactGoal(player)end)elsewarn("Proximity prompt not included in goal. Add one to each goal part under the InteractionPart")endendendlocal function createBeamForCharacter(character)local humanoidRootPart = character:WaitForChild("HumanoidRootPart")local playerBeamAttachment = Instance.new("Attachment")local beamTemplate = tutorialFolder:WaitForChild("TutorialBeam")if not beamTemplate thenwarn("Tutorial Beam not found in ReplicatedStorage")endplayerBeamAttachment.Name = "BeamAttachment"playerBeamAttachment.Parent = humanoidRootPartlocal targetBeamAttachment = getTargetAttachment()playerBeam = beamTemplate:Clone()playerBeam.Attachment0 = playerBeamAttachmentplayerBeam.Attachment1 = targetBeamAttachmentplayerBeam.Enabled = trueplayerBeam.Parent = humanoidRootPartendlocal function setupPlayer()setupGoals()TutorialManager.setupPlayerProgress(player)goalIndex = player:WaitForChild("GoalProgress")player.CharacterAdded:Connect(createBeamForCharacter)if player.Character thencreateBeamForCharacter(player.Character)endendsetupPlayer()goalIndex.Changed:Connect(updateBeamTarget)Chơi dự án để kiểm tra các kịch bản. Di chuyển từ gian hàng này sang gian hàng khác, sử dụng tính năng tương tác để xem liệu mã có hoạt động không.
Mẹo khắc phục sự cố
Vấn đề : Hạt chơi khi trò chơi bắt đầu.
Vào ServerStorage > Hạt hướng dẫn > Nổ. Kiểm tra Tắt để tắt. Vấn đề : Cảnh báo trong biên dịch viên như "sản lượng vô hạn".
Bởi vì kịch bản đang tìm kiếm các đối tượng cụ thể ở một số vị trí nhất định, có thể một phần được đặt tên sai.Kiểm tra lại xem tên và vị trí của mỗi phần trong trò chơi phù hợp với hướng dẫn.
Lợi ích và giới hạn của kịch bản
Nếu bạn đang sử dụng hệ thống hướng dẫn này trong trải nghiệm của mình, hãy nhớ những điều theo dõi: Lợi ích
- Các sự kiện như TutorialEnd có thể được sử dụng để kích hoạt các kịch bản khác. Ví ví dụ / trường hợp, bạn có thể trao cho người chơi một vật phẩm đặc biệt khi sự kiện này xảy ra.
- Tập lệnh TutorialParticles có thể chơi nhiều hạt cùng một lúc.Bạn có thể thêm nhiều hạt cảnh trong ServerStorage/TutorialParticles để có được các hiệu ứng phức tạp hơn. Giới hạn
- Tiến trình của người chơi trong hướng dẫn không bền vững, có nghĩa là bạn sẽ phải viết mã một cách lưu trữ tiến trình đó.Đối với hướng dẫn, xem bài viết: Lưu dữ liệu.