How do I clone a model to workspace on player click from a server script

title probably makes no sense so explaination:
I want to spawn a model “trip” from replicated storage to the players position. I found a way to get this to work through a local script (with help from roblox assistant) but the scripts inside the model wouldnt work. I know it has to be a server script to clone it and make the scripts work but i have no idea how to get a players mouse click on a server script. I’ve seen other ways that include a remote event but i can’t get the models vector3 from it because the players head (it’ll make sense if u read the script). this is what the assistance gave me:

(local script)

local Players = game:GetService("Players")
local UserInputService = game:GetService("UserInputService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

-- Assuming the model to spawn is stored in ReplicatedStorage
-- Make sure to replace 'ModelName' with the actual name of your model
local modelToSpawn = ReplicatedStorage:FindFirstChild("Trip")

-- Function to spawn the model above the player's head
local function spawnModelAbovePlayer(player)
    if not modelToSpawn then
        warn("Model to spawn not found in ReplicatedStorage.")
        return
	end
	if player.Team == game.Teams.Out then return end
	if player.team == game.Teams.Runner then return end

    local character = player.Character or player.CharacterAdded:Wait()
    local head = character:FindFirstChild("Head")
    if not head then
        warn("Player's head not found.")
        return
    end

    -- Clone the model to spawn
    local modelClone = modelToSpawn:Clone()

    -- Calculate the position above the player's head
    local spawnPosition = head.Position + Vector3.new(3, head.Size.Y + modelClone:GetExtentsSize().Y / 2, 0)

    -- Set the model's position and parent it to the workspace
    modelClone:PivotTo(CFrame.new(spawnPosition))
	modelClone.Parent = workspace
	wait(1)
	modelClone:WaitForChild("Rope").Script.Enabled = true
	modelClone:WaitForChild("Script").Enabled = true
	end


-- Function to handle mouse button 1 click
local function onMouseButton1Click()
    local player = Players.LocalPlayer
    spawnModelAbovePlayer(player)
end

-- Connect the mouse button 1 click event
UserInputService.InputBegan:Connect(function(input, gameProcessedEvent)
    if gameProcessedEvent then return end
    if input.UserInputType == Enum.UserInputType.MouseButton1 then
        onMouseButton1Click()
    end
end)

1 Like

To make an action happen on the server when a player clicks a GUI button, you’ll need to use a RemoteEvent.

its not a gui button tho, its just whenever the player click left mouse button at anytime

The solution for this is the same, just create a remote event inside of ReplicatedStorage and use the FireServer method inside of the LocalScript when the player clicks on the screen. In a server script, use the OnServerEvent event to listen for client requests. The documentation I linked in my first reply covers all that.

What you’re trying to do is communicate from client to server. You mentionned using RemotEvents which is exactly what we are looking for! Basically, you need to fire a remote from the localscript to the server. Then, in the server you can use OnServerEvent to receive the RemoteEvent. Don’t forget; when doing RemoteEvent.OnServerEvent:Connect(function(PLAYER) the player that clicked is passed as an argument. So we can use that PlayerInstance to spawn the model above the player’s head. A lot of yapping so let’s put this into code.

First we need a RemoteEvent. Add a RemoteEvent inside of the ReplicatedStorage and name it whatever you want (I would name it SpawnModelRemote). Now we’re reading to code!

IN THE LOCAL SCRIPT:

local Players = game:GetService("Players")
local UserInputService = game:GetService("UserInputService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local remote = ReplicatedStorage:FindFirstChild("SpawnModelRemote") -- your remote (change the name to what you named the remote)

-- Function to handle mouse button 1 click
local function onMouseButton1Click()
    remote:FireServer() -- firing the remote to the server
end

-- Connect the mouse button 1 click event
UserInputService.InputBegan:Connect(function(input, gameProcessedEvent)
    if gameProcessedEvent then return end
    if input.UserInputType == Enum.UserInputType.MouseButton1 then
        onMouseButton1Click()
    end
end)

Now we need a serverscript. Add a Script inside of the ServerScriptService. You can name it whatever you want, it doesn’t matter :wink:

IN THE SERVERSCRIPT:

local ReplicatedStorage = game:GetService("ReplicatedStorage")

local remote = ReplicatedStorage:FindFirstChild("SpawnModelRemote")

-- Assuming the model to spawn is stored in ReplicatedStorage
-- Make sure to replace 'ModelName' with the actual name of your model
local modelToSpawn = ReplicatedStorage:FindFirstChild("Trip")
-- Function to spawn the model above the player's head

local function spawnModelAbovePlayer(player)
    if not modelToSpawn then
        warn("Model to spawn not found in ReplicatedStorage.")
        return
	end
	if player.Team == game.Teams.Out then return end
	if player.team == game.Teams.Runner then return end

    local character = player.Character or player.CharacterAdded:Wait()
    local head = character:FindFirstChild("Head")
    if not head then
        warn("Player's head not found.")
        return
    end

    -- Clone the model to spawn
    local modelClone = modelToSpawn:Clone()

    -- Calculate the position above the player's head
    local spawnPosition = head.Position + Vector3.new(3, head.Size.Y + modelClone:GetExtentsSize().Y / 2, 0)

    -- Set the model's position and parent it to the workspace
    modelClone:PivotTo(CFrame.new(spawnPosition))
	modelClone.Parent = workspace
	wait(1)
	modelClone:WaitForChild("Rope").Script.Enabled = true
	modelClone:WaitForChild("Script").Enabled = true
end

remote.OnServerEvent:Connect(function(player) -- receiving the remote (notice how player is an argument)
	spawnModelAbovePlayer(player)
end)

Hope I helped!

1 Like

i said in my post a remoteevent wont work because i dont know how to get the vector3 without the head.Position. when i do use a remote event it just gives me an error saying “vector3 expected, got instance.” this is the edited code i used to get it to fire the event:

(local script)

local Players = game:GetService("Players")
local UserInputService = game:GetService("UserInputService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

-- Assuming the model to spawn is stored in ReplicatedStorage
-- Make sure to replace 'ModelName' with the actual name of your model
local modelToSpawn = ReplicatedStorage:FindFirstChild("Trip"):Clone()

-- Function to spawn the model above the player's head
local function spawnModelAbovePlayer(player)
	if player.Team == game.Teams.Out then return end
	if player.team == game.Teams.Runner then return end

    local character = player.Character or player.CharacterAdded:Wait()
    local head = character:FindFirstChild("Head")

    -- Calculate the position above the player's head
    local position = head.Position + Vector3.new(3, head.Size.Y + modelToSpawn:GetExtentsSize().Y / 2, 0)

	game.ReplicatedStorage.TagTrip:FireServer(player, position)
	end


-- Function to handle mouse button 1 click
local function onMouseButton1Click()
    local player = Players.LocalPlayer
    spawnModelAbovePlayer(player)
end

-- Connect the mouse button 1 click event
UserInputService.InputBegan:Connect(function(input, gameProcessedEvent)
    if gameProcessedEvent then return end
    if input.UserInputType == Enum.UserInputType.MouseButton1 then
        onMouseButton1Click()
    end
end)

(server script(also help from roblox assistant))

-- Server-side script to spawn a model at the player's click position
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local Workspace = game:GetService("Workspace")

-- Assuming a RemoteEvent named "SpawnModelRequest" exists in ReplicatedStorage for clients to request spawning a model
local spawnModelRequestEvent = ReplicatedStorage.TagTrip


-- Function to spawn the model
local function spawnModel(position)
    local model = ReplicatedStorage.Trip:Clone()
    if model then
        model:SetPrimaryPartCFrame(CFrame.new(position))
        model.Parent = Workspace
    end
end

-- Event listener for the spawn model request
spawnModelRequestEvent.OnServerEvent:Connect(function(player, position)
    -- Validate if the player is allowed to spawn the model
    -- This is where you can add conditions or checks, for example, to limit how often a player can spawn models
    -- For simplicity, this example allows all requests
    spawnModel(position)
end)

-- Bind to PlayerAdded event to handle incoming players
Players.PlayerAdded:Connect(function(player)
    -- Example: Send a message to the player, or set up player-specific data
    -- player:FindFirstChildOfClass("PlayerGui"):SetCore("ChatMakeSystemMessage", {
    --     Text = "Welcome! Click anywhere to spawn a model.";
    -- })
end)

-- Iterate through all existing players and attach the logic
for _, player in Players:GetPlayers() do
    -- Example: Send a message to the player, or set up player-specific data
    -- player:FindFirstChildOfClass("PlayerGui"):SetCore("ChatMakeSystemMessage", {
    --     Text = "Welcome! Click anywhere to spawn a model.";
    -- })
end

When you FireServer, you don’t need to pass the player as it is done by default. Just send the position and it’ll be fine.

game.ReplicatedStorage.TagTrip:FireServer(position)
1 Like

No need to pass the position thru the remote either. Just do it on the server :wink:

1 Like

this worked. i forgot i could get the position after i fired the event lol ty

1 Like

yeah exactly lol. Glad I could help!!

ahhh quick question since ur here. how would i get the model to clone in the same direction the player is looking? i know how do that if it wasnt spawning above the players head but idk how to do that while cloning it

You might find CFrame.lookAt() useful here. Just set the CFrame to look at the player’s HumanoidRootPart.

local spawnPosition = head.Position + Vector3.new(3, head.Size.Y + modelClone:GetExtentsSize().Y / 2, 0)
	local playerPosition = character.HumanoidRootPart.Position
	local lookAtDirection = CFrame.lookAt(spawnPosition, playerPosition)

	modelClone:PivotTo(lookAtDirection)

this script still spawns the model but it still spawns in one direction and not the direction the player is looking at

(i realized the other script was so wrong lol)

Make sure the primary part’s front face is facing the correct direction. CFrame.lookAt() uses the front face to determine what the front of the object is.

i know that, but the model is spawning in one single direction no matter which way i turn my character

like this

Try this:

local lookVector = rootPart.CFrame.LookVector
local spawnPosition = head.Position + (lookVector * 3)
		
model:PivotTo(CFrame.lookAt(spawnPosition, spawnPosition - lookVector))

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.