Goal
Right now I am designing a first person shooter game. The character model I am using is R15. I want the right arm of the player to follow the mouse. The only movement that the right arm will do is moving up and down, but never side to side (because apparently, if the player tries to look left and right, the whole character model rotates).
Attempted Solutions
Right now, I have used various solutions, but it always ends in failure. Here’s a list of them:
- Using other solution in the forum where it all applies to third-person-shooter. It had very weird behaviours when implementing that.
- Adjusting the C0 of the upper right arm, but it ends up making the whole right arm goes missing.
- Adding animation to the right arm, but barely works. I set the animation to rotate the upper right arm by 1 degree and only plays the animation if the next arm orientation is higher or lower than the previous one.
Local Script
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Events = ReplicatedStorage:FindFirstChild("Events")
local MouseFollowFunctionRemoteEvent = Events.MouseFollowFunctionRemoteEvent
local currentCamera = workspace.CurrentCamera
local Player = Players.LocalPlayer
local rayOriginVector
local rayDirection
local raycastResult
local hitPart
local opposite
local adjacent
local raycastResultVector
local angle
local raycastParams = RaycastParams.new()
raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
raycastParams.FilterDescendantsInstances = {Player.Character}
local function calculateDistance(finalPoint, startingPoint)
return finalPoint - startingPoint
end
local function calculateAngle(opposite, adjacent)
return math.atan2(opposite, adjacent)
end
local function checkMouseLocation()
rayOriginVector = Player.Character:WaitForChild("Head").Position
rayDirection = currentCamera.CFrame.LookVector * 1000
raycastResult = workspace:Raycast(rayOriginVector, rayDirection , raycastParams)
if raycastResult then
raycastResultVector = raycastResult.Position
adjacent = calculateDistance(raycastResultVector.X, rayOriginVector.X)
opposite = calculateDistance(raycastResultVector.Z, rayOriginVector.Z)
angle = calculateAngle(opposite, adjacent)
MouseFollowFunctionRemoteEvent:FireServer(angle)
end
end
RunService.RenderStepped:Connect(checkMouseLocation)
Server Script
local MouseFollowFunctionRemoteEvent = game:GetService("ReplicatedStorage").Events.MouseFollowFunctionRemoteEvent
MouseFollowFunctionRemoteEvent.OnServerEvent:Connect(function(Player, angle)
local Character = Player.Character
local Humanoid = Character.Humanoid
local Animator = Humanoid:FindFirstChildOfClass("Animator")
local RightUpperArm = Character.RightUpperArm
local RightUpperArmOrientation = RightUpperArm.Orientation
local Animation = Instance.new("Animation")
local animationTrack
local Tool = Character:FindFirstChildWhichIsA("Tool")
if (angle > RightUpperArmOrientation.X) and Tool then
Animation.AnimationId = "rbxassetid://10186687345"
animationTrack = Animator:LoadAnimation(Animation)
animationTrack:Play()
end
if (angle < RightUpperArmOrientation.X) and Tool then
Animation.AnimationId = "rbxassetid://10186692841"
animationTrack = Animator:LoadAnimation(Animation)
animationTrack:Play()
end
end)
The code above is for the third solution. Feel free to adjust it!