Camera offset throws off player movement

Found a similar post 3 years ago that never got solved, exact same problem as him with weird spirals

similar code, i just use lerp to look at the midpoint and tween in case i need to add an offset

i never hold w or s in the video

					local function LockOn()
						humRP.CFrame = CFrame.new(humRP.Position,Vector3.new(Target.RootPart.Position.X, humRP.Position.Y, Target.RootPart.Position.Z))
						game:GetService("TweenService"):Create(camera, TweenInfo.new(0.0625, Enum.EasingStyle.Quad, Enum.EasingDirection.InOut), {CFrame = CFrame.new((humRP.CFrame * Vector3.new(5, 2, 7.5)),humRP.Position:Lerp(Target.Head.Position, 0.5))}):Play()
						local health = Target.Hum.Health
						local f = health/100
						--otherHP.Adornee = Target
						--otherHPFrame:TweenSize(UDim2.new(f,0,1,0),"Out","Quad",0.25)
					end
					game:GetService("RunService"):BindToRenderStep("LockOn", Enum.RenderPriority.Camera.Value + 1, LockOn)

As you said you will need an offset to the movement vector opposite.

I have done some research into the default player module, the camera relative to the movement is done here. I’m guessing if you can somehow insert the camera CFrame using CFrame.lookAt() it will always be perp

function ControlModule:calculateRawMoveVector(humanoid: Humanoid, cameraRelativeMoveVector: Vector3): Vector3
	--Blabla a lot of other code for VR controls or joystick

--The important below which prints with default key board controls
	local c, s
--Modify cameraCFrame here such that it is always perpendicular to the target enemy
--Add this line to replace the camera CFrame for recalculation purposes
local cameraCFrame = CFrame.lookAt(humRP, targetCharacterPosition) --Find a way to get targetCharacterPosition in this function

--Below is the default code, it is complex and doesn't matter as we know the default movement behavior (move right = move right in camera.CFrame.RightVector)
	local _, _, _, R00, R01, R02, _, _, R12, _, _, R22 = cameraCFrame:GetComponents()
	if R12 < 1 and R12 > -1 then
		-- X and Z components from back vector.
		c = R22
		s = R02
	else
		-- In this case the camera is looking straight up or straight down.
		-- Use X components from right and up vectors.
		c = R00
		s = -R01*math.sign(R12)
	end
	local norm = math.sqrt(c*c + s*s)
	print("Returning")
	return Vector3.new(
		(c*cameraRelativeMoveVector.X + s*cameraRelativeMoveVector.Z)/norm,
		0,
		(c*cameraRelativeMoveVector.Z - s*cameraRelativeMoveVector.X)/norm
	)
end

Nvm got really interested in the problem. Here is a proof of concept local script which forks over the player module and changes the function

local ControlModule = require(game.StarterPlayer.StarterPlayerScripts.PlayerModule):GetControls()

local VRService = game:GetService("VRService")
local UserInputService = game:GetService("UserInputService")

local target = workspace.Steve --replace target to your liking

local function getGamepadRightThumbstickPosition(): Vector3
	local state = UserInputService:GetGamepadState(Enum.UserInputType.Gamepad1)
	for _, input in pairs(state) do
		if input.KeyCode == Enum.KeyCode.Thumbstick2 then
			return input.Position
		end
	end
	return Vector3.new(0,0,0)
end

function ControlModule:calculateRawMoveVector(humanoid: Humanoid, cameraRelativeMoveVector: Vector3): Vector3
	local camera = workspace.CurrentCamera
	if not camera then
		return cameraRelativeMoveVector
	end
	local cameraCFrame = camera.CFrame
	cameraCFrame = CFrame.lookAt(humanoid.RootPart.Position, target.Position)
	
	if VRService.VREnabled and humanoid.RootPart then
		local vrFrame = VRService:GetUserCFrame(Enum.UserCFrame.Head)

		vrFrame = self:GetEstimatedVRTorsoFrame()

		-- movement relative to VR frustum
		local cameraDelta = camera.Focus.Position - cameraCFrame.Position
		if cameraDelta.Magnitude < 3 then -- "nearly" first person
			cameraCFrame = cameraCFrame * vrFrame
		else
			cameraCFrame = camera.CFrame * (vrFrame.Rotation + vrFrame.Position * camera.HeadScale)
		end
	end

	if humanoid:GetState() == Enum.HumanoidStateType.Swimming then	
		if VRService.VREnabled then
			cameraRelativeMoveVector = Vector3.new(cameraRelativeMoveVector.X, 0, cameraRelativeMoveVector.Z)
			if cameraRelativeMoveVector.Magnitude < 0.01 then
				return Vector3.zero
			end

			local pitch = -getGamepadRightThumbstickPosition().Y * math.rad(80)
			local yawAngle = math.atan2(-cameraRelativeMoveVector.X, -cameraRelativeMoveVector.Z)
			local _, cameraYaw, _ = cameraCFrame:ToEulerAnglesYXZ()
			yawAngle += cameraYaw
			local movementCFrame = CFrame.fromEulerAnglesYXZ(pitch, yawAngle, 0)
			return movementCFrame.LookVector
		else
			return cameraCFrame:VectorToWorldSpace(cameraRelativeMoveVector)
		end
	end

	local c, s
	local _, _, _, R00, R01, R02, _, _, R12, _, _, R22 = cameraCFrame:GetComponents()
	if R12 < 1 and R12 > -1 then
		-- X and Z components from back vector.
		c = R22
		s = R02
	else
		-- In this case the camera is looking straight up or straight down.
		-- Use X components from right and up vectors.
		c = R00
		s = -R01*math.sign(R12)
	end
	local norm = math.sqrt(c*c + s*s)
	return Vector3.new(
		(c*cameraRelativeMoveVector.X + s*cameraRelativeMoveVector.Z)/norm,
		0,
		(c*cameraRelativeMoveVector.Z - s*cameraRelativeMoveVector.X)/norm
	)
end
1 Like

just maybe not so rly quickly but could you implement it to something like this please, because i want to be able to turn it off and on

--pretty bad code, i'll fix it later

local plr = game:GetService("Players").LocalPlayer
local char = plr.Character or plr.CharacterAdded:Wait()
local hum = char:FindFirstChildOfClass("Humanoid")
local humRP = hum.RootPart

--local otherHP = plr.PlayerGui.OtherHPBarGui
--otherHPFrame = otherHP.HealthbarFrame.HealthBar

local uis = game:GetService("UserInputService")

hum:SetAttribute("Locked", false)

local function getTarget(input: InputObject, gameProcessedEvent: boolean)
	if gameProcessedEvent then return end

	if input.UserInputType == Enum.UserInputType.MouseButton3 then
		local camera = workspace.CurrentCamera

		local length = 66.6667

		local raycastParams = RaycastParams.new()
		raycastParams.FilterDescendantsInstances = {char}
		raycastParams.FilterType = Enum.RaycastFilterType.Exclude
		raycastParams.IgnoreWater = true

		local raycastResult = workspace:Raycast(camera.CFrame.Position, camera.CFrame.LookVector * length, raycastParams)

		if raycastResult.Instance.Parent:IsA("Model") then
			if raycastResult.Instance.Parent:FindFirstChildOfClass("Humanoid") then
				local Target = {
					["Head"] = raycastResult.Instance.Parent.Head,
					["Model"] = raycastResult.Instance.Parent,
					["Hum"] =  raycastResult.Instance.Parent:FindFirstChildOfClass("Humanoid"),
					["RootPart"] =  raycastResult.Instance.Parent:FindFirstChildOfClass("Humanoid").RootPart,
				}

				if hum:GetAttribute("Locked") == false then
					local mouse = game:GetService("Players").LocalPlayer:GetMouse()

					--otherHP.Enabled = true
					local function LockOn()
						humRP.CFrame = CFrame.new(humRP.Position,Vector3.new(Target.RootPart.Position.X, humRP.Position.Y, Target.RootPart.Position.Z))
						game:GetService("TweenService"):Create(camera, TweenInfo.new(0.0625, Enum.EasingStyle.Quad, Enum.EasingDirection.InOut), {CFrame = CFrame.new((humRP.CFrame * Vector3.new(5, 2, 7.5)),humRP.Position:Lerp(Target.Head.Position, 0.5))}):Play()
						local health = Target.Hum.Health
						local f = health/100
						--otherHP.Adornee = Target
						--otherHPFrame:TweenSize(UDim2.new(f,0,1,0),"Out","Quad",0.25)
					end
					game:GetService("RunService"):BindToRenderStep("LockOn", Enum.RenderPriority.Camera.Value + 1, LockOn)
					repeat
						task.wait()
						camera.CameraType = Enum.CameraType.Scriptable
					until
					camera.CameraType == Enum.CameraType.Scriptable
					hum:SetAttribute("Locked", true)
					print("alpha")
				elseif hum:GetAttribute("Locked") == true or hum.Died or Target.Hum.Died then
					--ill do this later
					hum:SetAttribute("Locked", false)
				end
			else
				print("nah")
			end
		end
	end
end

uis.InputEnded:Connect(function(input: InputObject, gameProcessedEvent: boolean) 
	getTarget(input, gameProcessedEvent)
end)```

nvm made unlocking myself dont reply

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.