I have a fixed "Over-The-Shoulder" camera system, and i want to aim the gun where the camera is pointing at.
My best bet was to use the CFrame.Rotation
, but it didn't work so well.
That's when i tried, getting the angles from the camera every time it changed, using: workspace.CurrentCamera.Change:Connect
, and then applying the rotation vectors (Camera.CFrame.Rotation
) to the entire of the player's body.
Then i've tried implementing Inverse Kinematics, to my code, but honestly, i could not stand copied code that i don't know how it works, so i scraped everything that i've copied.
Everything that i found about IK (Inverse Kinematics), was little to no useful, since no one really did what i want to achieve.
I don't know if it's achievable or not, but, if it helps, here is the state of my code, and an example image.
-- Script for controling the player camera.
-- Used for aiming in general.
-- Game global table
local globals = require(game.ReplicatedStorage.globalStates)
-- Normal services
local UserInputService, runService = game:GetService("UserInputService"), game:GetService("RunService")
local LocalPlayer = game:GetService("Players").LocalPlayer -- Get client's player
local Camera = game:GetService("Workspace").CurrentCamera -- Player's camera(?)
local TweenService = game:GetService("TweenService")
local PlayerMouse = LocalPlayer:GetMouse()
local DEF_FOV = 70
local AIM_FOV = 35
local AIM_SENS = 0.3
local AIM_DURR_TIME = 0.15
local xAngle, yAngle = 0, 0
local cameraOffset = Vector3.new(3.5, 0, 7.5)
local tweenIn = TweenService:Create(Camera, TweenInfo.new(AIM_DURR_TIME), {FieldOfView = AIM_FOV})
local tweenOut = TweenService:Create(Camera, TweenInfo.new(AIM_DURR_TIME), {FieldOfView = DEF_FOV})
-- TODO: Fix bug when player changes camera mode in menu
wait(1)
Camera.CameraType = Enum.CameraType.Scriptable -- Used for creating custom behavior
UserInputService.MouseBehavior = Enum.MouseBehavior.LockCenter -- Lock the cursor
PlayerMouse.Icon = "rbxassetid://9095360160" -- Set dot crosshair
UserInputService.InputChanged:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseMovement then
xAngle = xAngle - input.Delta.x * 0.4
yAngle = math.clamp(yAngle - input.Delta.y * 0.4, -80, 80)
end
end)
-- This will run every frame
runService.RenderStepped:Connect(function()
local Character = LocalPlayer.Character
local Root = LocalPlayer.Character:FindFirstChild("HumanoidRootPart")
if Character and Root then
local startCFrame = CFrame.new((Root.CFrame.p + Vector3.new(0,2,0))) * CFrame.Angles(0, math.rad(xAngle), 0) * CFrame.Angles(math.rad(yAngle), 0, 0)
local cameraCFrame = startCFrame + startCFrame:vectorToWorldSpace(Vector3.new(cameraOffset.X,cameraOffset.Y,cameraOffset.Z))
local cameraFocus = startCFrame + startCFrame:vectorToWorldSpace(Vector3.new(cameraOffset.X,cameraOffset.Y,-50000))
Camera.CFrame = CFrame.new(cameraCFrame.p ,cameraFocus.p)
end
end)
-- Only 'aim' if TOGGLE_MOUSE and TOGGLE_MOUSE are false
PlayerMouse.Button2Down:Connect(function()
if globals.TOGGLE_MOUSE == false and globals.IS_PLAYER_AIMING == false then
tweenIn:Play()
globals.IS_PLAYER_AIMING = true
else
print("Could not start player aim")
end
end)
PlayerMouse.Button2Up:Connect(function()
tweenOut:Play()
globals.IS_PLAYER_AIMING = false
end)