How would I make a dynamic top down view camera?

I don’t know what that is :stuck_out_tongue:


One way you could improve your script tho:

Instead of using Parts to represent CFrames... just use CFrames.

This…

local LAM=game.Workspace.LookAtMe
local FC=game.Workspace.FakeCamera
local MP=game.Workspace.MouseP
mouse.TargetFilter = MP

… becomes this:

local LAM, FC, MP

And this:

MP.CFrame = CFrame.new(mouse.Hit.p) --- where mouse points "MouseP"
LAM.CFrame = playerrootpart.CFrame:Lerp(MP.CFrame, 0.2) --- white brick in the middle "LookAtMe"
FC.CFrame = CFrame.new (LAM.Position + offset) --- part that hovers above white brick "FakeCamera"

--- camera stares at "LookAtMe" from above thanks to the flying "FakeCamera"
camera.CFrame = CFrame.new (FC.Position, LAM.Position)

becomes this:

MP = CFrame.new(mouse.Hit.p) --- where mouse points "MouseP"
LAM = playerrootpart.CFrame:Lerp(MP, 0.2) --- white brick in the middle "LookAtMe"
FC = CFrame.new(LAM.p + offset) --- part that hovers above white brick "FakeCamera"

--- camera stares at "LookAtMe" from above thanks to the flying "FakeCamera"
camera.CFrame = CFrame.new(FC.p, LAM.p)

I would also use much more verbose variable names, but that’s just a matter of coding style.

1 Like

Well harder for me, I really wanna try to do it your way, using absolute size and mouse z,x.
Because im really curious how that would work.

1 Like

Oh, right. Something like this?


local DOWN = Vector3.new(0, -1, 0)

local cameraMouseSensitivity = 10
local cameraOffset = Vector3.new(0, 10, 0)

function getMouseScreenPositionCentered()
	return Vector2.new(
		mouse.X - screenGui.AbsoluteSize.X/2,
		mouse.Y - screenGui.AbsoluteSize.Y/2
	)
end

function pixelToFraction(pixelV2)
	--Turns a coordinate in pixels into a coordinate in some fraction of the size of the screen
	return pixelV2 / screenGui.AbsoluteSize
end

function onRenderStep() 	
	if player.Character then
		local rootPart = player.Character.HumanoidRootPart
		
		local mouseScreenPos = pixelToFraction( getMouseScreenPositionCentered() )
		local cameraPos = cameraOffset + Vector3.new(mouseScreenPos.X, mouseScreenPos.Y) * cameraMouseSensitivity

		camera.CFrame = CFrame.new(cameraPos, cameraPos + DOWN)
	end
end
11 Likes

Yes exactly!
but …

  • seems like you forgot to put 0 in
    Vector3.new(mouseScreenPos.X, 0 , mouseScreenPos.Y)

  • and here is a fix for opacity.

	return Vector2.new(
		mouse.Y + ScreenGui.AbsoluteSize.X/2,
		mouse.X - ScreenGui.AbsoluteSize.Y/2)
end 

other than that, great knowledge mine, I didn’t know that you can use vector3 to face a certain direction and those functions that translate mouse movement on-screen is just amazing.

I’m gonna tinker with it some more.

1 Like

Ok, I may have crost the line.


Returning to my opacity fix, it doesn’t work.

I started messing around with everything and figured out that “DOWN” is causing all this trouble. After a while, I found a somewhat working position -
local DOWN = Vector3.new(0, -90, -45)
here is the effect

Aight found a perfect spot and calibrated it.

local offset = Vector3.new(0,25,5.35)
local DOWN = Vector3.new(0, -100, -15)
local cameraMouseSensitivity = 20

If you could somehow rotate “DOWN” a bit counter-clockwise it should give you that perfect top-down view but I didn’t find any other way then to just add an angle to it,
darn thing doesn’t want to move with smaller numbers.

Once Again I can’t express how thankfull I am for your help. :grinning:

1 Like

Do you mean the walking controls stop working? This is because the default character controller uses the camera’s LookVector to determine which horizontal direction corresponds to each movement direction. When the camera is looking straight up/down, there is no horizontal component to the LookVector so there’s no obvious way of figuring out which direction is forwards just from the LookVector…

…except it seems pretty obvious to us what direction the character should move in, it’s just a small flaw in the default character controller that pretty much never comes up when using the default camera controller, because looking straight up or down is impossible (there’s a +85 / -85 degree limit to looking up/down).

Rotating the camera as little as 10^-7 radians was enough to allow normal walking:
local RunS = game:GetService("RunService")

local DOWN = Vector3.new(0, -1, 0)
local MIN_CAM_ANGLE_FOR_WALKING = 10e-7

local player = game.Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local camera = game.Workspace.CurrentCamera

RunS.RenderStepped:Connect(function()
	local cameraPos = character.PrimaryPart.Position + Vector3.new(0, 25, 0)
	camera.CFrame = CFrame.new(
		cameraPos,
		cameraPos + DOWN
	) * CFrame.Angles(MIN_CAM_ANGLE_FOR_WALKING, 0, 0)
end)

You could also fix the default camera controller (test the game and copy it from the PlayerScripts folder), or make your own from scratch that falls back to using the UpVector to figure out direction in case the LookVector is straight up/down.

2 Likes

Goddamn, another well explained trick I had no idea even existed.
Thanks for that Mr. RoBama.

1 Like

Since Robama started sharing this post im gonna leave best version of it here.

-- Made by ThanksRoBama.
-- Explained and polished by Czlopek

local Player = game:GetService("Players").LocalPlayer	
local player = game.Players.LocalPlayer
local mouse = Player:GetMouse()
local camera = workspace.CurrentCamera
local runService = game:GetService("RunService")
local screenGui = game.StarterGui.ScreenGui

-- here is your template for Vector3 axis (x y z)

local Distance = Vector3.new(0,25,0) -- Distance from player
local Direction = Vector3.new(0,-1,0) -- Direction from which camera will be looking at player
local CameraSensitivity = 20 -- change it if you want that camera to lean further (give it a bigger number) 
-- or if want an effect to be more subtle decrease the number. (if you set it as a negative, camera will lean in the opposite direction)

function getMouseScreenPositionCentered() 
	return Vector2.new(
		mouse.X - screenGui.AbsoluteSize.X/2,
		mouse.Y - screenGui.AbsoluteSize.Y/2)
end

function pixelToFraction(pixelV2)
	--Turns a coordinate in pixels into a coordinate in some fraction of the size of the screen
	return pixelV2 / screenGui.AbsoluteSize
end

function onRenderStep() 	
	if player.Character then
		local rootPart = player.Character.HumanoidRootPart
		local playerposition = player.Character.HumanoidRootPart.Position + Vector3.new(0,0,3) -- sometimes camera will be offset to your character, 
		-- thats why you need to add few studs to it so it would stay in middle of the screen.
		local cameraoffset = Distance + playerposition

		local mouseScreenPos = pixelToFraction( getMouseScreenPositionCentered() )
		local Axis = Vector3.new(-mouseScreenPos.Y,0,mouseScreenPos.X)

		local cameraPos = cameraoffset + Axis * CameraSensitivity 


		-- depending on what direction you set the camera to be facing remember that you will need to change it accurately to direction of the camera. 
		-- top down view will have Direction = Vector3.new(0,-1,0) and Axis = Vector3.new(-mouseScreenPos.Y,0,mouseScreenPos.X)
		-- side ways Direction = Vector3.new(0,0,-1) Axis = Vector3.new(mouseScreenPos.X,-mouseScreenPos.Y,0)

		camera.CFrame = CFrame.new(cameraPos, cameraPos + Direction)
	end
end

runService:BindToRenderStep("Camera", Enum.RenderPriority.Camera.Value, onRenderStep)

I strongly suggest using this thing:
Square
it shows what 2 axis you will need to change for it to work.

Script It self should be put in “StarterCharacterScripts”,
this thing.
Nowy obraz mapy bitowej (2)

8 Likes

Hey, so this works great but im having issues with the y axis. If I go up, the Y axis increases however if I go down the Y axis goes down.

https://gyazo.com/a80df34a95db17a723e90f4e93f69ab9

Sorry for taking so long was busy doing real-life stuff,

So scrip I posted was remade for a 2D Side view camera, that’s why one side goes down-up and the other left-right to fix this you need to change variables called

Direction = Vector3.new(0,-1,0)

and

Axis = Vector3.new(-mouseScreenPos.Y,0,mouseScreenPos.X)

to those above.
Settings for cameras were explained in the lower part of the code.

1 Like

Help the camera does not change when i move my mouse…
i’ve put the script into the StarterPlayerScripts but it just acts like a top down view camera.
i am not a scripter so i dont really know what to do.

That’s really unusual, there may be a script in that gun that conflicts with the camera, could you try to use this code in a new fresh place?

I see there was something called “weapon system” in Output, I bet that’s causing the problem.

If its an open sourced module, can you post the link to it? So i can check out whats causing the problem.


nope it does not even work on a fresh new place it just top down view again…
but after putting pistol model in, the camera would start changing when moving with your mouse but then the top down view is not working.

The system it self is in replicate storage, dissable it if anything.

1 Like

Code itself works fine its must be coliding with diffrent scripts in your game.

maybe i needed to do something more than putting the script in ‘‘StarterPlayerScripts’’