I am creating a first person view model with 2 hands for a horror game I am working on.
Issue
Whenever the player holds a tool, the tool is displayed on the player’s actual arm, not the view model.
What I’ve tried
I tried to change the CFrame of the Handle of the tool and using weld constraints, just to find out that it doesn’t work.
Code
local Player = game.Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local HRP = (Character:FindFirstChild("Head") :: BasePart)
local Camera = workspace.Camera
local RunService = game:GetService("RunService")
local ViewModel: Model = game.ReplicatedStorage.ViewModel:Clone()
ViewModel.Parent = Camera
Player.Character:WaitForChild("Body Colors"):Clone().Parent = ViewModel;
Player.Character:WaitForChild("Shirt"):Clone().Parent = ViewModel;
Player.Character:WaitForChild("Pants"):Clone().Parent = ViewModel;
local VMHumanoid = ViewModel:FindFirstChildWhichIsA("Humanoid");
local VMAnimator = VMHumanoid:FindFirstChild("Animator") :: Animator;
local VMAnimSaves = ViewModel:FindFirstChild("Animations") :: Model;
local VMBobble = VMAnimator:LoadAnimation(VMAnimSaves:WaitForChild("Bobble"));
local VMHold = VMAnimator:LoadAnimation(VMAnimSaves:WaitForChild("BobbleHoldItem"));
VMHold.Priority = Enum.AnimationPriority.Action4;
local VMRightArm = ViewModel:WaitForChild("Right Arm") :: BasePart;
local VMToolHandle = VMRightArm:WaitForChild("ToolHandle") :: BasePart;
local toolCheck = function(tool: Tool): ()
local equipped: boolean = false;
local weld: WeldConstraint = Instance.new("WeldConstraint");
local handle = tool:WaitForChild("Handle") :: BasePart;
tool.Equipped:Connect(function(): ()
if not (VMHold.IsPlaying) then
VMHold:Play();
equipped = true;
end;
end);
tool.Unequipped:Connect(function(): ()
if (VMHold.IsPlaying) then
VMHold:Stop();
equipped = false;
end;
end);
end;
RunService.RenderStepped:Connect(function()
if Player.Character.Humanoid.Health == 0 then
if Camera:FindFirstChild("ViewModel") ~= nil then
ViewModel:Destroy()
end
end
if Camera:FindFirstChild("ViewModel") ~= nil then
ViewModel:PivotTo(Camera.CFrame * CFrame.new(.025, -2, -.3) * CFrame.Angles(0.3, 0, 0))
end
if (Character:FindFirstChildWhichIsA("Humanoid").MoveDirection.Magnitude > 0) then
if not (VMBobble.IsPlaying) then
VMBobble:Play();
end;
else
if (VMBobble.IsPlaying) then
VMBobble:Stop();
end;
end;
for i: number, v: Tool in ipairs(Player.Backpack:GetChildren()) do
if v:IsA("Tool") then
toolCheck(v);
end;
end;
end)
First of all, OMG I absolutely love how you formatted the topic, it’s simple, concise, clear and straight to the point, Roblox should make this the format of each topic imo
So, since you are using animation best thing to do here is use a Motor6D over a WeldConstraint (im not much experienced with WeldConstraints )
Also you are running the toolCheck func every frame which is unideal. Instead running it once in the outer scope and then every time a child is added to backpack using the Backpack.ChildAdded event
Hello there!
Firstly, thank you for responding
Second of all, I forgot that I was in a renderStepped function, that’s why I didn’t realize I was running the loop in it
Thirdly, This is the right arm.
This happens when I equip the tool: (please ignore the bg sounds )
I figured it OUT!
So basically what I did was make clones of the tool’s handle and weld them to the Right Hand of the view model.
I wasn’t really sure why i couldn’t think of this solution, maybe I was a little too burnt out.
local Player = game.Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local HRP = (Character:FindFirstChild("Head") :: BasePart)
local Camera = workspace.Camera
local RunService = game:GetService("RunService")
local ReplicatedStorage = game:GetService("ReplicatedStorage");
local Tools = ReplicatedStorage:WaitForChild("Tools");
local ViewModel: Model = ReplicatedStorage:WaitForChild("ViewModel"):Clone();
ViewModel.Parent = Camera;
Player.Character:WaitForChild("Body Colors"):Clone().Parent = ViewModel;
Player.Character:WaitForChild("Shirt"):Clone().Parent = ViewModel;
Player.Character:WaitForChild("Pants"):Clone().Parent = ViewModel;
local VMHumanoid = ViewModel:FindFirstChildWhichIsA("Humanoid");
local VMAnimator = VMHumanoid:FindFirstChild("Animator") :: Animator;
local VMAnimSaves = ViewModel:FindFirstChild("Animations") :: Model;
local VMBobble = VMAnimator:LoadAnimation(VMAnimSaves:WaitForChild("Bobble"));
local VMHold = VMAnimator:LoadAnimation(VMAnimSaves:WaitForChild("BobbleHoldItem"));
VMHold.Priority = Enum.AnimationPriority.Action4;
local VMRightArm = ViewModel:WaitForChild("Right Arm") :: BasePart;
local VMToolHandle = VMRightArm:WaitForChild("ToolHandle") :: BasePart;
local SUFFIX = "_CLONE";
local PREFIX = "CHECK_DONE_";
local lArrow = "<-";
local rArrow = "->";
local toolCheck = function(tool: Tool): ()
local equipped: boolean = false;
tool.Equipped:Connect(function(): ()
if not (VMHold.IsPlaying) then
VMHold:Play();
equipped = true;
for i: number, v: Instance in ipairs(tool:GetDescendants()) do
if v:IsA("BasePart") or v:IsA("MeshPart") or v:IsA("UnionOperation") then
v.Transparency = 1;
elseif v:IsA("PointLight") or v:IsA("SurfaceLight") then
v.Brightness = 0;
elseif v:IsA("ParticleEmitter") then
v.Enabled = false;
end;
end;
local cloneTool: BasePart = Tools:WaitForChild(tool.Name):Clone();
cloneTool.Name = tool.Name..SUFFIX;
cloneTool.Parent = VMToolHandle;
local motor6d = Instance.new("Motor6D", VMToolHandle);
motor6d.Name = lArrow..tool.Name..SUFFIX..rArrow;
motor6d.Part0 = cloneTool;
motor6d.Part1 = VMToolHandle;
end;
end);
tool.Unequipped:Connect(function(): ()
if (VMHold.IsPlaying) then
VMHold:Stop();
equipped = false;
local clonedTool = VMToolHandle:WaitForChild(tool.Name..SUFFIX);
clonedTool:Destroy();
local motor6d = VMToolHandle:WaitForChild(lArrow..tool.Name..SUFFIX..rArrow);
motor6d:Destroy();
end;
end);
return PREFIX..tool.Name;
end;
RunService.RenderStepped:Connect(function()
if (Player.Character.Humanoid.Health == 0) then
if (Camera:FindFirstChild("ViewModel")) then
ViewModel:Destroy()
end
end
if Camera:FindFirstChild("ViewModel") ~= nil then
ViewModel:PivotTo(Camera.CFrame * CFrame.new(.025, -2, -.3) * CFrame.Angles(0.3, 0, 0))
end
if (Character:FindFirstChildWhichIsA("Humanoid").MoveDirection.Magnitude > 0) then
if not (VMBobble.IsPlaying) then
VMBobble:Play();
end;
else
if (VMBobble.IsPlaying) then
VMBobble:Stop();
end;
end;
end)
Player.Backpack.ChildAdded:Connect(function(child: Instance)
if child:IsA("Tool") then
local test = toolCheck(child);
end;
end);
for i: number, v: Tool in ipairs(Player.Backpack:GetChildren()) do
if (v:IsA("Tool")) then
local test = toolCheck(v);
end;
end;
Obviously this code was written to satisfy the “Candle” tool (for tests).
You can modify this however you want!
Again, thank you so much for reading, and the ones who helped me!
Thank you