I’ve been trying to achieve a top-down view for a galaxy map which I’ve done using another person’s script. However, I’ve been trying to tween the camera to a star’s position on the map but the camera doesn’t follow any linear movement like expected. Instead, it rotates and spins around before returning to the original camera position (before the tween). I’ve found no possible fix for this, at least from what I understand from the documentation
Camera Script
local run = game:GetService("RunService")
local uis = game:GetService("UserInputService")
local TweenService = game:GetService("TweenService")
local plr = game:GetService("Players").LocalPlayer
local char = plr.Character or plr.CharacterAdded:Wait()
local hrp = char:WaitForChild("HumanoidRootPart")
char:MoveTo(Vector3.new(0, -50, 0))
hrp.Anchored = true
local mouse = plr:GetMouse()
local camera = workspace.CurrentCamera
camera.FieldOfView = 5
plr.CameraMinZoomDistance = 3
local clamp = math.clamp
local canDrag = script:GetAttribute("canDrag")
local playerSetup = script:GetAttribute("playerSetup")
script.AttributeChanged:Connect(function()
canDrag = script:GetAttribute("canDrag")
end)
script.AttributeChanged:Connect(function()
playerSetup = script:GetAttribute("playerSetup")
end)
local speed = 7 -- Speed when dragging
local lockMouse = false -- locks mouse when dragging
local origin = CFrame.lookAt(Vector3.new(0, 250 ,0), Vector3.new()) -- Where the camera will start
local moveArea = Vector2.new(125, 125) -- Clamp area
local zAngle = CFrame.Angles(0,0,math.rad(0))
local yAngle = CFrame.Angles(0, math.rad(0), 0)
local xAngle = CFrame.Angles(math.rad(0),0,0)
local scrollable = true -- Scrolling will zoom the camera
local scrollMin = 0 -- Scrolling minimum (studs)
local scrollMax = 2400 -- Scrolling maximum (studs)
local scrollDelta = 50 -- How much movement when scrolling
local targetMoved = Vector2.zero -- How much the camera has moved
local targetScroll = clamp(10 ,scrollMin, scrollMax) -- How much the user has scrolled
playerSetup = true
local dragging = false
local oldMousePos = Vector2.zero
if uis.MouseEnabled then
mouse.Button1Down:Connect(function()
dragging = true
oldMousePos = uis:GetMouseLocation()
end)
mouse.Button1Up:Connect(function()
dragging = false
uis.MouseBehavior = Enum.MouseBehavior.Default
end)
mouse.Button2Down:Connect(function()
dragging = true
oldMousePos = uis:GetMouseLocation()
end)
mouse.Button2Up:Connect(function()
dragging = false
uis.MouseBehavior = Enum.MouseBehavior.Default
end)
mouse.Move:Connect(function()
if dragging then
if lockMouse then
uis.MouseBehavior = Enum.MouseBehavior.LockCurrentPosition
targetMoved += uis:GetMouseDelta()*speed/60
else
targetMoved += (uis:GetMouseLocation() - oldMousePos)*speed/60
oldMousePos = uis:GetMouseLocation()
end
targetMoved = Vector2.new(clamp(targetMoved.X, -moveArea.X, moveArea.X),clamp(targetMoved.Y, -moveArea.y, moveArea.Y))
end
end)
mouse.WheelForward:Connect(function()
if scrollable then
targetScroll = targetScroll - scrollDelta > scrollMin and targetScroll - scrollDelta or scrollMin
end
end)
mouse.WheelBackward:Connect(function()
if scrollable then
targetScroll = targetScroll + scrollDelta > scrollMax and scrollMax or targetScroll + scrollDelta
end
end)
elseif uis.TouchEnabled then
uis.InputBegan:Connect(function(input, gp)
if gp then return end
local pos = Vector2.new(input.Position.X,input.Position.Y)
oldMousePos = pos
end)
uis.InputChanged:Connect(function(input)
local pos = Vector2.new(input.Position.X,input.Position.Y)
targetMoved += (pos - oldMousePos)*speed/60
targetMoved = Vector2.new(clamp(targetMoved.X, -moveArea.X, moveArea.X),clamp(targetMoved.Y, -moveArea.y, moveArea.Y))
oldMousePos = pos
end)
end
local scroll = targetScroll
local moved = targetMoved
local event = game:GetService("ReplicatedStorage"):WaitForChild("CameraPositionUpdater")
local function cameraDrag(dt)
if not canDrag then return end
scroll = scroll + (targetScroll - scroll)*dt*scrollDelta
moved = moved:Lerp(targetMoved,dt*speed)
camera.CFrame = origin * zAngle * CFrame.new(-moved.X, moved.Y, scroll) * xAngle * yAngle
end
run:BindToRenderStep("camera", Enum.RenderPriority.Camera.Value, cameraDrag)
event.Event:Connect(function(boolean)
if boolean == true then
run:UnbindFromRenderStep("camera")
else
run:BindToRenderStep("camera", Enum.RenderPriority.Camera.Value, cameraDrag)
end
end)
Click Handler
local TweenService = game:GetService("TweenService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local LocalPlayer = Players.LocalPlayer
local mouse = LocalPlayer:GetMouse()
local camera = game.Workspace.CurrentCamera
local cameraEvent = ReplicatedStorage:WaitForChild("CameraPositionUpdater")
local starHighlighter = ReplicatedStorage:WaitForChild("StarHighlighter")
local starGui = LocalPlayer.PlayerGui:WaitForChild("StarGui")
local starHighlightTweenInfo = TweenInfo.new(5, Enum.EasingStyle.Linear, Enum.EasingDirection.In, -1, false)
local starHighlightTween = TweenService:Create(starHighlighter, starHighlightTweenInfo, { Orientation = Vector3.new(0, 360, 0) })
local starCurrentedSelected = false
local function starHoverEnter(star)
if starCurrentedSelected == true then
starCurrentedSelected = false
end
starHighlighter.Parent = star
starHighlighter.Position = Vector3.new(star.Position.x, star.Position.y - 0.4, star.Position.z)
starHighlightTween:Play()
end
local function starHoverLeave()
if starCurrentedSelected == false then
starHighlighter.Parent = ReplicatedStorage
starHighlightTween:Pause()
end
end
local playerSetupScript = script.Parent:WaitForChild("PlayerSetup")
local function starSelect(star)
local highligherPosition = Vector3.new(star.Position.x, star.Position.y - 0.4, star.Position.z)
starHighlighter.Parent = star
starHighlightTween:Play()
starCurrentedSelected = true
local cameraTweenInfo = TweenInfo.new(0.75, Enum.EasingStyle.Linear, Enum.EasingDirection.In)
local cameraTween = TweenService:Create(camera, cameraTweenInfo, { CFrame = CFrame.new(star.Position.x, 250, star.Position.z)})
cameraEvent:Fire(true)
cameraTween:Play()
cameraTween.Completed:Connect(function()
cameraEvent:Fire(false)
end)
end
mouse.Button1Down:Connect(function()
if mouse.Target then
if not mouse.Target:FindFirstChild("ClickDetector") then
starCurrentedSelected = false
starHighlighter.Parent = ReplicatedStorage
starHighlightTween:Pause()
end
end
end)
for _, star in pairs(game.Workspace.Stars:GetChildren()) do
local clickDetectorPart = star:WaitForChild("StarClickDetector")
local ClickDetector = clickDetectorPart:WaitForChild("ClickDetector")
if ClickDetector then
ClickDetector.MouseClick:Connect(function()
starSelect(star)
end)
ClickDetector.MouseHoverEnter:Connect(function()
starHoverEnter(star)
end)
ClickDetector.MouseHoverLeave:Connect(function()
starHoverLeave()
end)
end
end