2D Camera Lock-On Issues

I’ve been having issues with this 2D lock-on script. Whenever the player approaches the target, it spins around and whenever the player goes to the other side of the target the camera switches sides. What I’m trying to achieve is the player character continuing to walk in the direction they’re going after reaching the target instead of continuously walking towards the target after reaching them. So far, I couldn’t come up with any solutions.

local inbetweenPart = create('Part', {
	CanCollide = false,
	Size = Vector3.new(1, 1, 1),
	Transparency = 1,
	CFrame = Character.Torso.CFrame,
	Anchored = true,
	Parent = Camera
})

local function LockOn()
	if isLockedOn == true then
		local CharHRP = Character.HumanoidRootPart
		local plrHumanoidRP = isPlayerHum.Parent.HumanoidRootPart
		
		CharHRP.CFrame = CFrame.new(CharHRP.Position, 
			Vector3.new(plrHumanoidRP.Position.X, CharHRP.Position.Y, plrHumanoidRP.Position.Z))
		
		CharHRP.Lock.MaxTorque = Vector3.new(0, math.huge, 0)
		CharHRP.Lock.D = 13e3
		CharHRP.Lock.P = 11^8
		CharHRP.Lock.CFrame = CFrame.new(CharHRP.Position, 
			Vector3.new(plrHumanoidRP.Position.X, CharHRP.Position.Y, plrHumanoidRP.Position.Z))
		
		if cameraIs == "2D" then
			local inbetween = (CharHRP.Position + plrHumanoidRP.Position)/2
			local indist = (CharHRP.Position - plrHumanoidRP.Position).magnitude
			
			inbetweenPart.CFrame = inbetweenPart.CFrame:Lerp(CFrame.new(inbetween + Vector3.new(0, 2, 0), 
				CharHRP.Position + Vector3.new(0, 2, 0)) 
				* CFrame.Angles(0, math.pi * 1.5, 0), .215)
			
			local reverseX, _, reverseZ = inbetweenPart.CFrame:ToEulerAnglesXYZ()
					
			Camera.CFrame = inbetweenPart.CFrame
				* CFrame.new(0, 0, 11 + indist/3)
				* CFrame.Angles(0, 0, -(reverseX + reverseZ))
       end
    end
end

RunService.RenderStepped:Connect(LockOn)
3 Likes

Consider using CollisionGroups to make the player not collide with the dummy. Also try to lock the character’s Y rotation by setting it back to default value whenever it changes.

The player doesn’t collide with the dummy at all. Also, the character always has to be facing the dummy. The camera is offset from a part that is between the two, but always flips whenever the player goes on the other side of the dummy.

If you’re still looking for a solution to this issue, you can check if the player is within a certain distance of the target then switch the factor by which you multiply the CFrame.

This would look something like this:

local turningRatio, turningLine, turningPoint = 3/2, nil, nil -- to be place outside the loop

 -----------
 -----------

if cameraIs == "2D" then

local inbetween = (CharHRP.Position + plrHumanoidRP.Position)/2
local distVector = CharHRP.Position - plrHumanoidRP.Position
local indist = (distVector).magnitude
		
inbetweenPart.CFrame = inbetweenPart.CFrame:Lerp(CFrame.new(inbetween + Vector3.new(0, 2, 0), 
	CharHRP.Position + Vector3.new(0, 2, 0)) 
	* CFrame.Angles(0, math.pi * turningRatio, 0), .215) -- turning ratio applied here
		
local reverseX, _, reverseZ = inbetweenPart.CFrame:ToEulerAnglesXYZ()
				
local cameraCFrame = inbetweenPart.CFrame
	* CFrame.new(0, 0, 11 + indist/3)
	* CFrame.Angles(0, 0, -(reverseX + reverseZ))

if turningPoint and turningLine then	
	cameraCFrame = turningPoint

	-- as soon as the player goes past the target switch the ratio
	if turningLine and distVector.Unit:Dot(turningLine) < 0 then 
		turningLine = distVector.Unit
		turningRatio = 2 - turningRatio
	end
					
	if indist > TurnRange then
		turningPoint = nil
		turningLine = nil
	end			
elseif indist <= TurnRange then -- set turn range to whatever u want it to be
	turningPoint = cameraCFrame
	turningLine = distVector.Unit
end	

Camera.CFrame = cameraCFrame

end

This can be probably be reduced to fewer lines but I haven’t thought about it too much.

1 Like