Hi guys.
I am trying to replicate the effect in this post right here:
As you can see, the camera is moving, but the crosshair seems to just ignore its movement, and lock itself in world space(While still allowing camera movement from the player’s mouse).
My setup is basic camera bobbing, which i want to be ignored by the crosshair. The most logical solution for me, is:
-
Apply the bobbing to our camera as we would normally
camera.CFrame *= currentBobCFrame -
Make a variable called “cleanCFrame” where we store the camera CFrame WITHOUT the bobbing applied. We do that by simply doing
cleanCFrame = camera.CFrame * currentBobCFrame:Inverse() -
We get the cleanCFrame’s lookvector. We create a world position somewhere along it, and position the UI element on it via
:WorldToViewportPoint()
This all seems to work technically, but in practice i just cannot get it to work. This is the code, which i am currently using.
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local player = Players.LocalPlayer
local camera = workspace.CurrentCamera
local playerGui = player:WaitForChild("PlayerGui")
local testUI = playerGui:WaitForChild("TestUI")
local frame = testUI:WaitForChild("Frame")
local BOB_SPEED = 5.5
local BOB_AMOUNT_Y = 0.08
local BOB_AMOUNT_X = 0.1
local BOB_TILT_Z = 1.5
local BOB_TILT_X = 0.8
local LERP_ALPHA = 0.15
local REFERENCE_SPEED = 16
local INTENSITY_EXPONENT = 1.6
local MAX_SPEED_SCALE = 3
local bobTime = 0
local currentBobCFrame = CFrame.new()
local targetBobCFrame = CFrame.new()
local function getCharacterParts()
local character = player.Character
if not character then return nil, nil end
local humanoid = character:FindFirstChildOfClass("Humanoid")
local rootPart = character:FindFirstChild("HumanoidRootPart")
return humanoid, rootPart
end
local cleancframe
RunService:BindToRenderStep("WalkBob", Enum.RenderPriority.Camera.Value + 1, function(deltaTime)
local humanoid, rootPart = getCharacterParts()
if not humanoid or not rootPart or camera.CameraType ~= Enum.CameraType.Custom then
targetBobCFrame = CFrame.new()
currentBobCFrame = currentBobCFrame:Lerp(targetBobCFrame, LERP_ALPHA)
camera.CFrame = camera.CFrame * currentBobCFrame
return
end
local velocity = rootPart.AssemblyLinearVelocity
local horizontalSpeed = Vector3.new(velocity.X, 0, velocity.Z).Magnitude
local isMoving = horizontalSpeed > 0.5
local isGrounded = humanoid.FloorMaterial ~= Enum.Material.Air
if isMoving and isGrounded then
local rawScale = horizontalSpeed / REFERENCE_SPEED
local speedScale = math.clamp(rawScale ^ INTENSITY_EXPONENT, 0, MAX_SPEED_SCALE)
bobTime = bobTime + deltaTime * BOB_SPEED * speedScale
local bobX = math.sin(bobTime) * BOB_AMOUNT_X * speedScale
local bobY = math.sin(bobTime * 2) * 0.5 * BOB_AMOUNT_Y * speedScale
local tiltZ = math.cos(bobTime) * BOB_TILT_Z * speedScale
local tiltX = math.cos(bobTime * 2) * BOB_TILT_X * speedScale
targetBobCFrame =
CFrame.Angles(math.rad(tiltX) / 30, math.rad(tiltX) / 18, math.rad(tiltZ) / 1.5)
else
bobTime = 0
targetBobCFrame = CFrame.new()
end
----------------------------------IMPORTANT PART FOR DEVFORUM------------------------------------------
currentBobCFrame = currentBobCFrame:Lerp(targetBobCFrame, LERP_ALPHA)
camera.CFrame = camera.CFrame * currentBobCFrame
cleancframe = camera.CFrame * currentBobCFrame:Inverse()
local aheadPoint = cleancframe.Position + cleancframe.LookVector * 8
local screenPos, onScreen = camera:WorldToViewportPoint(aheadPoint)
frame.Visible = onScreen
frame.Position = UDim2.fromOffset(screenPos.X, screenPos.Y)
----------------------------------------------------------------------------
end)
game:GetService("ScriptContext")
player.CharacterRemoving:Connect(function()
bobTime = 0
currentBobCFrame = CFrame.new()
end)
And this is the problematic section:
----------------------------------IMPORTANT PART FOR DEVFORUM------------------------------------------
currentBobCFrame = currentBobCFrame:Lerp(targetBobCFrame, LERP_ALPHA)
camera.CFrame = camera.CFrame * currentBobCFrame
cleancframe = camera.CFrame * currentBobCFrame:Inverse()
local aheadPoint = cleancframe.Position + cleancframe.LookVector * 8
local screenPos, onScreen = camera:WorldToViewportPoint(aheadPoint)
frame.Visible = onScreen
frame.Position = UDim2.fromOffset(screenPos.X, screenPos.Y)
----------------------------------------------------------------------------
Please if anyone knows how to achive this crosshair effect, any help is appreciated!!!