Setting gravity in a certain area (more like a box)

Hey guys I need help with creating a simple script that sets the users’ gravity to a number if they’re inside a certain area. I am unsure of how to do this, and ask for all help, pointers or ultimately an example to go off of. Once again all help is very appreciated thank you in advanced!

I think these may help:

GM:Think

ents.FindInBox

Entity:SetGravity

You could use the tips above, one thing to note is the Entity:SetGravity is a multiplier not an actual value. I would use a SetVelocity instead and use that inside a GM:PlayerTick hook - as its run for every player tick and gives you access to the players movedata.

[editline]30th April 2016[/editline]

Just an example…



hook.Add("PlayerTick","ModifyPlayerGravity",function(ply,movedata)
    local targetPosMin = Vector(-10,-10,-10)
    local targetPosMax = Vector(10,10,10)
    if( targetPosMin <= ply:GetPos() <= targetPosMax ) then
        --do some stuff with the movedata here if you want?
        ply:SetVelocity(Vector(0,0,200))  --This doesnt set the velocity, but rather adds it to the current overall velocity.
    end
end)


Change the min and max vectors for the world pos you want…

Should run this on the server btw.

Wouldn’t that make players fly in certain directions depending on the client’s tickrate?

Yes thats true, i’m not too sure whats the proper way of applying a percise velocity rate thats dependant on an accurate time, like gravity.

When I messed around with creating my own gravity, I just used a serverside playertick hook, seemed to work out fine. I bet even the serverside fluctuates some.

I’d like to know if anyone has any insight on what function does the server calculate gravity for entities and how often?

This is perfect dude thanks, and also thanks for everyone here commenting. Just curious what’s the difference between SetGravity and SetVelocity?

You’re overthinking this.



local ent = player.GetAll()[1] -- or whatever you want
local bones = ent:GetPhysicsObjectCount()

for  i=0, bones-1 do
	local phys = ent:GetPhysicsObjectNum( i )
	if ( IsValid( phys ) ) then
		phys:EnableGravity( false )
	end
end


citation @ https://github.com/garrynewman/garrysmod/blob/master/garrysmod/lua/autorun/properties/gravity.lua

I had no clue players had valid modifiable physics bones considering they aren’t ragdolls?

I got this error when running the code: (I changed set velocity to set gravity too)

[ERROR] gamemodes/darkrp/gamemode/modules/sv_gravity.lua:4: attempt to compare two userdata values

  1. fn - gamemodes/darkrp/gamemode/modules/sv_gravity.lua:4

[editline]30th April 2016[/editline]

I am sorry, but I am not sure how this would set the gravity in a certain area. I am not looking to enable to disable gravity entirely but change the value from a certain vector to another vector. My idea here is to have 0 gravity everywhere else but then gravity in a certain spot.

Then just call that in a Tick hook and do a simple check to see if the player in question is in the specified area, as Palooz did in his example

[editline]30th April 2016[/editline]

Also, setting the gravity as 0 is the same as disabling it entirely, isn’t it?

Oh ok yeah I guess I could do that. And I meant to say setting it to just a lower state xD Thanks for that idea and Potato :smiley:

Don’t know if its proper to place that in modules, I would create an addon folder and place this code within the serverside directory of said folder. Other than that I guess this would solve the error, perhaps lua doesnt accept that logic format:



if(( targetPosMin <= ply:GetPos() ) and ( ply:GetPos() <= targetPosMax )) then


[editline]30th April 2016[/editline]

the targetPosMin and targetPosMax are world position coordinates. World position is a type of vector. The values I used in the example create a 20 unit square box with its center directly at the world origin.

[editline]30th April 2016[/editline]

Here is some code where you can define the world position origin of the gravity box, and how big the box is.



hook.Add("PlayerTick","ModifyPlayerGravity",function(ply,movedata)

    local targetPosOrigin = Vector(0,0,0)    -- we want the box to spawn at the world origin coordinates 0,0,0
    local targetPosSize = Vector(20,20,20)   -- the box will be 20 units square units (width,length,height)


    targetPosSize:Mul(0.5)   -- divides the size by 2, so we can add and subtract evenly from PosOrigin

    local targetPosMin = targetPosOrigin - targetPosSize  -- sets up the negative half of the box
    local targetPosMax = targetPosOrigin + targetPosSize  --sets up the positive half of the box

    if(( targetPosMin <= ply:GetPos()) and (ply:GetPos() <= targetPosMax) ) then   --checks to see if we are within the box we just set up above
        --do some stuff with the movedata here if you want?
        ply:SetVelocity(Vector(0,0,200))  --This doesnt set the velocity, but rather adds it to the current overall velocity. note- this vector is calculated from the local player instead of world origin, so as such this will add a straight upward velocity.
    end
end)


That’s just there to compensate for any entity that comes in the box.

Why don’t you just disable noclip, on the server. And download the Rocket Boot addon on the workshop ?
:goodjob:

Link: https://steamcommunity.com/sharedfiles/filedetails/?id=237544369

Because he’d still need to code it so the rocket boots only fire when the player is in a specified area, which’d probably be even more painful than just disabling the gravity