Help needed, method for finding the nearest open space

I’m working on a teleportation ability (based off of Jumper) that doesn’t require any sweps or anything like that, however, it’s possible to teleport into a wall or an object and I can’t think of any way that’s efficient to find the nearest open space that the player can fit in. Knowledge would be appreciated.

I guess the best way in my opinion is to teleport them there and see if they collide with anything. If they do collide then teleport them back. If they don’t then play the teleport effect.

Use a trace with trace.HitNormal.

well, the problem with that is that when i put them in the new spot, they get instantly set there, so there’s no collision anyway, and the point that represents their position would still be outside of the object even though they’re half in it.

the trace.HitNormal would only work if they teleport to a wall and there is no ceiling directly above or an object nearby

any other suggestions?

Try Ents find in box? Perhaps it even returns WOrldSPawn

Do an active trace and scan points before they actually activate the jump.

Is this going to work something like the teleport magic in Shadowrun?

Try this
[lua]
local t = {}
t.start = ply:GetPos() + Vector( 0, 0, 32 )
t.endpos = ply:GetPos() + ply:EyeAngles():Forward() * 16384
t.filter = ply

local tr = util.TraceEntity( t, ply )

local pos = tr.HitPos

if pos:Distance( ply:GetPos() ) < 64 then
return
end

ply:SetPos( pos )
ply:SetLocalVelocity( Vector( 0, 0, 0 ) )
[/lua]

ULX uses this for teleporting, seems to work.

I’m not sure what you mean by active trace, and i’ve never used the teleport magic from Shadowrun, so i don’t know

You can see it in this video:

By active trace, I mean have a script that checks a whole bunch of positions around the player on a regular basis. Not just when they want to teleport. Might also be worth making a script that saves all these traced locations and then just pulls them back each game.

it’s a little difficult to tell where he’s teleporting in that vid, but mine works by either alt-left click to teleport where you’re looking, alt-right click to go into a top down view and then from there, left click to where you want to teleport (has edge scrolling and such) or you can save a location and assign it to alt-R or you can take objects by walking up to it and hitting alt-E.

the only method that i could think of would be to get all the points in the player’s bounding box and check to see if they’re inside world, and if they are, then move it and check again. How would you suggest i use the traces, and trace from where?

You’d have to run a complex system of traces and measurements. This isn’t wise.

well, for objects i can just find in box and then push them out, but i need to do something about environment because it’s really annoying to teleport and end up stuck in some wall or ceiling.

edit: well, I’ve now got it so you won’t get stuck unless you click the wall near the ceiling or click the floor/ceiling near a wall.

do you think i ought to leave it as is, or should i try to make it less likely for you to get stuck?

Less likely, if you can get stuck in any way the mod is not complete, sorry :frowning: I’m not trying to be mean or anything, but you can’t have a truly finished mod with bugs :confused:

understandable, i just don’t think there’s much more that I can do…

Perhaps a util.HullTrace() with a length of 1 starting from the prospective teleport position and mins of ply:OBBMins() and maxs of ply:OBBMaxs(), then check to see if tr.FractionLeftSolid and if tr.Hit. If either of those two things happen, the player then cannot teleport to there.

i’m not entirely sure how a traceHull works, but would there be a way to trace at least in the six basic directions and then move the position out depending on if it hits on those traces, then check again and if it still hits something, then disallow the teleport?

edit: how do i specify the length without specifying a direction?

edit2: -fixed-
[lua] local tracedata = {}
tracedata.start = endpos
tracedata.endpos = endpos + Vector(1,0,0)
tracedata.filter = ply
tracedata.mins = ply:OBBMins() + Vector(2,2,2)
tracedata.maxs = ply:OBBMaxs() - Vector(2,2,2)
local trace = util.TraceHull(tracedata)
if trace.Hit then return end[/lua]
(The reason for the + and - vectors is so that you can still teleport to ramps where you might get stuck for a sec before it releases you.)

never mind on that, I got it working. Now i just need to get from the center to the hitpos and move it in the opposite direction however far it is from the hitpos to the edge of the bounding box, unfortunately, i’m not that good at vector math. How is it done?

Is the endpos 1/2 way the distance bewteen OBBMins.z and OBBMaxs.z from the ground?

You can always use util.IsInWorld(). Comes in handy.
Take a look at these too:

i’ve been using those allot, actually

You’re forgetting http://wiki.garrysmod.com/?title=Util.PointContents

:smiley:

Actually, you check could just check all the corners of the player’s OBB in the destination location with that. :V