Is there any way to morph without the touched event ( In a server script)

I am trying to make something where you choose a class then deciding upon the class, it tps you somewhere to fall through a part to morph yourself but if you just click the confirm button and morph into to would look way cleaner. I use the basic morph scirpt:

local pad = script.Parent
local characterName = "Criminal"
local character = pad.Parent:WaitForChild(characterName)
 
local debounce = true
pad.Touched:Connect(function(obj)
    local plr = game.Players:GetPlayerFromCharacter(obj.Parent)
    if plr and debounce == true then
        debounce = false
       
        pad.BrickColor = BrickColor.new("Really red")
       
        local charClone = character:Clone()
        charClone.Name = plr.Name
        plr.Character = charClone
       
        local rootPart = charClone:FindFirstChild("HumanoidRootPart") or charClone:FindFirstChild("Torso")
        local plrRoot = obj.Parent:FindFirstChild("HumanoidRootPart") or obj.Parent:FindFirstChild("Torso")
       
        if rootPart and plrRoot then
            rootPart.CFrame = plrRoot.CFrame
        end
       
        charClone.Parent = workspace
       
        wait(5)
       
        pad.BrickColor = BrickColor.new("Lime green")
        debounce = true
    end
end)

This is the event triggering the morph. See how it uses the touched object to do a player lookup to check if it was a character that touched it? You can fire a remote event when the confirm button is clicked, and add the morph to the player with the same logic. The server listener for Remote’s gets passed the player as the first argument implicitly.

morphRemoteEvent.OnServerEvent:Connect(function(player)
    if debounce == true then
        debounce = false

        pad.BrickColor = BrickColor.new("Really red")

        -- + the rest of the code i didn't include for examples sake

        debounce = true
    end
end)

What was plr in your code is now the param player, which tells the server which client fired that remote event.

client firing via gui button click along the lines of

confirmButton.Activated:Connect(function()
    morphRemoteEvent:FireServer()
end)

You are parenting the character to workspace at the end of the script?

but how would I reference a player?

No I grouped the pad and the morph together

The OnServerEvent signal of the RemoteEvent always passes the firing client’s player as the first argument. That’s why it already exists in the binding for that signal.

morphRemoteEvent.OnServerEvent:Connect(function(player)

end)