Roblox模型克隆后内部Teleport Script无法运行求助
Roblox克隆SpawnDoor模型后内部Teleport脚本无法运行问题
模型层级
SpawnDoor (Model) ├─Door (Sound) ├─Light (Folder) │ ├─Door1 (Part) │ ├─Door2 (Part) │ ├─Part (Part) │ └─SurfaceLight (SurfaceLight) ├─**Teleport (Script)** -- 模型生成后无法工作的脚本 └─Wood (Folder) ├─Door1 (Model) │ └─Union └─Door2 (Model) └─Union
生成模型的客户端代码
local TweenService = game:GetService("TweenService") local ReplicatedStorage = game:GetService("ReplicatedStorage") local CameraShaker = require(ReplicatedStorage:WaitForChild("CameraShaker")) local player = game.Players.LocalPlayer local playerGui = player.PlayerGui.Red.Red local Camera = game.Workspace.CurrentCamera local cooldown = false -- Cooldown flag local cooldownTime = 2 -- Cooldown time in seconds local function ShakeCamera(shakCf) Camera.CFrame = Camera.CFrame * shakCf end local renderPriority = Enum.RenderPriority.Camera.Value + 1 local camShake = CameraShaker.new(renderPriority, ShakeCamera) camShake:Start() -- Function to handle J key press local function onKeyPress(input) if input.KeyCode == Enum.KeyCode.J then if cooldown then print("Tool is on cooldown") -- Shake camera and show GUI camShake:ShakeOnce(60, 80, 1, 1) -- Adjust parameters as needed local transparencyTweenInfo = TweenInfo.new(1, Enum.EasingStyle.Linear, Enum.EasingDirection.InOut, 0, false, 0) local tween1 = TweenService:Create(playerGui, transparencyTweenInfo, { BackgroundTransparency = 0.3 }) local tween2 = TweenService:Create(playerGui, transparencyTweenInfo, { BackgroundTransparency = 1 }) tween1:Play() tween1.Completed:Connect(function() tween2:Play() end) return end cooldown = true -- Activate cooldown print("Tool Activated") -- Check if this prints when you use the tool game.SoundService.Biwa:Play() local Player = game.Players.LocalPlayer local Char = Player.Character if not Char then print("Character not found") cooldown = false -- Reset cooldown if an error occurs return end local HRP = Char:FindFirstChild("HumanoidRootPart") if not HRP then print("HumanoidRootPart not found") cooldown = false -- Reset cooldown if an error occurs return end local DoorModel = game.ReplicatedStorage.SpawnDoor if not DoorModel or not DoorModel:IsA("Model") then print("SpawnDoor Model not found in ReplicatedStorage or not a Model") cooldown = false -- Reset cooldown if an error occurs return end -- Raycast to find the ground below the player local rayOrigin = HRP.Position local rayDirection = Vector3.new(0, -100, 0) -- Cast downwards local raycastParams = RaycastParams.new() raycastParams.FilterDescendantsInstances = {Char} raycastParams.FilterType = Enum.RaycastFilterType.Blacklist local raycastResult = workspace:Raycast(rayOrigin, rayDirection, raycastParams) if not raycastResult then print("No ground detected below the player") cooldown = false -- Reset cooldown if an error occurs return end local groundPosition = raycastResult.Position local door = DoorModel:Clone() door.Parent = workspace -- Set the PrimaryPart of the door model door.PrimaryPart = door:FindFirstChild("Light").Part if not door.PrimaryPart then print("PrimaryPart not found in DoorModel") door:Destroy() cooldown = false -- Reset cooldown if an error occurs return end -- Set the position of the door model to the ground position door:SetPrimaryPartCFrame(CFrame.new(groundPosition)) print("Door spawned at:", door.PrimaryPart.Position) -- Delay before sliding doors open wait(2) -- Animation to slide open doors local door1 = door.Wood.Door1 local door2 = door.Wood.Door2 if door1 and door2 then if door1.Union and door2.Union then -- Tween for Door1 local door1OpenCFrame = door1.Union.CFrame * CFrame.new(0, 0, -5) -- Example: Move 5 studs to the right local door1Tween = TweenService:Create(door1.Union, TweenInfo.new(0.2), {CFrame = door1OpenCFrame}) -- Tween for Door2 local door2OpenCFrame = door2.Union.CFrame * CFrame.new(0, 0, 5) -- Example: Move 5 studs to the left local door2Tween = TweenService:Create(door2.Union, TweenInfo.new(0.2), {CFrame = door2OpenCFrame}) door1Tween:Play() door2Tween:Play() game.SoundService.Door:Play() else print("Primary part not found in one of the doors") end else print("One of the doors not found in DoorModel") end print("Doors sliding open") task.wait(1) -- Destroy the door model after a delay repeat door.Wood.Door1.Union.Transparency += 0.01 door.Wood.Door2.Union.Transparency += 0.01 door.Light.Part.Transparency += 0.01 door.Light.Door1.Transparency += 0.01 door.Light.Door2.Transparency += 0.01 task.wait(0.01) until door.Wood.Door1.Union.Transparency >= 1 door:Destroy() print("Door destroyed after 3 seconds") -- Start cooldown timer task.delay(cooldownTime, function() cooldown = false print("Cooldown ended") end) end end -- Connect the function to the key press event game:GetService("UserInputService").InputBegan:Connect(onKeyPress)
已尝试的解决方法
- 从Workspace克隆模型
- 用持续运行的服务器脚本检测模型生成后执行操作
- 将Teleport脚本替换为简单的打印脚本,均无效
问题根源与解决方案
问题核心
当前生成模型的代码是客户端LocalScript,克隆的模型直接放入Workspace:
Teleport (Script)是服务器脚本,Roblox安全机制禁止客户端运行服务器脚本,因此脚本不会执行。- 客户端创建的模型在FilteringEnabled开启(默认开启)的情况下,服务器无法直接检测到,导致服务器监听脚本无法触发。
方案一:通过RemoteEvent让服务器克隆模型(推荐)
这是符合Roblox安全规范的做法,所有涉及对象创建的敏感操作由服务器处理。
- 在
ReplicatedStorage中创建RemoteEvent,命名为SpawnDoorEvent。 - 修改客户端代码,将克隆逻辑替换为触发RemoteEvent:
-- 客户端代码中,找到groundPosition后替换克隆代码: local ReplicatedStorage = game:GetService("ReplicatedStorage") local SpawnDoorEvent = ReplicatedStorage:WaitForChild("SpawnDoorEvent") SpawnDoorEvent:FireServer(groundPosition) -- 保留客户端的冷却、相机震动、GUI效果逻辑,移除原有的克隆、动画、销毁代码
- 在
ServerScriptService中创建服务器脚本,处理模型生成:
local ReplicatedStorage = game:GetService("ReplicatedStorage") local Workspace = game:GetService("Workspace") local TweenService = game:GetService("TweenService") local SpawnDoorEvent = ReplicatedStorage:WaitForChild("SpawnDoorEvent") SpawnDoorEvent.OnServerEvent:Connect(function(player, groundPosition) -- 服务器验证玩家状态(可选,防止滥用) local char = player.Character if not char or not char:FindFirstChild("HumanoidRootPart") then return end -- 克隆模型到Workspace local DoorModel = ReplicatedStorage:WaitForChild("SpawnDoor") local door = DoorModel:Clone() door.Parent = Workspace -- 设置模型位置 door.PrimaryPart = door.Light.Part door:SetPrimaryPartCFrame(CFrame.new(groundPosition)) -- 开门动画 task.wait(2) local door1 = door.Wood.Door1 local door2 = door.Wood.Door2 if door1 and door2 and door1.Union and door2.Union then local door1OpenCFrame = door1.Union.CFrame * CFrame.new(0, 0, -5) local door1Tween = TweenService:Create(door1.Union, TweenInfo.new(0.2), {CFrame = door1OpenCFrame}) local door2OpenCFrame = door2.Union.CFrame * CFrame.new(0, 0, 5) local door2Tween = TweenService:Create(door2.Union, TweenInfo.new(0.2), {CFrame = door2OpenCFrame}) door1Tween:Play() door2Tween:Play() game.SoundService.Door:Play() end -- 销毁模型 task.wait(1) repeat door.Wood.Door1.Union.Transparency += 0.01 door.Wood.Door2.Union.Transparency += 0.01 door.Light.Part.Transparency += 0.01 door.Light.Door1.Transparency += 0.01 door.Light.Door2.Transparency += 0.01 task.wait(0.01) until door.Wood.Door1.Union.Transparency >= 1 door:Destroy() end)
此时模型由服务器生成,内部的Teleport (Script)服务器脚本会正常执行。
方案二:将Teleport脚本改为LocalScript(仅限非敏感逻辑)
如果Teleport逻辑不需要服务器验证(比如仅本地视觉效果或客户端可控的传送),可以将Teleport (Script)改为LocalScript,客户端克隆模型后LocalScript会自动运行。
注意:涉及玩家位置修改、物品生成等敏感操作,必须使用服务器脚本,避免作弊风险。
额外排查点
- 检查模型销毁时间:当前模型在生成后约3秒销毁,确保Teleport脚本在销毁前有足够时间完成逻辑。
- 查看Roblox Studio输出窗口,确认是否有脚本错误提示。
- 验证FilteringEnabled状态:开启状态下客户端创建的对象服务器不可见,必须通过服务器生成模型才能让服务器脚本检测到。
内容的提问来源于stack exchange,提问作者Sergei Ivlev
相关产品推荐
相关产品推荐

