I am trying to use the portal demo@EgoMoose created to replicate tools in the portal world, as well as trying to fix the bugs with characters not being removed after death in the viewport. To follow along, you can take a copy of the place from the link.
I have tried making a detection function that updates the characters when death occurs or a tool is equipped/unequipped inside CharacterClone:
CheckReplace
-- Replace Function
function CharacterClone:CheckReplace(char)
for fake, real in next, self.Lookup do
if (char:FindFirstChild("Humanoid")) and Died == true then
print("Humanoid")
Died = false
end
char:WaitForChild("Humanoid").Died:connect(function()
fake:Destroy()
Died = true
return true
end)
if char:FindFirstChild("ClassicSword") and ToolGate == false then
fake:Destroy()
ToolGate = true
print("Tool!")
return true
end
if not char:FindFirstChild("ClassicSword") and ToolGate == true then
fake:Destroy()
ToolGate = false
print("No tool!")
return true
end
--print("Ran!")
end
end
As well, inside the GetLookup function I added code to clone tools (this works):
GetLookup
elseif (item:IsA("Tool")) then
local match = character:FindFirstChild(item.Name).Handle
item = item.Handle
item.Anchored = true
lookup[item] = match
end```
Finally, I added the CheckReplace function into the FixedBlock script in the RenderStepped portion:
RenderStepped
game:GetService("RunService").RenderStepped:Connect(function(dt)
for i = 1, #clones do
clones[i]:Update()
if clones[i]:CheckReplace(script.Parent) then
onCharacter(script.Parent)
end
end
end)
However, my solution fails to work. If you have any ideas on how to fix this, let me know!
The way I dealt with tools was simply using .DecendantAdded and .DecendantRemoving events. Tools get parented between Backpack and Character, so they fire DescendantAdded when you equip and DescendantRemoving when you unequip.
This way, you don’t need to poll every single character every single frame! Just handle them when the events fire. This method is nice cuz it’ll handle other things being added to the character too, such as hats or even custom armor meshes.
For deaths, you can simply reuse the dead body parts for the respawned character. This means you don’t need to recreate it, you just move them from the floor back up into the character.
local ViewportHandler = require(script.ViewportHandler)
local VF = game.Players.LocalPlayer:WaitForChild("PlayerGui"):WaitForChild("ScreenGui").ViewportFrame
VF.CurrentCamera = workspace.CurrentCamera
local VF_H = ViewportHandler.new(VF)
local pHs = {} --player handlers
game.Players.PlayerRemoving:Connect(function(plr)
if pHs[plr] then
pHs[plr]:Destroy() -- Clear old body
end
end)
game.Players.PlayerAdded:Connect(function(plr) -- Setup players that join later
--Initial
local char = plr.Character or plr.CharacterAdded:Wait()
local hum = char:WaitForChild("Humanoid",3)
if hum then wait() -- wait otherwise we run this before the meshes load properly
pHs[plr] = VF_H:RenderHumanoid(char)
end
--Future
plr.CharacterAdded:Connect(function(char)
local hum = char:WaitForChild("Humanoid",3)
if hum then wait() -- wait otherwise we run this before the meshes load properly
if pHs[plr] then
pHs[plr]:Destroy() -- Clear old body
end
pHs[plr] = VF_H:RenderHumanoid(char)
end
end)
end)
wait(1) -- Let players load in
for i,plr in pairs(game.Players:GetPlayers()) do -- Setup players in game
spawn(function() -- Run in parallel since each can yield from the :Wait()
--Initial
local char = plr.Character or plr.CharacterAdded:Wait()
local hum = char:WaitForChild("Humanoid",3)
if hum then wait() -- wait otherwise we run this before the meshes load properly
pHs[plr] = VF_H:RenderHumanoid(char)
end
--Future
plr.CharacterAdded:Connect(function(char)
local hum = char:WaitForChild("Humanoid",3)
if hum then wait() -- wait otherwise we run this before the meshes load properly
if pHs[plr] then
pHs[plr]:Destroy() -- Clear old body
end
pHs[plr] = VF_H:RenderHumanoid(char)
end
end)
end)
end
Everything is handled inside the module, you just tell it what you want it to do!