Morph not quite working

Hi, I am trying to make a feature where you press the “R” key on your keyboard and it changes your avatar into a rat. The code doesn’t error, but all it does is make a rat fly out of the player’s HRP. This is run by a LocalScript parented to StarterCharacterScripts. I’ve tried moving it to a few different locations and nothing has worked. I’m still pretty new to scripting, so I’m not really sure what to do now.

Here is my code:

local UserInputService = game:GetService("UserInputService")

local Player = game:GetService("Players").LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local HumanoidRootPart = Player.Character:WaitForChild("HumanoidRootPart")

local morph = game.Workspace.Rat

UserInputService.InputBegan:Connect(function(input)
	if input.KeyCode == Enum.KeyCode.R then
		
		morph:Clone()
		morph.HumanoidRootPart.Anchored = false
		morph:SetPrimaryPartCFrame(Character.PrimaryPart.CFrame)
		
		Player.Character = morph
		morph.Parent = workspace
		print("works")
	end
end)

If you think you know what went wrong, please let me know. Have a good day!

3 Likes

I have a feeling it’s probably something really simple and that I’m just looking over it lol.

1 Like

Hello!
Your script is mostly correct, however, you made two mistakes.

First one is that you placed the morph in the workspace, when it should only be put there after the character is changed. So, instead, you should place it somewhere such as the ServerStorage.

The other issue is that you used a LocalScript, instead of a ServerScript. For you to change a player character, it needs to be ran in the server, not in the client. Therefore, you can do the following:

  1. Insert a RemoteEvent inside of ReplicatedStorage. This will allow the Client to communicate with the Server, so it knows when the player pressed the letter “R”. We’ll name this RemoteEvent “RatEvent”.
  2. Create a ServerScript in the ServerScriptService, with the following code:
game:GetService("ReplicatedStorage").RatEvent.OnServerEvent:Connect(function(Player)
	local Character = Player.Character
	local HumanoidRootPart = Character.HumanoidRootPart
	
	morph:Clone()
	morph.HumanoidRootPart.Anchored = false
	morph:SetPrimaryPartCFrame(Character.PrimaryPart.CFrame)

	Player.Character = morph
	morph.Parent = workspace
end)
  1. Now, you must adapt your LocalScript so that it fires the RemoteEvent instead of changing the player character. Set it to the following:
local UserInputService = game:GetService("UserInputService")

UserInputService.InputBegan:Connect(function(input)
	if input.KeyCode == Enum.KeyCode.R then
		-- Firing the RemoteEvent once the R key is pressed
		game:GetService("ReplicatedStorage").RatEvent:FireServer()
	end
end)
1 Like

It worked! Thank you so much! Now, how would you make it to where once the player is changed into the rat, they can press “R” again and go back to their regular avatar?

You could have a variable in your code that changes when the player becomes a Rat. And, when they press the R button again, the script would call Player:LoadCharacter() to respawn them with their original character.

1 Like

Should I do this in my server or local script? I’m assuming server.

The server is the one who should keep track of these values, just so the client can’t potentially mislead it into doing something different. However, in this case, the client can do it as well.

1 Like

Can I please have a code example? Here’s mine so you can tweak it:

local morph = game.ServerStorage.Rat

game:GetService("ReplicatedStorage").RatEvent.OnServerEvent:Connect(function(Player)
	local Character = Player.Character
	local HumanoidRootPart = Character.HumanoidRootPart
	
	morph:Clone()
	morph.HumanoidRootPart.Anchored = false
	morph:SetPrimaryPartCFrame(Character.PrimaryPart.CFrame)
	
	Player.Character = morph
	morph.Parent = workspace
end)

It depends on your case, honestly. If you left the player character with the name of “Rat”, you could just check the Character name and do it that way.

local morph = game.ServerStorage.Rat

game:GetService("ReplicatedStorage").RatEvent.OnServerEvent:Connect(function(Player)
	local Character = Player.Character
	local HumanoidRootPart = Character.HumanoidRootPart
	
	-- Check if the character name is "Rat"
	if Character.Name == "Rat" then
		local position = HumanoidRootPart.CFrame
		Player:LoadCharacter() -- Respawn player
		Player.Character.HumanoidRootPart.CFrame = position -- Teleport them back to where they were
		return
	end

	morph:Clone()
	morph.HumanoidRootPart.Anchored = false
	morph:SetPrimaryPartCFrame(Character.PrimaryPart.CFrame)

	Player.Character = morph
	morph.Parent = workspace
end)
1 Like

Doesn’t something have to be done on the LocalScript? I ran the code, but it doesn’t work.

It worked on my end. The LocalScript doesn’t need changing since the Server was the one handling it.

Did you get any errors?

1 Like

No, it’s completely blank. Should I use another Event to track switching the character?

But is anything happening in specific? Is the person re-spawning but still with the Rat uniform (this would indicate that the Server is not detecting that the user is a Rat), or something different?

No need. You can have it all be in one event. The best way to do this is to have the server verify which character the person is currently set to. Maybe you could check for a specific part inside of the character instead of the name, or try to find a solution that works for your specific case.

1 Like

Nothing is happening. Press the “R” key does nothing and no errors appear in the output.

So you can’t even become a Rat? That’s odd… it could be an issue in your end, since nothing much was changed from between the 2 scripts.

1 Like

You can become a rat, but you can’t change back into your Roblox character, even after I changed the server script with the code you provided. I tried restarting Studio and moving things around, but nothing’s changed.

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