I'm making a sort of interactable console and am wondering how one would check if the player has moved their mouse over the surface that has been created. I know that you would have to get the player's traceline and position but I can't figure out how to check if they're looking at the surface area. The reason for this is to make it so that the surface will appear highlighted sort of like how the keypad entity does (which is most often used in DarkRP servers).
Here's one of my buttons:
[lua]local X = -210
local Y = -150
local W = 350
local H = 175
-- This is inside the ENT:Draw() function and inside a cam.Start3D2D
surface.SetDrawColor(0, 125, 0, 255);
surface.DrawRect(X+10, Y+220, W-190, H-100);[/lua]
A better question: How can I get the coordinates of where I'm looking at on the entity according to the entity's position? (Aka, not the world coordinates, but the coordinates of the entity)
[b]Edit:[/b]
I was able to get the world coordinates by using this:
[lua]local Ply = LocalPlayer();
local t = {}
t.start = Ply:GetShootPos()
t.endpos = Ply:GetAimVector() * 100 + t.start
t.filter = Ply
local tr = util.TraceLine(t);
local pos = self.Entity:WorldToLocal(tr.HitPos)
local x = (pos.x)
local y = (pos.y)
if ( (tr.Entity == self.Entity) ) then
print("X: "..tr.HitPos.x)
print("Y: "..tr.HitPos.y)
end
[/lua]
You could look at LocalToWorld but I'm not sure if that will help you much.
Try this:
[lua]-- l0 is the start of the ray (player shoot pos?)
-- l is the ray direction (player aim vector?)
-- p is the a point on the plane (the position of your entity?)
-- right is the right vector of the plane normal.
-- the length of right must be half the width of your surface
-- you can get this like so:
-- local right = Angle(p, y, r):Right() * W/2
-- where Angle(p, y, r) is the normal angle of your 3D2D
-- up is the up vector of the plane normal.
-- the length of up must be half the height of your surface
-- you can get this like so:
-- local up = Angle(p, y, r):Up() * H/2
-- where Angle(p, y, r) is the normal angle of your 3D2D
-- returns a Vector with z=0 where x and y are the local coordinates of the intersection
-- relative to p
local function RayQuadIntersect(l0, l, p, right, up)
local vp = l:Cross(up)
local d = right:Dot(vp)
if d <= 0 then return end
local vt = l0 - p
local u = vt:Dot(vp)
if u < 0 or u > d then return end
local v = l:Dot(vt:Cross(right))
if v < 0 or v > d then return end
return Vector(u/d, v/d, 0)
end[/lua]
[QUOTE=jaooe;40094085]You could look at LocalToWorld but I'm not sure if that will help you much.[/QUOTE]
Nope, that didn't really work. It was more counter-productive.
[QUOTE=MakeR;40094609]Try this:
[lua]-- l0 is the start of the ray (player shoot pos?)
-- l is the ray direction (player aim vector?)
-- p is the a point on the plane (the position of your entity?)
-- right is the right vector of the plane normal.
-- the length of right must be half the width of your surface
-- you can get this like so:
-- local right = Angle(p, y, r):Right() * W/2
-- where Angle(p, y, r) is the normal angle of your 3D2D
-- up is the up vector of the plane normal.
-- the length of up must be half the height of your surface
-- you can get this like so:
-- local up = Angle(p, y, r):Up() * H/2
-- where Angle(p, y, r) is the normal angle of your 3D2D
-- returns a Vector with z=0 where x and y are the local coordinates of the intersection
-- relative to p
local function RayQuadIntersect(l0, l, p, right, up)
local vp = l:Cross(up)
local d = right:Dot(vp)
if d <= 0 then return end
local vt = l0 - p
local u = vt:Dot(vp)
if u < 0 or u > d then return end
local v = l:Dot(vt:Cross(right))
if v < 0 or v > d then return end
return Vector(u/d, v/d, 0)
end[/lua][/QUOTE]
Eh, I don't really know how I would be able to use this properly. I tried using it the best I could but got no needed results.
Sorry, you need to Log In to post a reply to this thread.