Free character Morph Script

Morph Script - v1.1.0

A nice little module that lets you morph into any character :slight_smile:


Grab the module here!
VVV


How to use:

Insert the module anywhere in your game that is accessible by a Server Script. Next require the Module and you’ll be able to call these two functions:

1. Morph Player

MorphModule.MorphPlayer(Player, Model, Extra)
--[[
The above function will turn the desired player into the Model inputted.

If no Model is inputted into the function then it will instead Revert the 
Player back to their original avatar.

The third parameter, Extra, is optional, where Extra is An array of instances.
Having this will clone all instances in the array into the character model after 
morphing.

]] 

2. Revert Player

MorphModule.RevertPlayer(Player, Extra)

--[[
The above function will turn the desired player back to their original avatar. 

The second parameter, Extra, as mentioned previously, is optional.
]]


Make sure your models are properly rigged! (aka: has Humanoid, HumanoidRootPart, is unanchored, etc…)

In order for Roblox’s default ‘Animate’ script to work with multiplayer make sure you have a ‘Animator’ instance under your Humanoid.
image


Module:

Update - 5/18/25

--!strict
--[[

MORPH SCRIPT by Meat Make
v1.1.0


The Morph Script can Morph any player, as well as turn them back. Recommended for server side only.


-- [API] --


MorphPlayer(Player: Player, Model: Model?, Extra: {Instance}?)


RevertPlayer(Player: Player, Extra: {Instance}?)




-- Change Logs

Added function RevertPlayer to change the player character back to their own avatar

Bug fix for when var 'oldCharacter' is nil



]]

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--[Variables]
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


local StarterCharacterScripts = game:GetService("StarterPlayer").StarterCharacterScripts

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--[Types]
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

type Extra = {Instance}?

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--[Helper]
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function GetCharacter(Player: Player): Model
	local Character = Player.Character

	while Character == nil do

		Character = Player.Character
		task.wait()
	end
	
	
	return (Character :: any) :: Model
end

function AddExtra(Character, Extra: Extra)
	if Extra then
		for _, instance in ipairs(Extra) do
			local newInstance = instance:Clone()
			instance.Parent = Character
		end	
	end
end

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--[Module]
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------



local module = {}


-- Morphs the player into the Model. If no model is given, RevertPlayer function is ran automatically.
function module.MorphPlayer(Player: Player, Model: Model?, Extra: Extra)
	
	if not Model then
		module.RevertPlayer(Player)
		return
	end
	
	-- Morph into Model
	local oldCharacter:any = GetCharacter(Player)
	
	local newCharacter:any = Model:Clone()
	
	newCharacter.Name = Player.Name
	newCharacter.HumanoidRootPart.Anchored = false
	
	newCharacter:PivotTo(oldCharacter:WaitForChild("HumanoidRootPart").CFrame)
	Player.Character = newCharacter
	newCharacter.Parent = workspace

	oldCharacter:Destroy()
	
	-- Add back all scripts from StarterCharacterScrits
	for i, charScript in pairs(StarterCharacterScripts:GetChildren()) do
		local charScriptClone = charScript:Clone()
		charScriptClone.Parent = newCharacter
	end
	
	-- Add all Extra instances
	AddExtra(newCharacter, Extra)
	
end

-- Morphs the player back into their original avatar.
function module.RevertPlayer(Player: Player, Extra: Extra)
	
	local oldCharacter:any = GetCharacter(Player)
	local oldCframe = oldCharacter:WaitForChild("HumanoidRootPart").CFrame
	
	Player:LoadCharacter()
	local newCharacter = GetCharacter(Player)
	
	newCharacter:PivotTo(oldCframe)
	
	-- Add all Extra instances
	AddExtra(newCharacter, Extra)
end




return module



Try it out here!

Uncopylocked example place:

14 Likes

My bad guys. I discovered a bug where if you are in CameraType.Scriptable, then morph and go back to Enum.CameraType.Custom the camera breaks

1 Like

Solved the problem!
if you are trying to change from a different cam type to CameraType.Custom do this:

cam.CameraSubject = LocalPlayer.Character.Humanoid
cam.CameraType = Enum.CameraType.Custom

small error, :SetPrimaryPartCFrame() is now :PivotTo()

Can you send me the error message? I tried both :SetPrimaryPartCframe() and :PivotTo() and they seem to work fine…

also SetPrimaryPartCframe is deprecated I would use MoveTo() instead:

Found another camera bug, if I try an morph while my cameraType is in scriptable the position changes, looking into it

my bad, i meant small mistake, since :SetPrimaryPartCframe() is deprecated.

1 Like

ohhhh thats what you mean, thanks i’ll update the code now :sweat_smile:

1 Like

So this is my fix, I created a remote event and fire it to the player that’s being morphed. And then on the client side I just update the cam back to what its originally supposed to be.

SERVER SIDE

-- SERVER SIDE
local morphedCamClient = Events:WaitForChild("morphedCamClient") -- replace with your remote event 

local function doMorph(Player, morphModel)
	local oldCharacter = Player.Character
	local newCharacter = morphModel:Clone()
	
	newCharacter.HumanoidRootPart.Anchored = false
	newCharacter:PivotTo(oldCharacter.PrimaryPart.CFrame)
	Player.Character = newCharacter
	newCharacter.Parent = workspace
	
	oldCharacter:Destroy()
	for i, charScript in pairs(StarterCharacterScripts:GetChildren()) do
		local charScriptClone = charScript:Clone()
		charScriptClone.Parent = newCharacter
	end
	morphedCamClient:FireClient(Player)
	
end

CLIENT SIDE

local Players = game:GetService("Players")
local LocalPlayer = Players.LocalPlayer
local cam = workspace.Camera

Events:WaitForChild("morphedCamClient").OnClientEvent:Connect(function() -- replace with your own event

	repeat task.wait()
		
	until cam.CameraType == Enum.CameraType.Custom

	-- add in your own function that reconnects your camera


end)
4 Likes

Updated this module, hope you guys enjoy

Updated to 1.1.0!

Added a new function which lets you revert back into your own original avatar

Do you happen to have an example testing editable place to check this out , with some different characters?

Thanks

1 Like

I gotchu

2 Likes

Nice, is there meant to be a delay on the revert after you click on it?

no, probs server lag. It uses the LoadCharacter function to get your avatar

why would you not get it one time when the character loads… then maybe clone it for Original character… then when you revert, it is already there as a Orig char clone, … and might not lag…

Theres also an edge case where the player changes their avatar while in game, and those changes wouldn’t be made when u use your cloning method.

And I just tried it again, and I’m not seeing any lag on my end.

cool, ok… those edge cases can get tricky…