Character Instance does not behave as expected [How to call Module functions]

I am trying to create a trampoline model that bounces you up and makes you ragdoll.
So far, the trampoline part is working, but the ragdoll part isn’t.

It looks like this:
image

When Mat is touched, the following script runs, which is named JumpScript.

local canwork = true -- to avoid loops
local prevjumpheight = 0 -- this is to get back the player height to the height which was before jumping on trampoline

script.Parent.Touched:Connect(function(hit) -- event fires when some thing touches the trampoline
	if hit.Parent:FindFirstChild("Humanoid") and canwork == true then -- if its a player who stepped
		local humanoid = hit.Parent:FindFirstChild("Humanoid")
		canwork = false -- now script wont run
		prevjumpheight = hit.Parent:FindFirstChild("Humanoid").JumpHeight
		humanoid.JumpHeight = 35 -- this is the height that the player can jump, we make it 150, so the player can jump high
		humanoid.Jump = true -- we will make the player jump, so its like a trampoline
		script.Jumped:Fire(hit.Parent)
		task.wait(0.5) -- when the player goes up the sky by 150 studs, we make the player height they can jump normal
		humanoid.JumpHeight = prevjumpheight -- again the player character jump height in studs become normal
		canwork = true -- script runs again
	end
end)

It triggers an Event, named Jumped, which relays the name of the player who touched it.

The “Script” script triggers the ragdoll after it recieves the event. It’s here:

local Module = require(script.RagdollModule)
script.Parent.JumpScript.Jumped.Event:Connect(function(character)
	assert(typeof(character) == 'Instance' and character:IsA("Model"), "OK")
	Module:Ragdoll(character, {LimbsCollision = true; Duration = 10;})
end)

The module script is here:

export type RagdollDatas = {
	LimbsCollision: boolean;
	Duration: number;
}

local RagdollHandler = {}

local Players = game:GetService('Players')
local Debris = game:GetService('Debris')

local RagdollBlacklists = {
	States = {
		Enum.HumanoidStateType.Ragdoll;
		Enum.HumanoidStateType.FallingDown;
	};

	CollisionLimbs = {
		'HumanoidRootPart';
		'Torso';
		'UpperTorso';
		'LowerTorso';
	}
}

local CurrentRecoverThread = nil

function RagdollHandler.Ragdoll(Character: Model, Datas: RagdollDatas)
	assert(typeof(Character) == 'Instance' and Character:IsA('Model') and Character:FindFirstChild('Humanoid'), 'Character is not a valid character. Please check again!')

	Datas = Datas or {}

	local Humanoid = Character:WaitForChild('Humanoid')
	local HumanoidRootPart = Character:WaitForChild('HumanoidRootPart')

	if Humanoid:GetState().Name == 'Dead' then
		return
	end

	local Default_Datas: RagdollDatas = {
		LimbsCollision = true;
		Duration = 1;
	}	

	local function FillTableInfo(Template: {any}, GivenTable: {any})
		for Name, Value in Template do
			GivenTable[Name] = GivenTable[Name] or Value

			local DataType = typeof(GivenTable[Name])
			local DefaultDataType = typeof(Value)

			assert(DataType == DefaultDataType, `{Name} expected to be {DefaultDataType} but got {DataType} instead!`)

			if DataType == 'table' then
				FillTableInfo(Value, GivenTable[Name])
			end
		end
	end

	for Name, Value in Default_Datas do
		Datas[Name] = Datas[Name] or Value

		local DataType = typeof(Datas[Name])
		local DefaultDataType = typeof(Value)

		assert(DataType == DefaultDataType, `{Name} expected to be {DefaultDataType} but got {DataType} instead!`)

		if DataType == 'table' then
			FillTableInfo(Value, Datas[Name])
		end
	end

	for _, State in RagdollBlacklists.States do
		Humanoid:SetStateEnabled(State, false)
	end

	Humanoid:ChangeState(Enum.HumanoidStateType.Physics)

	Humanoid.AutoRotate = false
	Humanoid.PlatformStand = true

	for _, Obj in Character:GetDescendants() do
		if Obj:IsA('Motor6D') then
			local RagdollSocket = Instance.new("BallSocketConstraint")
			local RagdollAttachment0 = Instance.new("Attachment")
			local RagdollAttachment1 = Instance.new("Attachment")

			RagdollAttachment0.Parent = Obj.Part0
			RagdollAttachment1.Parent = Obj.Part1
			RagdollSocket.Parent = Obj.Parent

			RagdollSocket:SetAttribute('RagdollAsset', true)
			RagdollAttachment0:SetAttribute('RagdollAsset', true)
			RagdollAttachment1:SetAttribute('RagdollAsset', true)

			RagdollSocket.Attachment0 = RagdollAttachment0
			RagdollSocket.Attachment1 = RagdollAttachment1

			RagdollAttachment0.CFrame = Obj.C0
			RagdollAttachment1.CFrame = Obj.C1

			RagdollSocket.LimitsEnabled = true
			RagdollSocket.TwistLimitsEnabled = true

			Obj.Enabled = false
		end
	end

	for _, Obj in Character:GetChildren() do
		if Datas.LimbsCollision and Obj:IsA('BasePart') and not table.find(RagdollBlacklists.CollisionLimbs, Obj.Name) then
			local LimbCopy = Obj:Clone()
			LimbCopy.Parent = Obj
			LimbCopy.Size = Vector3.new(Obj.Size.X / 2, Obj.Size.Y / 2, Obj.Size.Z / 2)
			LimbCopy.CFrame = Obj.CFrame
			LimbCopy.CanCollide = true
			LimbCopy.Anchored = false
			LimbCopy.Transparency = 1

			LimbCopy:SetAttribute('RagdollAsset', true)

			local LimbWeld = Instance.new('WeldConstraint')
			LimbWeld.Parent = LimbCopy
			LimbWeld.Part0 = LimbCopy
			LimbWeld.Part1 = Obj

			LimbWeld:SetAttribute('RagdollAsset', true)
		end
	end

	if Datas.Duration then
		if CurrentRecoverThread then
			task.cancel(CurrentRecoverThread)
			CurrentRecoverThread = nil
		end

		CurrentRecoverThread = task.delay(Datas.Duration, function()
			for _, Obj in Character:GetDescendants() do
				if Obj:GetAttribute('RagdollAsset') ~= nil then
					Obj:Destroy()
				end
			end

			for _, Obj in Character:GetDescendants() do
				if Obj:IsA('Motor6D') and not Obj.Enabled then
					Obj.Enabled = true
				end
			end

			Humanoid:ChangeState(Enum.HumanoidStateType.Running)

			Humanoid.AutoRotate = true
			Humanoid.PlatformStand = false

			for _, State in RagdollBlacklists.States do
				Humanoid:SetStateEnabled(State, true)
			end
		end)
	else
		for _, Obj in Character:GetDescendants() do
			if Obj:GetAttribute('RagdollAsset') ~= nil then
				Obj:Destroy()
			end
		end

		for _, Obj in Character:GetDescendants() do
			if Obj:IsA('Motor6D') and not Obj.Enabled then
				Obj.Enabled = true
			end
		end

		Humanoid:ChangeState(Enum.HumanoidStateType.Running)

		Humanoid.AutoRotate = true
		Humanoid.PlatformStand = false

		for _, State in RagdollBlacklists.States do
			Humanoid:SetStateEnabled(State, true)
		end
	end
end

return RagdollHandler

It is taken from here: Github

The module reports the Character that it is not a Character, which I think is incorrect.

Thank you in advance! :slight_smile:

1 Like

Hello!
When you’re calling that Ragdoll function, you should use dot notation instead of a colon, e.g., Module.Ragdoll() instead of Module:Ragdoll().

Colons are for calling methods, not functions. When you used Module:Ragdoll(), it returns the module itself as the first parameter, which isn’t a character.

Wow! I did not know this before, as I’m not familiar with modules, thanks!

1 Like

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