Third Person and Point Click Movement

I have been looking for a script for point click movement along with the third-person? Even if you would point me in the right direction on where to start at coding it myself. Thanks a lot.

somewhere on the forum there is a function some wrote to get the 3d position of the mouse on the screen. (I’m looking for it)

I don’t know how to use it but the wiki will help.

[editline]15th December 2013[/editline]

3d2d mouse stuff: wrong thing

[editline]15th December 2013[/editline]

This might help http://www.facepunch.com/threads/891702

Yea im looking for something with a sort of runescape aspect. Where the camera follows the player, not where it freely moves like LoL.

I don’t think there are any public scripts, you could check coderhire but I doubt it. Your best bet it to write your own.

I’m not even sure where to start on the movement. Changing the camera position is easy, but the movement is an entirely different story.

The secret is to use NavMeshes.

[editline]15th December 2013[/editline]

(I saw some guy working on a MOBA in WAYWO, he was using NextBot)

How would i convert mouse click position to world position?

Here take a look at this; what I’m using for my gamemode I’m working on.

[lua]
local worldPos = gui.ScreenToVector(gui.MouseX(), gui.MouseY())
local worldTrace = util.QuickTrace(Custom Camera Pos From CalcView, worldPos * 1e9)
local traceEnd = worldTrace.HitPos

function Move(traceEnd)
	LocalPlayer():SetEyeAngles((traceEnd - LocalPlayer():GetShootPos()):Angle()) //Make the player look at the end point
	LocalPlayer():ConCommand("+forward")
	
	//Frequently Check If I Get There By Comparing Distance
	CheckIfReachedPoint(traceEnd)
end

[/lua]

There has to be a much better and more efficient way to do this.

I’m not too sure about your entire plans, but you could probably assign each player a nextbot entity and set the calcview to follow that entity and then you could easily use navmeshes for better movement.

I was thinking about doing that but im not sure how i would set up the camera then

I’m probably taking on way too much doing something like this

Pathfinding is more complicated, but making the player walk towards the pointer while you hold a button is easy.

You will need CalcView for your camera.

Getting the world position of the pointer is more complicated, but if you don’t want pathfinding you can skip that part and use approximation.

To make the local player face the pointer:

[lua]
local mposx,myposy,halfwidth,halfheight,x,y,ang
mposx = gui.MouseX()
mposy = gui.MouseY()
halfwidth = ScrW()/2
halfheight = ScrH()/2
x = halfwidth - mposx
y = halfheight - mposy
ang = Angle(0,math.deg(math.atan2(-y,x))-90,0)
ang:RotateAroundAxis(ang:Forward(),45)
LocalPlayer():SetEyeAngles(ang)
[/lua]

Be sure to use gui.EnableScreenClicker(true) to allow the pointer to be visible.

[editline]15th December 2013[/editline]

Note that this was tested with my camera, and screen dimension ratio. Some adjustments may be needed.

[editline]15th December 2013[/editline]

Note that ScreenToVector, while ideal sounding in name, only works in certain scenarios.

As suggested, using nextbots as player is the best way to do it as the path-finding is already integrated.

Okay so I got the movement and path-finding. I just used nextbots as players as everyone has suggested. Any ideas how I would get the camera to rotate around the bot so that the center of the screen is aimed directly at the bot no matter what the angles of the camera are.


CameraPos = NextBot:LocalToWorld( SomeLocalPoint ) - CameraAngles:Forward( ) * CameraDistance

The idea is that the player isn’t moving a camera around in the world, but is instead rotating around a local point on the entity and zooming in and out.

Assuming you wanted to make forward and back zoom, strafing pan, and jump / duck pitch, you could do something like:



DefaultAngles = Angle( P, Y, R ) --Whatever the default camera angles would be
DefaultDistance = 32 --Or whatever you like
MinimumDistance = 18
MaximumDistance = 128
--How much the camera can be adjusted, in units / degrees per second
ZoomSpeed = 32
PanSpeed = 64
PitchSpeed = 45

MinPitch = -90
MaxPitch = 90

CameraAngles = DefaultAngles * 1 --Initialize it
CameraDistance = DefaultDistance

LocalPoint = Vector( 0, 0, 72 )  --The local point on the model

--Inside SetupMove, Move, or FinishMove - any of them, but only on the client
function X( pl, move )
  if pl == LocalPlayer( ) then
    local buttons = move:GetButtons( )

    if bit.band( buttons, IN_FORWARD ) then
      CameraDistance = math.Clamp( CameraDistance - RealFrameTime( ) * ZoomSpeed, MinimumDistance, MaximumDistance )
    elseif bit.band( buttons, IN_BACK ) then
      CameraDistance = math.Clamp( CameraDistance + RealFrameTime( ) * ZoomSpeed, MinimumDistance, MaximumDistance )
    end

    if bit.band( buttons, IN_JUMP ) then
      CameraAngles:RotateAroundAxis( CameraAngles:Right( ), -PitchSpeed * RealFrameTime( ) )
    elseif bit.band( buttons, IN_DUCK ) then
      CameraAngles:RotateAroundAxis( CameraAngles:Right( ), PitchSpeed * RealFrameTime( ) )
    end
   
    CameraAngles.p = math.Clamp( CameraAngles.p, MinPitch, MaxPitch )

    if bit.band( buttons, IN_MOVERIGHT ) then
      CameraAngles:RotateAroundAxis( vector_up, PanSpeed * RealFrameTime( ) )
    elseif bit.band( buttons, IN_MOVELEFT ) then
      CameraAngles:RotateAroundAxis( vector_up, PanSpeed * RealFrameTime( ) )
    end
  end
end

--Inside CalcView

view.origin = PsuedoLocalPlayer:LocalToWorld( LocalPoint ) - CameraAngles:Forward( ) * CameraDistance
view.angles = CameraAngles


It’s completely untested, but it’s how I’d go about it.

That works perfectly thanks, now im only having problems with using the scroll wheel to zoom in and out. Im trying not to ask too much but i dont want to start a new thread for anything, im sure ill figure it out.

input.IsMouseDown( MOUSE_WHEEL_X )

MOUSE_WHEEL_UP
MOUSE_WHEEL_DOWN

Yea i have tried that but for some reason nothing is happening, this is what i have:



if ( input.IsMouseDown( MOUSE_WHEEL_UP ) ) then
	print( "UP" )
elseif ( input.IsMouseDown( MOUSE_WHEEL_DOWN ) ) then
	print( "Down" )
end


I have tried placing this in and out of the think function. Nothing either way.

Bump. Still havent fixed this and its aggravating me that it is not fixed.

It is broken. Here’s my fix!

[lua]
local overlayingpanel = vgui.Create(‘DFrame’)
local wheeldirection, wheeldelay = 0,0
overlayingpanel:SetSize(ScrW()+100,ScrH()+100)
overlayingpanel:SetPos(-50,-50)
overlayingpanel:SetAlpha(0)
function overlayingpanel:OnMouseWheeled(mc)
wheeldirection = mc
wheeldelay = 1
end
timer.Create(‘mousewheeloverlay’,1/5,0,function()
if wheeldirection == 0 then return end
wheeldelay = wheeldelay - 1
if wheeldelay < 0 then wheeldelay = 0 end
if wheeldelay == 0 then wheeldirection = 0 end
end)
local oldinputismousedown = input.IsMouseDown
function input.IsMouseDown(enum)
if enum == MOUSE_WHEEL_DOWN || enum == MOUSE_WHEEL_UP then
if enum == MOUSE_WHEEL_DOWN then
if wheeldirection < 0 then return true end
else
if wheeldirection > 0 then return true end
end
return false
else
return oldinputismousedown(enum)
end
end
[/lua]

This will allow you to keep using input.IsMouseDown, and have it work, by overriding it. I place a big invisible VGUI panel over the screen, which accepts mouse wheel input, that I feed back into input.IsMouseDown().