Open source reanim with your little friend
Key RequiredUniversal

Open source reanim with your little friend

Universal ScriptMonkerMonker 5.5K views 504 executesUpdated Apr 26, 2025
3.8/ 5(4 votes)
3175% Positive
Lua Script•436 lines (13144 chars)
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local UserInputService = game:GetService("UserInputService")

local LocalPlayer = Players.LocalPlayer
local Camera = workspace.CurrentCamera

local Mouse = LocalPlayer:GetMouse()
local rightCtrlDown = false

local function logOutput(logType, message, bypass)
	if (bypass or getgenv().Network.Output.Enabled) and typeof(logType) == "function" then
		logType(getgenv().Network.Output.Prefix .. message)
	end
end

if not getgenv().Network then
	local Network = {
		BaseParts = {},
		Output = {
			Enabled = true,
			Prefix = "[NETWORK] ",
			Send = logOutput
		},
		CharacterRelative = false,
		Velocity = Vector3.new(14.46262424, 14.46262424, 14.46262424)
	}
	getgenv().Network = Network

	logOutput(print, ": Loading.")

	function Network.RetainPart(part, returnFake)
		logOutput(print, 'Checking '..tostring(part)..'...')
		logOutput(print, 'Is an Instance: '..tostring(typeof(part) == "Instance"))
		logOutput(print, 'Is a Part: '..tostring(part:IsA("Part") or part:IsA("MeshPart")))
		logOutput(print, 'Is a descendant of workspace: '..tostring(part:IsDescendantOf(workspace)))
		assert(typeof(part) == "Instance" and (part:IsA("Part") or part:IsA("MeshPart")) and part:IsDescendantOf(workspace), "RetainPart Error: Invalid part.")
		if returnFake and typeof(returnFake) ~= "boolean" then
			error("RetainPart Error: Invalid returnFake flag.")
		end
		if table.find(Network.BaseParts, part) then
			logOutput(warn, "Part already retained: " .. part:GetFullName())
			return false
		end

		if Network.CharacterRelative then
			local character = LocalPlayer.Character
			if not (character and character.PrimaryPart) then
				logOutput(warn, "Character.PrimaryPart not found.")
				return false
			end
			local dist = (character.PrimaryPart.Position - part.Position).Magnitude
			if dist > 1000 then
				logOutput(warn, "Part too far from character: " .. part:GetFullName())
				return false
			end
		end

		table.insert(Network.BaseParts, part)
		part.CustomPhysicalProperties = PhysicalProperties.new(0, 0, 0, 0, 0)
		logOutput(print, "PartOwnership applied to: " .. part:GetFullName())
		return returnFake and FakePart or true
	end

	function Network.RemovePart(part)
		assert(typeof(part) == "Instance" and part:IsA("BasePart"), "RemovePart Error: Invalid part.")
		local idx = table.find(Network.BaseParts, part)
		if idx then
			table.remove(Network.BaseParts, idx)
			logOutput(print, "Removed PartOwnership from: " .. part:GetFullName())
		else
			logOutput(warn, "Part not found: " .. part:GetFullName())
		end
	end

	local SuperStepper = Instance.new("BindableEvent")
	Network.SuperStepper = SuperStepper
	for _, event in ipairs({RunService.Stepped, RunService.Heartbeat}) do
		event:Connect(function()
			SuperStepper:Fire(SuperStepper, tick())
		end)
	end

	Network.PartOwnership = {
		Enabled = false,
		PreMethodSettings = {}
	}

	function Network.PartOwnership.Enable()
		if Network.PartOwnership.Enabled then
			logOutput(warn, "PartOwnership already enabled.")
			return
		end
		Network.PartOwnership.Enabled = true
		Network.PartOwnership.PreMethodSettings = {
			ReplicationFocus = LocalPlayer.ReplicationFocus,
			SimulationRadius = gethiddenproperty(LocalPlayer, "SimulationRadius")
		}
		LocalPlayer.ReplicationFocus = workspace

		Network.PartOwnership.Connection = SuperStepper.Event:Connect(function()
			sethiddenproperty(LocalPlayer, "SimulationRadius", math.huge)
			for _, part in ipairs(Network.BaseParts) do
				task.spawn(function()
					if part:IsDescendantOf(workspace) then
						if Network.CharacterRelative then
							local character = LocalPlayer.Character
							if not (character and character.PrimaryPart) then
								logOutput(warn, "Missing Character.PrimaryPart.")
								return
							end
							if (character.PrimaryPart.Position - part.Position).Magnitude > 1000 then
								logOutput(warn, "Part too far: " .. part:GetFullName())
								Network.RemovePart(part)
								return
							end
						end
						part.Velocity = Network.Velocity + Vector3.new(0, math.cos(tick() * 10) / 100, 0)
					else
						Network.RemovePart(part)
					end
				end)
			end
		end)
		logOutput(print, "PartOwnership enabled.")
	end

	function Network.PartOwnership.Disable()
		if not Network.PartOwnership.Connection then
			logOutput(warn, "PartOwnership already disabled.")
			return
		end
		Network.PartOwnership.Connection:Disconnect()
		LocalPlayer.ReplicationFocus = Network.PartOwnership.PreMethodSettings.ReplicationFocus
		sethiddenproperty(LocalPlayer, "SimulationRadius", Network.PartOwnership.PreMethodSettings.SimulationRadius)
		for _, part in ipairs(Network.BaseParts) do
			Network.RemovePart(part)
		end
		Network.BaseParts = {}
		Network.PartOwnership.Enabled = false
		logOutput(print, "PartOwnership disabled.")
	end

	logOutput(print, ": Loaded.")
end

task.spawn(getgenv().Network.PartOwnership.Enable)

local character = LocalPlayer.Character
local IsR15 = character.Humanoid.RigType == Enum.HumanoidRigType.R15
local root
local handsAndLegs = {}

if IsR15 then
	for _,v in character:FindFirstChildOfClass('Humanoid'):GetAccessories() do
		if v.Name == "MeshPartAccessory" then
			if v.Handle.MeshId == "rbxassetid://4819720316" then
				root = v.Handle
			else
				table.insert(handsAndLegs, v.Handle)
			end
		end
	end
else
	for _,v in character:FindFirstChildOfClass('Humanoid'):GetAccessories() do
		if v.Name == "MeshPartAccessory" then
			if v.Handle.SpecialMesh.MeshId == "rbxassetid://4819720316" then
				root = v.Handle
			else
				table.insert(handsAndLegs, v.Handle)
			end
		end
	end
end

local pet = character['Accessory (ChudrikAccessory)'].Handle

local function CreateBodyMovers(part)
	local bp = Instance.new("BodyPosition", part)
	bp.D = 100
	bp.P = 10000
	bp.MaxForce = Vector3.new(math.huge, math.huge, math.huge)

	local bg = Instance.new("BodyGyro", part)
	bg.D = 100
	bg.P = 10000
	bg.MaxTorque = Vector3.new(math.huge, math.huge, math.huge)

	return bp, bg
end

replicatesignal(LocalPlayer.ConnectDiedSignalBackend)
task.wait(Players.RespawnTime)
local startPos = character.HumanoidRootPart.Position
character.HumanoidRootPart.CFrame = CFrame.new(0, workspace.FallenPartsDestroyHeight+10, 0)
task.wait(.1)
character:FindFirstChildOfClass("Humanoid"):ChangeState(15)

getgenv().Network.RetainPart(root)
getgenv().Network.RetainPart(pet)

local handsMovers = {}
for i = 1, 4 do
    local part = handsAndLegs[i]
    if part then
        local bp, bg = CreateBodyMovers(part)
        handsMovers[i] = {
            bp = bp,
            bg = bg,

            angleX = (i == 1 or i == 3) and math.rad(-90) or math.rad(90),
						angleY = 0,

            offset = if i <= 2 
                then Vector3.new(i == 1 and 1.5 or -1.5, 1, 0) 
                else Vector3.new(i == 3 and 0.625 or -0.625, -1, 0)
        }
    end
end

for _,v in handsAndLegs do
    getgenv().Network.RetainPart(v)
end

local bp, bg = CreateBodyMovers(root)
local bpPet, bgPet = CreateBodyMovers(pet)
local movementPart = Instance.new("Part", workspace)
movementPart.Position = startPos
movementPart.Size = Vector3.new(2, 4, 2)
movementPart.Transparency = 1

local tempMover = Instance.new('BodyAngularVelocity', movementPart)
tempMover.MaxTorque = Vector3.new(math.huge, math.huge, math.huge)
tempMover.AngularVelocity = Vector3.zero
tempMover.P = 10000

tempMover = Instance.new('BodyVelocity', movementPart)
tempMover.MaxForce = Vector3.new(math.huge, 0, math.huge)
tempMover.Velocity = Vector3.zero
tempMover.P = 10000

movementPart.CustomPhysicalProperties = PhysicalProperties.new(0.7, 0, 0, 100, 100)

UserInputService.JumpRequest:Connect(function()
	movementPart.Velocity += Vector3.new(0, 60, 0)
end)

Mouse.Button1Down:Connect(function()
	if UserInputService:IsKeyDown(Enum.KeyCode.RightControl) then
		movementPart.Position = Mouse.Hit.Position + Vector3.yAxis
  end
end)

Camera.CameraSubject = movementPart

local function rotateSmoothDirection(direction, deltaTime)
	if direction.Magnitude == 0 then return end

	local flatDirection = Vector3.new(direction.X, 0, direction.Z).Unit
	local targetRotation = CFrame.lookAt(movementPart.Position, movementPart.Position - flatDirection)
	local smoothCFrame = movementPart.CFrame:Lerp(CFrame.new(movementPart.Position) * targetRotation.Rotation, deltaTime*10)

	movementPart.CFrame = smoothCFrame
end

local function rotateWithCamera()
	local lookVector = Camera.CFrame.LookVector
	local flatLook = Vector3.new(lookVector.X, 0, lookVector.Z).Unit
	if flatLook.Magnitude == 0 then return end

	local targetRotation = CFrame.lookAt(movementPart.Position, movementPart.Position - flatLook)

	movementPart.CFrame = CFrame.new(movementPart.Position) * targetRotation.Rotation
end

local rad15Z = CFrame.Angles(0, 0, -math.rad(15))
local rad180Y = CFrame.Angles(0, math.rad(180), 0)
local forward = true
local moving = false

local Players = game:GetService("Players")

local function getNearestPlr()
	local lowest = math.huge
	local NearestPlayer
	for _,plr in pairs(Players:GetPlayers()) do
		if plr ~= LocalPlayer and plr.Character then
			local distance = plr:DistanceFromCharacter(movementPart.Position)
			if distance < lowest then
				lowest = distance
				NearestPlayer = plr
			end
		end
	end
	return NearestPlayer
end

local willFollowNotMe = false
local targetOffset = Vector3.zero
local target
local tempPlr

spawn(function()
	while wait(math.random(30, 60)) do
		targetOffset = Vector3.zero
		if math.random(0, 10) > 5 then
			target = getNearestPlr().Character.Head
			willNotFollowMe = true
		else
			tempPlr = getNearestPlr().Character
			if tempPlr:FindFirstChild('LowerTorso') then
				target = tempPlr.LowerTorso
				willNotFollowMe = true
			elseif tempPlr:FindFirstChild('Torso') then
				target = tempPlr.Torso
				targetOffset = Vector3.new(0, -1, 0)
				willNotFollowMe = true
			end
		end
		if willNotFollowMe then
    		wait(math.random(10, 30))
    		willNotFollowMe = false
    	end
	end
end)

bpPet.Position = startPos
pet.Position = startPos

RunService.Heartbeat:Connect(function(deltaTime)
	if not UserInputService:GetFocusedTextBox() then
		local moveDir = Vector3.zero

		if not (UserInputService:IsKeyDown(Enum.KeyCode.W) and UserInputService:IsKeyDown(Enum.KeyCode.S)) then
			if UserInputService:IsKeyDown(Enum.KeyCode.W) then
				local lookVector = Camera.CFrame.LookVector
				moveDir += Vector3.new(lookVector.X, 0, lookVector.Z)
			elseif UserInputService:IsKeyDown(Enum.KeyCode.S) then
				local lookVector = Camera.CFrame.LookVector
				moveDir -= Vector3.new(lookVector.X, 0, lookVector.Z)
			end
		end

		if not (UserInputService:IsKeyDown(Enum.KeyCode.A) and UserInputService:IsKeyDown(Enum.KeyCode.D)) then
			if UserInputService:IsKeyDown(Enum.KeyCode.A) then
				local rightVector = Camera.CFrame.RightVector
				moveDir -= Vector3.new(rightVector.X, 0, rightVector.Z)
			elseif UserInputService:IsKeyDown(Enum.KeyCode.D) then
				local rightVector = Camera.CFrame.RightVector
				moveDir += Vector3.new(rightVector.X, 0, rightVector.Z)
			end
		end

		if moveDir.Magnitude > 0 then
			moving = true
			moveDir = moveDir.Unit

			movementPart.Position += moveDir * deltaTime * 20

			if UserInputService.MouseBehavior ~= Enum.MouseBehavior.LockCenter then
				rotateSmoothDirection(moveDir, deltaTime)
			end
		else
			moving = false
			forward = true
		end

		if UserInputService.MouseBehavior == Enum.MouseBehavior.LockCenter then
			rotateWithCamera()
		end
	end

	bp.Position = movementPart.Position + Vector3.yAxis
	bg.CFrame = movementPart.CFrame * rad15Z
	root.CFrame = movementPart.CFrame * rad15Z + Vector3.yAxis

	for i = 1, 4 do
		local mover = handsMovers[i]
		if mover then
			if moving then
				if i == 1 or i == 4 then
					if forward then
						mover.angleY += 1
						if mover.angleY == 45 then
							forward = false
						end
					else
						mover.angleY -= 1
						if mover.angleY == -45 then
							forward = true
						end
					end
				else
					if forward then
						mover.angleY -= 1
					else
						mover.angleY += 1
					end
				end
			else
				mover.angleY = 0
			end

			local targetCFrame = movementPart.CFrame 
				* CFrame.new(mover.offset) 
				* CFrame.Angles(math.rad(mover.angleY), 0, mover.angleX)

			mover.bp.Position = targetCFrame.Position
			mover.bg.CFrame = targetCFrame
			handsAndLegs[i].CFrame = targetCFrame
		end
	end
	local tempCFrame
	local tempPos
	if willNotFollowMe then
		if target then
			if (pet.Position - target.Position).Magnitude > 2 then
				tempCFrame = CFrame.lookAt(pet.Position, target.Position + targetOffset)*rad180Y
				bgPet.CFrame = tempCFrame
				tempPos = (pet.Position - (bgPet.CFrame.LookVector * deltaTime * 20))
				bpPet.Position = tempPos
				pet.Position = tempPos
			end
		else
			willNotFollowMe = false
		end
	else
		if (pet.Position - movementPart.Position).Magnitude > 3 then
			tempCFrame = CFrame.lookAt(pet.Position, movementPart.Position)*rad180Y
			bgPet.CFrame = tempCFrame
			tempPos = pet.Position - (bgPet.CFrame.LookVector * deltaTime * 20)
			bpPet.Position = tempPos
			pet.Position = tempPos
		end
	end
end)

Features & Information

"your little friend" in the title means "pet", because scriptblox doesn't allow the word "pet" in script title This is my open source reanim script. Also I added pet that follows you. Accessories: https://www.roblox.com/catalog/4819740796/Robox and 4 any fedoras any accessory for pet DONT FORGET TO SCALE THESE ACCESSORIES TO MAX You can change your pet accessory on line 176 and body parts(NO HEAD) on line 154
#reanim#cool#open source#free#universal

Community Comments (0)

No comments yet for this script.

More Scripts for Universal Scripts