Search Unity

How to add force on an object in the direction in which the player is facing?

Discussion in 'Physics' started by surajsirohi1008, Apr 18, 2018.

Thread Status:
Not open for further replies.
  1. surajsirohi1008

    surajsirohi1008

    Joined:
    Jun 21, 2016
    Posts:
    267
    I'm using character controller so I'm using :
    Code (CSharp):
    1. private void OnControllerColliderHit(ControllerColliderHit hit)
    2.     {
    3.         if (hit.gameObject.GetComponent<Rigidbody>() != null)
    4.             hit.gameObject.GetComponent<Rigidbody>().AddForce(Vector3.forward);
    5.     }
    But it's adding force only in certain direction, I've cans (cylinders), I want to make them fall in the direction I'm facing when I push them.
     
    Last edited: Apr 19, 2018
  2. SparrowGS

    SparrowGS

    Joined:
    Apr 6, 2017
    Posts:
    2,536
    Use the player's .forward

    Vector3.forward returns (0,0,1), that's forward relative to the world
     
    SwixDevs likes this.
  3. surajsirohi1008

    surajsirohi1008

    Joined:
    Jun 21, 2016
    Posts:
    267
    I've tried it, not working.
     
    VortexInCortex likes this.
  4. chelnok

    chelnok

    Joined:
    Jul 2, 2012
    Posts:
    680
    Try harder. It'll work.
     
  5. surajsirohi1008

    surajsirohi1008

    Joined:
    Jun 21, 2016
    Posts:
    267
    oh my god!... still not working.
     
  6. SparrowGS

    SparrowGS

    Joined:
    Apr 6, 2017
    Posts:
    2,536
    What did you try?
    Show us your new code
     
    panendraommina likes this.
  7. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,450
  8. SparrowGS

    SparrowGS

    Joined:
    Apr 6, 2017
    Posts:
    2,536
    Could also do AddForce(Player.transform.forward)
     
  9. surajsirohi1008

    surajsirohi1008

    Joined:
    Jun 21, 2016
    Posts:
    267
    Yes, this is working, thanks!

    I just had to change Player.transform.forward to this.transform.forward, how is it different from Vector3.forward?
     
  10. surajsirohi1008

    surajsirohi1008

    Joined:
    Jun 21, 2016
    Posts:
    267
    'new' was a typo (I didn't paste the code here, directly typed it), edited the question and fixed. transform.forward is working for me.
     
  11. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,450
    Sure but it's slower as this gets the transform then computes a world-space forward vector which can then be passed to the world-space AddForce. Using AddRelativeForce requires the constant forward vector only and be applied directly.

    In short; AddForce requires a world-space vector whereas AddRelativeForce requires a local-space vector.
     
  12. SparrowGS

    SparrowGS

    Joined:
    Apr 6, 2017
    Posts:
    2,536
    Answered it on the first post

     
  13. SparrowGS

    SparrowGS

    Joined:
    Apr 6, 2017
    Posts:
    2,536
    True that, but performance shouldn't be a concern for him yet(assuming you're new to unity), he should mostly realize what does what and why
     
  14. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,450
    I agree and understanding local-space and world-space difference is super important too hence my post.

    Anyway, lots of useful info here, thanks.
     
    Ultroman, hahahpizza and Otavio_ like this.
  15. surajsirohi1008

    surajsirohi1008

    Joined:
    Jun 21, 2016
    Posts:
    267
    I used this:
    Code (CSharp):
    1. rb.AddRelativeForce(Vector3.forward);
    It's not working.
     
  16. surajsirohi1008

    surajsirohi1008

    Joined:
    Jun 21, 2016
    Posts:
    267
    Actually I'd appreciate it If I get any advice which leads to a more smooth and optimised game.
     
  17. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,450
    Well it does work so not sure how you've got that setup there. It might be more useful to describe what is happening rather than simply saying it does not work. Will maybe give us clues to what is going wrong on your side.

    Here's a simple test project. Focus on the cube, press play and rotate its Transform around the Y axis in the inspector. It'll add force to the direction its facing. Note the force obviously accumulates so if you leave it too long in one direction it'll get quite fast and will resist changes in motion.

    https://oc.unity3d.com/index.php/s/XyvGZWBZFW0P67q
     
    Otavio_ likes this.
  18. SparrowGS

    SparrowGS

    Joined:
    Apr 6, 2017
    Posts:
    2,536
    Maybe the force is just too weak?
     
  19. surajsirohi1008

    surajsirohi1008

    Joined:
    Jun 21, 2016
    Posts:
    267
    Your project has the force acting the moving player itself, My project is a little different, here's the simplified version of my project, you can just open and click play, you'll notice the problem:

    https://drive.google.com/drive/folders/1ZIUubTfUHlzOFX8yZ9wywWpN0WpYGcQs?usp=sharing
     
  20. surajsirohi1008

    surajsirohi1008

    Joined:
    Jun 21, 2016
    Posts:
    267
    I've a force multiplier, I've tried different values, the force is acting but not in the direction I want.
     
  21. SparrowGS

    SparrowGS

    Joined:
    Apr 6, 2017
    Posts:
    2,536
    You do know where global forward is, right?
     
  22. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,450
    Again, you're not saying what you want but just saying "not in the direction I want". Which direction is that? Would help if we knew.

    I've tried your project and it moves forward in its local Z axis which is what forward is. If you want a different axis or direction then use a different vector. If you want to move in a different direction then use Vector3.back, Vector3.left, Vector3.right etc.
     
    prakyath_unity and Otavio_ like this.
  23. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,450
    Also note that your code seems wrong. You're not using AddForce/AddRelativeForce. You're only do that for stuff you hit with the CharacterController. To move your player you're just using transform.forward * vert * walkspeed etc via the CharacterController using SimpleMove:
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.SceneManagement;
    3.  
    4. public class move : MonoBehaviour
    5. {
    6.     CharacterController charControl;
    7.  
    8.     public float walkSpeed;
    9.  
    10.     public float ForceMultiplier;
    11.     public float rotationMultiplier;
    12.  
    13.     void Awake()
    14.     {
    15.         charControl = GetComponent<CharacterController>();
    16.     }
    17.  
    18.     void Update()
    19.     {
    20.         MovePlayer();
    21.  
    22.         if (Input.GetMouseButton(0))
    23.             rotate(1);
    24.  
    25.         if (Input.GetMouseButton(1))
    26.             rotate(-1);
    27.  
    28.  
    29.  
    30.         //Restart Scene by Pessing R
    31.         if (Input.GetKey(KeyCode.R))
    32.             SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
    33.                 }
    34.  
    35.     void MovePlayer()
    36.     {
    37.         float horiz = Input.GetAxis("Horizontal");
    38.         float vert = Input.GetAxis("Vertical");
    39.  
    40.         Vector3 moveDirSide = transform.right * horiz * walkSpeed;
    41.         Vector3 moveDirForward = transform.forward * vert * walkSpeed;
    42.  
    43.         charControl.SimpleMove(moveDirSide);
    44.         charControl.SimpleMove(moveDirForward);
    45.  
    46.     }
    47.  
    48.     private void OnControllerColliderHit(ControllerColliderHit hit)
    49.     {
    50.         if (hit.gameObject.GetComponent<Rigidbody>() != null)
    51.         {
    52.             //hit.gameObject.GetComponent<Rigidbody>().AddForce(transform.forward * ForceMultiplier);
    53.  
    54.             hit.gameObject.GetComponent<Rigidbody>().AddRelativeForce(Vector3.forward * ForceMultiplier);
    55.  
    56.         }
    57.     }
    58.  
    59.     private void rotate(int direction){
    60.  
    61.         transform.Rotate(new Vector3(0, direction * rotationMultiplier, 0));
    62.     }
    63.  
    64.  
    65. }
     
    ALIENPANDA, Only4gamers and Otavio_ like this.
  24. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,450
    AFAIK you should try to use only a single SimpleMove per-frame so it should be like this:
    Code (CSharp):
    1. void MovePlayer()
    2.     {
    3.         float horiz = Input.GetAxis("Horizontal");
    4.         float vert = Input.GetAxis("Vertical");
    5.  
    6.         var moveDirection = transform.TransformDirection(new Vector3(horiz, 0, vert)) * walkSpeed;
    7.         charControl.SimpleMove(moveDirection);
    8.     }
    9.  
    Put horiz/vert in the axis-directions you want to move.
     
  25. surajsirohi1008

    surajsirohi1008

    Joined:
    Jun 21, 2016
    Posts:
    267
    (0,0,1), the blue arrow, Z-axis on global...?
     
  26. surajsirohi1008

    surajsirohi1008

    Joined:
    Jun 21, 2016
    Posts:
    267
    Consider a cube with box collider, if it hits a cylinder with rigid body, the cylinder will fall, right (Given cylinder has small radius but big height)? If the cube is going south to north and hit cylinder the cylinder should naturally fall towards the north, if cube is going east to west the cylinder should fall towards west.

    I just want the fall to happen like it would have happened as if both cube and cylinder have rigid body. But since using character controller doesn't allow rigid body I've to use method like OnControllerColliderHit() to make the fall natural.
     
  27. surajsirohi1008

    surajsirohi1008

    Joined:
    Jun 21, 2016
    Posts:
    267
    Thanks for the suggestion to improve my code.
     
  28. Ripunjoy

    Ripunjoy

    Joined:
    Jul 19, 2017
    Posts:
    2
    Can we add Relative Force to move a physics body in the same direction as it is in a canvas?
     
  29. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,450
    Adding a relative force will be done in the Rigidbody(2D) local-space so if it's rotated then the direction the force is applied is in that rotated space. The physics system knows nothing about a canvas (or anything else beyond the transform) but if your body is rotated then yes, it'll be applied in that rotated space.
     
    Only4gamers, Otavio_ and Ripunjoy like this.
  30. Ripunjoy

    Ripunjoy

    Joined:
    Jul 19, 2017
    Posts:
    2
    Thanks for your response sir. But in my case it's not working as expected.

    _playerRectTransform_List[_playerActiveCount].GetComponent<Rigidbody2D>().AddRelativeForce(_touchDirection * _playerLaunchForce, ForceMode2D.Impulse);

    Here, _touchDirection is a Vector2 and the player does'nt actually rotate but the parent of the player rotates.
     
  31. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,450
    It's impossible for me to debug it though. All I can say is that AddRelativeForce applies it in the rotated space so either what you're passing isn't correct or the Rigidbody2D.rotation isn't rotated as you expect.

    One thing that looks odd above is "_touchDirection". It sounds like you're already applying a directing then using that with AddRelativeForce which applies it in the rotated space. Maybe those are in conflict?
     
    Only4gamers, Otavio_ and Ripunjoy like this.
  32. mruva

    mruva

    Joined:
    Apr 12, 2020
    Posts:
    4
    this is working for me! thanks a lot!
     
    raulprofe likes this.
  33. Only4gamers

    Only4gamers

    Joined:
    Nov 8, 2019
    Posts:
    327
    Hello sir,
    It will be great if you can please look into my post:
    https://forum.unity.com/threads/add-force-and-rotation-to-an-object-in-one-direction.1043524/
    Which is maybe similar situation as this thred.
    Thanks
     
  34. Coldroom

    Coldroom

    Joined:
    Dec 15, 2014
    Posts:
    2
    For me this is the answer to the original question. After using .AddRelativeForce my objects move 'forward' realtive to them, not the world. Thank you MelvMay.
     
    MelvMay likes this.
  35. xDayhawk

    xDayhawk

    Joined:
    Jun 24, 2020
    Posts:
    57
    i know its an old post, hope u still work in Unity, but thank u :D
    i'm developing a top-down spaceship shooter, and the only thing that worked for me is
    Code (CSharp):
    1. rigidbody2d.AddRelativeForce(Vector2.up * movementSpeed * Time.deltaTime);
    I'm using my mouse as a pointer for direction
     
    Last edited: Jul 27, 2021
    MelvMay likes this.
  36. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,450
    You're most welcome. Good luck with your project.
     
  37. xDayhawk

    xDayhawk

    Joined:
    Jun 24, 2020
    Posts:
    57
    thank you!
    may you never run out of cell battery while in the bathroom!
     
    MelvMay likes this.
  38. MoGro

    MoGro

    Joined:
    Jun 12, 2021
    Posts:
    2
    You helped me sooooooooooooooooooooooo much!!!! Thx
    PS: i know i didn't ask but thx u
     
  39. Dait1

    Dait1

    Joined:
    Dec 23, 2021
    Posts:
    1
    The name 'hit' does not exist in the current context.
     
  40. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,450
    Is this a question?
     
    SparrowGS likes this.
  41. rtcheteden

    rtcheteden

    Joined:
    Dec 30, 2020
    Posts:
    22
    ok, im using addrelativeforce for movement, how do i make the player face the direction they are moving like a 3rd person character controller, ive tried multiple sources but so far none have worked with addforce, even this forum ended the same way, dont know why that is
    Code (CSharp):
    1. r.AddRelativeForce(new Vector3(x * s, 0, z * s), ForceMode.VelocityChange);
    2.         r.velocity = new Vector3(Mathf.Clamp(x, 0, x * 40), Mathf.Clamp(r.velocity.y, r.velocity.y, 19.61f), Mathf.Clamp(z, 0, z * 40));
    EDIT SOLVED
    to rotate your player to the direction of your movement with addforce you need to use
    Code (CSharp):
    1. r.transform.Rotate(0, x, 0);
    this way, on the y axis (spinning flat on the ground) your horizontal input(in my case its named "x") will spin you in a big circle, use animations to turn your character(such as the ratchet and clank movement) and scene view or an upper view on camera to properly adjust
    now you wont be able to spin in place by code, but animation should be more than enough and either way, if it doesnt help, this code may be your best bet to start with
     
    Last edited: Jan 2, 2022
  42. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,450
    Locking this thread because it's fast becoming a magnet for any AddRelativeForce question.
     
Thread Status:
Not open for further replies.