You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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:

  1. Teleport (Script)是服务器脚本,Roblox安全机制禁止客户端运行服务器脚本,因此脚本不会执行。
  2. 客户端创建的模型在FilteringEnabled开启(默认开启)的情况下,服务器无法直接检测到,导致服务器监听脚本无法触发。

方案一:通过RemoteEvent让服务器克隆模型(推荐)

这是符合Roblox安全规范的做法,所有涉及对象创建的敏感操作由服务器处理。

  1. 在ReplicatedStorage中创建RemoteEvent,命名为SpawnDoorEvent。
  2. 修改客户端代码,将克隆逻辑替换为触发RemoteEvent:
-- 客户端代码中,找到groundPosition后替换克隆代码:
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local SpawnDoorEvent = ReplicatedStorage:WaitForChild("SpawnDoorEvent")

SpawnDoorEvent:FireServer(groundPosition)

-- 保留客户端的冷却、相机震动、GUI效果逻辑,移除原有的克隆、动画、销毁代码
  1. 在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会自动运行。

注意:涉及玩家位置修改、物品生成等敏感操作,必须使用服务器脚本,避免作弊风险。

额外排查点

  1. 检查模型销毁时间:当前模型在生成后约3秒销毁,确保Teleport脚本在销毁前有足够时间完成逻辑。
  2. 查看Roblox Studio输出窗口,确认是否有脚本错误提示。
  3. 验证FilteringEnabled状态:开启状态下客户端创建的对象服务器不可见,必须通过服务器生成模型才能让服务器脚本检测到。

内容的提问来源于stack exchange,提问作者Sergei Ivlev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 18:42:03