+1 vote

Local Movement with Physics

I can't figure a way to Locally setlinearvelocity() to my Rigidbody object. When I use setlinearvelocity, it only works on Global axis...

I really need a hand on making my Rigidbody Player move (with physics forces) along his own axis (X, Y and Z), or a turn around would be great to!!

My goal is to create a controller wich can make the player move like a 'Vessel' in the 3D environment. Here is my piece of code (only for the X axis as a test):

func _move_player():
# Define the Inputs in variables
btn_right = Input.is_action_pressed("controller_right") # created inputs
btn_left = Input.is_action_pressed("controller_left")

# Check if you are not moving on a particular axis to create a brake fx
if btn_right or btn_left:
    movingOnX = true
    movingOnX = false

# Code from Jospic from GitHub (thanks)
var linearVelocityModule = 100 
var anglePlayerRot = self.get("transform/rotation") # get_rot() not working!
var localLinearVelocityX = linearVelocityModule * cos(anglePlayerRot.x) #Can't convert Vector3 to Float!!
var localLinearVelocityY = linearVelocityModule * sin(anglePlayerRot.y)

# Trying this for 3D
var localLinearVelocityZ = linearVelocityModule * tan(anglePlayerRot.z)
var localLinearVelocity = Vector3(localLinearVelocityX, localLinearVelocityY, localLinearVelocityZ) 

# Apply Velocities
# If you press on A or D...
if movingOnX:
    # If you actually press D
    if btn_right:
        set_linear_velocity(Vector3(localLinearVelocity.x - speed, get_linear_velocity().y, get_linear_velocity().z))
    # If you actually press A
    elif btn_left:
        set_linear_velocity(Vector3(localLinearVelocity.x + speed, get_linear_velocity().y, get_linear_velocity().z))
# If you are not pressing on A or D... Brake fx
    if v.x != 0:
        set_linear_velocity(Vector3(localLinearVelocity.x * brake_damper, get_linear_velocity().y, get_linear_velocity().z))

If you have any ideas or tutorials to share with me... Feel free to correct all of it!

Thx, Math

in Engine by (46 points)
edited by

There is an easiest way to do it.

var speed = 3    #---set your speed here
var a = state.get_transform().basis
set_linear_velocity(Vector3(a.x.z, a.y.z, -a.z.z) * speed)

#--This code will works to axis Z
#--To use another axis just multiply the Vectors you want to use
Vector3(a.x.z, a.y.z, -a.z.z) * Vector3(a.x.x, a.y.x, -a.z.x)

var speed = 3
var a = state.get_transform().basis
var z = Vector3(a.x.z, a.y.z, -a.z.z)
var y = Vector3(a.x.y, a.y.y, -a.z.y)
set_linear_velocity((y * z) * speed)
#---Just be aware...any number Multiplied by zero is = zero, so check if the angle of your ship is not equal to zero. in this case turn your 0 to 1 or your ship won't move.

#-- angular velocity works almost the same way.
var speedspin = 2
var a = state.get
setangularvelocity(Vector3(a.x, a.y, a.z) * speed_spin)

1 Answer

+2 votes

You know angular rotation of your Player, and you can set linear velocity along Player two direction components:

   var linearVelocityModule = 100
    var anglePlayerRot = get_node("Player").get_rot()
    var localLinearVelocityX = linearVelocityModule * cos (anglePlayerRot)
    var localLinearVelocityY = linearVelocityModule * sin (anglePlayerRot)
    get_node("Player").set_linear_velocity(Vector2(localLinearVelocityX, localLinearVelocityY))


by (1,484 points)

Well it did'nt work :( But thanks a lot!

First, getrot is not existing in base Rigidbody... I tried getrotation() and getrotationdeg() but it results in weird behaviours :(

I forgot to mention that my project is in 3D... My bad! I really tried to make it work, but...

I will need more help :(

If you want to get a property that is editable in the editor inspector, use the function get()

enter image description here

In that case : get_node("Player").get("transform/rotation")

I tried it, and I failed! I can't figure a way to do it.
I've inserted my own piece of code... Let's see if someone can figure this out!

adding a thank you to this. For Godot 3.0 I used it as such and it works great:

var linearVelocityModule = 100
var anglePlayerRot = bullet.rotation
var localLinearVelocityX = linearVelocityModule * cos (anglePlayerRot)
var localLinearVelocityY = linearVelocityModule * sin (anglePlayerRot)
bullet.linear_velocity = Vector2(localLinearVelocityX, localLinearVelocityY)
Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read Frequently asked questions and How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to [email protected] with your username.