How to find mouse position in ViewportFrame?
How to raycast using WorldModel in ViewportFrame?
I want to detect, if player mouse is entering one of this bricks, for example, but how?
How to find mouse position in ViewportFrame?
How to raycast using WorldModel in ViewportFrame?
Use the read only Mouse.x and Mouse.y
How to transform it to 3d World in ViewportFrame?
Actually you can use raycast.
Belive it or not if you put a WorldModel inside a viewport frame you can do some physics related operations.
https://developer.roblox.com/en-us/api-reference/class/WorldModel
Much of the documentation is on there. I haven’t really got any reason to use it but have fun with it ig.
but how? I need to get direction for using raycast, how?
Its basically the same way as how you would raycast with a normal pistol except instead of using the normal CurrentCamera use the Camera for the viewport frame. Also, instead of doing workspace:Raycast(args)
you will be doing ViewportFrame.WorldModel:Raycast(args)
instead.
If you haven’t worked with guns before you have to use the Camera:ScreenPointToRay()
function and insert the mouse position as the arguments and then use the output ray to raycast.
local MouseLocation = UserInputService:GetMouseLocation()
local ViewportRay = Camera:ScreenPointToRay(MouseLocation.X, MouseLocation.Y) -- Camera is the ViewportFrame's camera.
local Result = ViewportFrame.WorldModel:Raycast(ViewportRay.Origin, ViewportRay.Direction * Length)
https://developer.roblox.com/en-us/api-reference/function/Camera/ScreenPointToRay
https://developer.roblox.com/en-us/api-reference/class/UserInputService
https://developer.roblox.com/en-us/api-reference/function/WorldRoot/Raycast
It’s possible that it might not work because I haven’t tested it and I don’t exactly know is ScreenPointToRay accounts for the offset that ViewportFrames have but it’s worth a shot.
Yeah, I know about this, and tested so, but… it doesn’t seem to work
Probably raycasts are not firing correctly. Could I see your code if possible.
-- Debug
local raycastView = Instance.new("Part")
raycastView.Anchored = true
raycastView.CanCollide = false
raycastView.CanQuery = false
raycastView.CanTouch = false
raycastView.CastShadow = false
local function visRay(startPosition,direction,colour)
local endPosition = startPosition + direction
local midpoint = (startPosition + endPosition) /2
local ray = raycastView:Clone()
ray.Parent = workspace
ray.Size = Vector3.new(0.2,0.2,direction.Magnitude)
ray.CFrame = CFrame.lookAt(midpoint,startPosition)
Debris:AddItem(ray,0.1)
--Ignore this if you do not care about the colour :)
if colour == "red" then
ray.BrickColor =BrickColor.new("Really red")
elseif colour == "green" then
ray.BrickColor =BrickColor.new("Bright green")
elseif colour == "blue" then
ray.BrickColor = BrickColor.new("Bright blue")
elseif colour == "violet" then
ray.BrickColor = BrickColor.new("Bright violet")
end
ray.Material = "Neon"
end
^This piece of code is a raycast visualizer. Make sure to change the parent to the worldmodel and then you should in theory be able to test and see what is happening.
I’m trying to figure out the exact same thing. I already made a post about my issue but it didn’t get any replies. My code is almost identical to your code but for some reason the ray’s direction is completely off. I’ve been stuck on this issue for days and have came up with no solution at all.
Hmm. I actually came up with a reason that might be the reason why the frames are off.
We might have to get the MousePosition relative to the frame and not the screen. It could be that Camera:ScreenPointToRay() only works for screens and we have to offset it ourselves for it to line up.
I am not entirely sure if it is the problem and I am not even sure if this will even work. But you could try simply negating the position of the frame.
local MouseLocation = UserInputService:GetMouseLocation()
local ViewportMouseLocation = MouseLocation - ViewportFrame.AbsolutePosition -- Idrk if this accounts for anchor points.
I will see if I can find a solution for you. Also, I didn’t see your post.
(Maybe you can experiment by setting the size of the Viewport frame to match the screen size.)
(Maybe you can experiment by setting the size of the Viewport frame to match the screen size.) <
I thought of the exact same thing and I don’t think that’s the issue. I scaled the ViewportFrame to be the size of the screen and I get the exact same result. What I find really weird about this is the fact that the ray is pointing in the complete wrong direction as I showed on my post:
The ray is shooting in a completely different direction than what would be expected.
CurrentCamera’s lookvector: -0, -0, -1
DrawUnitRay.Direction: 0.90532231330872, -0.42472475767136, -0.00064873765222728
I have also had no success with trying to use Camera:ScreenPointToRay/ViewportPointToRay on Cameras in ViewportFrames; it probably warrants a bug report/feature request at some point since you’d expect it to work normally, but…
In the meantime, the two functions below should work for raycasting from a ViewportFrame’s CurrentCamera (although I haven’t tested them extensively):
local function RaycastInViewportFrame(viewportFrame, x, y, raycastDistance, raycastParams)
local camera = viewportFrame.CurrentCamera
local worldModel = viewportFrame:FindFirstChildWhichIsA("WorldModel")
local mousePosition = Vector2.new(x,y) - viewportFrame.AbsolutePosition -- account for viewportframe offset
local relativePosition = ((mousePosition - (viewportFrame.AbsoluteSize/2)) * Vector2.new(1, -1))/(viewportFrame.AbsoluteSize/2) -- get the relative position of the click with center of viewportFrame as origin: -1 is left/bottom and 1 is right/top for X and Y respectively
local projectedY = math.tan(math.rad(camera.FieldOfView)/2)*raycastDistance -- the projected height of a 2D frame raycastDistance studs from the camera with same aspect ratio
local projectedX = projectedY * (viewportFrame.AbsoluteSize.X/viewportFrame.AbsoluteSize.Y) -- projected width from aspect ratio
local projectedPosition = Vector2.new(projectedX, projectedY) * relativePosition -- the projected position of the input on the similar frame
local worldPosition = (camera.CFrame * CFrame.new(projectedPosition.X, projectedPosition.Y, -raycastDistance)).Position -- the 3d position of said projected position
return worldModel:Raycast(camera.CFrame.Position, (worldPosition - camera.CFrame.Position).Unit * raycastDistance, raycastParams)
end
local function ViewportFramePointToRay(viewportFrame, x, y, depth) -- similar to Camera:ScreenPointToRay
depth = depth or 0
local camera = viewportFrame.CurrentCamera
local mousePosition = Vector2.new(x,y) - viewportFrame.AbsolutePosition -- account for viewportframe offset
local relativePosition = ((mousePosition - (viewportFrame.AbsoluteSize/2)) * Vector2.new(1, -1))/(viewportFrame.AbsoluteSize/2) -- get the relative position of the click with center of viewportFrame as origin: -1 is left/bottom and 1 is right/top for X and Y respectively
local projectedY = math.tan(math.rad(camera.FieldOfView)/2) * (1 + depth) -- the projected height of a 2D frame 1 + depth studs from the camera with same aspect ratio
local projectedX = projectedY * (viewportFrame.AbsoluteSize.X/viewportFrame.AbsoluteSize.Y) -- projected width from aspect ratio
local projectedPosition = Vector2.new(projectedX, projectedY) * relativePosition -- the projected position of the input on the similar frame
local worldPosition = (camera.CFrame * CFrame.new(projectedPosition.X, projectedPosition.Y, -(1 + depth))).Position -- the 3d position of said projected position
local rayOrigin = (CFrame.new(camera.CFrame.Position, worldPosition) * CFrame.new(0, 0, -depth)).Position
local rayDirection = worldPosition - rayOrigin
return Ray.new(rayOrigin, rayDirection)
end
yourViewportFrame.InputBegan:Connect(function(input)
if input.UserInputType ~= Enum.UserInputType.MouseButton1 then return end
print(RaycastInViewportFrame(yourViewportFrame, input.Position.X, input.Position.Y, yourRaycastDistance, yourRaycastParams))
local ray = ViewportFramePointToRay(yourViewportFrame, input.Position.X, input.Position.Y)
print(yourWorldModel:FindPartOnRay(Ray.new(ray.Origin, ray.Direction*500)))
end)
A sample place is provided below:
viewport_raycast.rbxl (37.1 KB)
The ViewportPointToRay of Roblox Studio still does not work
Sorry for the bump