Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
1

How to move a GUI to the Sun's position?

Asked by 8 years ago

Tried this, but it's trash

cam = workspace.CurrentCamera
while wait() do

sunDirection = game.Lighting:GetSunDirection()
camDirection = cam.CoordinateFrame.lookVector

sunDirectionXZPlane = Vector3.new(sunDirection.X,0,sunDirection.Z).unit

camDirectionXZPlane = Vector3.new(camDirection.X,0,camDirection.Z).unit
camDirectionYPlane = Vector3.new(sunDirection.X,camDirection.Y,sunDirection.Z).unit

angleLeftRight = math.acos(camDirectionXZPlane:Dot(sunDirectionXZPlane))
angleUpDown = math.acos(camDirectionYPlane:Dot(sunDirection))

angle = math.acos(camDirection:Dot(sunDirection))

print(angle)
script.Parent.Position = UDim2.new(angleLeftRight+0.5,-25,angleUpDown+0.5,-25)
end

1 answer

Log in to vote
3
Answered by
BlueTaslem 18071 Moderation Voter Administrator Community Moderator Super Administrator
8 years ago

You don't need to do the math yourself (you'd rather not because of field of view and unknown screen ratio).

The Camera object provides a helpful WorldToScreenPoint method.

local sunPosition = camera.CoordinateFrame.p
    + game.Lighting:GetSunDirection() * 10
-- get the position of the sun in the world.
-- how far away it is (the 10) shouldn't really matter.

local screenPosition = camera:WorldToScreenPoint( sunPosition )
script.Parent.Position = UDim2.new(0, screenPosition.x, 0, screenPosition.y)

And that's all there is to it! (EDIT: tested it, it works)


If you're curious about the math behind WorldToScreenPoint, it works something like this:

Take a point in the world, move it into the object space of the camera, then divide by depth:

local p = camera.CoordinateFrame:PointToObjectSpace( worldPoint )
p = p / p.z

Now you have to scale to fit the FieldOfView in the height of the screen.

local maxY = math.tan( FieldOfView / 2 )
p = p / maxY

Now you have to multiply by the screen size and center.


The PointToObjectSpace calculation works like this:

local cam = camera.CoordinateFrame
D = worldPoint - cam.p
local fwd, right, up = cam:VectorToWorldSpace(0, 0, -1), ...

local p = Vector3.new( right:Dot(D), up:Dot(D), fwd:Dot(D) )
Ad

Answer this question