I really don’t know how to attempt to do this here…I’m also unaware if there are any free models available that sort of demonstrate this system. Basically what I’m trying to achieve is to point an R15 character’s arm to the mouse’ position, or camera, like in a FPS.
If anybody could steer me in the right direction to achieve this that’d be great, I’m not the best with the math involved in this kind of stuff…
I’m not entirely sure if this requires Inverse Kinematics as the Roblox rig comes with it’s own joints. However, a CFrame is consisted of 2 components: the position and the direction (both Vector3’s). So, all you have to do is simply insert the arm position into the CFrame and then put the direction in.
You may need to do some adjusting but it should look like:
local Vector3dir = playerMouse.Hit -- This is a vector3 hit position from the mouse. You can also use playerMouse.Target.Position
arm.CFrame = CFrame.new(arm.Position,Vector3dir);
EDIT: Use RunService or Mouse.Move to update the Rig’s arm when needed.
I was thinking of writing something like that, but I think OP is talking about FPS arms, like the ones that hold a gun and are always pointing to the camera.
Another way instead of using a viewport is by creating two instances and making something to directly match the camera’s position but be a bit offset. I created a demo for something like this:
wait(1)
local Camera = workspace.CurrentCamera
local Arm1 = Instance.new("Part")
local Arm2 = Instance.new("Part")
function InitArm(Arm, Player, ArmType)
if Arm and Player then
if Arm:IsA("BasePart") and Player:IsA("Player") and Player.Character ~= nil then
Arm.Size = Vector3.new(1,1,2)
local ArmPart = ((Player.Character:FindFirstChild("Humanoid").RigType == Enum.HumanoidRigType.R6 and Player.Character:FindFirstChild(string.format("%s Arm", ArmType))) or (Player.Character:FindFirstChild("Humanoid").RigType == Enum.HumanoidRigType.R15 and Player.Character:FindFirstChild(string.format("%sHand", ArmType))))
Arm.Color = ArmPart.Color
Arm.CanCollide = false
Arm.Anchored = true
Arm.Position = Vector3.new()
Arm.Parent = workspace
game:GetService("RunService").RenderStepped:Connect(function()
if ArmType == "Left" then
Arm.CFrame = ((Camera.CFrame - (Camera.CFrame.RightVector / 1.25)) - (Camera.CFrame.UpVector / 1.25)) + (Camera.CFrame.LookVector * 1.25)
else
Arm.CFrame = ((Camera.CFrame + (Camera.CFrame.RightVector / 1.25)) - (Camera.CFrame.UpVector / 1.25)) + (Camera.CFrame.LookVector * 1.25)
end
end)
else return error("Missing a key part");end
else return error("Missing a key part");end
end
InitArm(Arm1, game.Players.LocalPlayer, "Left")
InitArm(Arm2, game.Players.LocalPlayer, "Right")
Viewport works, but you’ll ultimately end up with worse quality aside from it just being completely redundant. @zQ86’s option is the optimal solution for placing arms on the camera.
In that case, how would you add constraints to make it more realistic without having to do the math? If the CFrame on the arms is being constantly updated and they’re anchored, they can’t be susceptible to constraints.
If it’s an FPS, a Humanoid would work, but yes, essentially. You don’t need to go through the extra work of a custom system like this if you just have an idle animation.
You’re correct. Your viewport suggestion can be easily manipulated to make a simple animation script using CFrame logic, since the CFrame is not constantly updating.
Yes, but as @Stratiz suggested, that would be lacking in quality. (not sure why, hopefully he’ll respond)
If he really wanted to do the work, it would require an IK system for animating as you’d need to account for the rig’s arms. A viewport model would be my solution as it could be changed any way you wanted.
It doesn’t support lighting quality? Maybe we’re thinking of a different type of viewport model. My idea is where arms are welded to a camera brick that is welded to the character’s camera CFrame in first person mode.
local function updateArm(self, key)
if (self[key]) then
local shoulder = self.isR15 and self.viewModel[key.."UpperArm"][key.."Shoulder"] or self.viewModel.Torso[key .. " Shoulder"];
local cf = self.weapon[key].CFrame * CFrame.Angles(math.pi/2, 0, 0) * CFrame.new(0, self.isR15 and 1.5 or 1, 0);
shoulder.C1 = cf:inverse() * shoulder.Part0.CFrame * shoulder.C0;
end
end
Sorry I’m not quite sure how to format code on here but this should help
I think he’s confusing a view model in the Workspace or CurrentCamera (created by the client) for a ViewportFrame. Since the term viewport has been used interchangeably with ViewportFrames for whatever reason ever since the latter’s release, it’s been hard to distinguish what exactly one means when they say viewport.
View(port) models do not diminish quality or incur redundancy. It’s a model that’s created on the client. You’ll rarely have any real performance issues unless you’re making unwise choices with how you’re updating or setting up the model. Don’t worry about this.