Throwing something in the direction I am look with some umpf!

cindycindy Posts: 8Member

Hi all!

I would like to have a character throw an object in the direction he is looking ✨. I know about spawning objects 😊 and I think 🤔 that I need to use "apply_impulse" to get to object going. Sadly 😭 I don't know how to get the Vectors I need to put into this function. I just want it to go in the way I look.

Can anyone help me 🥳?

Comments

  • MegalomaniakMegalomaniak Posts: 4,173Admin

    Is this a first person or a third person game?

  • cindycindy Posts: 8Member

    1st person ^^

  • MegalomaniakMegalomaniak Posts: 4,173Admin

    Ok, that's useful to know for anybody who feels capable answering. Personally I haven't really done anything substantial with physics in godot but I'll @cybereality since I know they've done something interesting with physics recently and might be able to help. Hopefully they don't mind.

  • xyzxyz Posts: 452Member
    edited November 26

    Simplest way would be to take camera's local look direction (always negative z axis), project it into global space and multiply with strength of the impulse:
    var impulse_vector = camera.to_global(Vector3.FORWARD).normalized() * impulse_strength

  • cyberealitycybereality Posts: 2,685Moderator

    Hey there! Yes, I have some experience with this.

    First you need to obtain the forward vector. You can do this for the character like this:

    var forward_vec = Vector3(0.0, 0.0, -1.0)
    var basis = get_transform().basis
    var forward = basis.xform(forward_vec)
    

    So now forward will be facing toward wherever the character is looking. Then you can move the object like this:

    object.apply_central_impulse(forward * throw_speed)
    

    That should work.

  • cindycindy Posts: 8Member
    edited November 26

    I have also noticed that the way i get the initial position of the object to be thrown. as far as i can tell, there is no .get_position() in 3d, only .get_global_transform(). I have tried:

    object.set_global_transform(self.get_node("Head").get_global_transform())

    This spawns the object in the right pace but with some strange initial impulse. I don't know how to explain this 😭.

    @xyz said:
    Simplest way would be to take camera's local look direction (always negative z axis), project it into global space and multiply with strength of the impulse:
    var impulse_vector = camera.to_global(Vector3.FORWARD).normalized() * impulse_strength

    this is kinda working, but the direction of the throw is only influenced by the position of the character and not the direction the camera is facing 🤔.

    @cybereality said:
    Hey there! Yes, I have some experience with this.

    First you need to obtain the forward vector. You can do this for the character like this:

    var forward_vec = Vector3(0.0, 0.0, -1.0)
    var basis = get_transform().basis
    var forward = basis.xform(forward_vec)
    

    So now forward will be facing toward wherever the character is looking. Then you can move the object like this:

    object.apply_central_impulse(forward * throw_speed)
    

    That should work.

    As far as I can tell this:

    var forward_vec = Vector3(0.0, 0.0, -1.0)

    Is the direction the object is thrown in. How can I set this to the direction the character is looking 🤔?

  • xyzxyz Posts: 452Member
    edited November 26

    It's hard to give specific advice without seeing your actual node hierarchy.

    From your description it wasn't clear if throw is for first person view (player/camera) or third person view (character the camera is looking at). I assumed the former. But technically it really makes no difference.

    In general, the idea is to take one of character's local axes that represents its "forward" or "look" direction, and transform it from local space to space you're spawning the object (typically but not necessarily - global space). By convention the forward axis is assumed to be negative z (but it can be any other direction vector you choose). This transformation can be done in several ways. Both posted solutions basically do this. You just need to use proper forward axis and proper transformation that pertain to your node setup.

    My one-liner should work if you replace 'camera' with 'character' (or whichever node is doing the facing), assuming the spawn is done in global space. For simplicity, I assumed there is no non-proportional scaling in the character. If there is, then @cybereality's approach should be used.

  • cindycindy Posts: 8Member

    nvm, if figured it out using code from the 3d platformer example.

  • TwistedTwiglegTwistedTwigleg Posts: 5,028Admin

    Just for anyone looking in the future, the FPS tutorial on the Godot documentation for Godot 3.x has code for picking up and throwing RigidBody nodes in first person.

  • DaveTheCoderDaveTheCoder Posts: 567Member

    Picking up the cubes in the FPS tutorial and throwing them at the stacks of cubes is fun.

  • cyberealitycybereality Posts: 2,685Moderator

    @cindy said:
    As far as I can tell this:

    var forward_vec = Vector3(0.0, 0.0, -1.0)

    Is the direction the object is thrown in. How can I set this to the direction the character is looking 🤔?

    That's exactly what the rest of the code does. By transforming a generic forward vector (which is the same for all objects in Godot) into the the forward relative to a particular object, in this case your character or camera.

Leave a Comment

BoldItalicStrikethroughOrdered listUnordered list
Emoji
Image
Align leftAlign centerAlign rightToggle HTML viewToggle full pageToggle lights
Drop image/file