Search Unity

  1. Unity 2019.2 is now released.
    Dismiss Notice

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.

  1. surajsirohi1008

    surajsirohi1008

    Joined:
    Jun 21, 2016
    Posts:
    265
    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. SparrowsNest

    SparrowsNest

    Joined:
    Apr 6, 2017
    Posts:
    1,855
    Use the player's .forward

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

    surajsirohi1008

    Joined:
    Jun 21, 2016
    Posts:
    265
    I've tried it, not working.
     
  4. chelnok

    chelnok

    Joined:
    Jul 2, 2012
    Posts:
    673
    Try harder. It'll work.
     
    ctyrell likes this.
  5. surajsirohi1008

    surajsirohi1008

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

    SparrowsNest

    Joined:
    Apr 6, 2017
    Posts:
    1,855
    What did you try?
    Show us your new code
     
  7. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    1,962
    URekt likes this.
  8. SparrowsNest

    SparrowsNest

    Joined:
    Apr 6, 2017
    Posts:
    1,855
    Could also do AddForce(Player.transform.forward)
     
    surajsirohi1008 likes this.
  9. surajsirohi1008

    surajsirohi1008

    Joined:
    Jun 21, 2016
    Posts:
    265
    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:
    265
    '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:
    1,962
    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.
     
    SparrowsNest likes this.
  12. SparrowsNest

    SparrowsNest

    Joined:
    Apr 6, 2017
    Posts:
    1,855
    Answered it on the first post

     
  13. SparrowsNest

    SparrowsNest

    Joined:
    Apr 6, 2017
    Posts:
    1,855
    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:
    1,962
    I agree and understanding local-space and world-space difference is super important too hence my post.

    Anyway, lots of useful info here, thanks.
     
  15. surajsirohi1008

    surajsirohi1008

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

    surajsirohi1008

    Joined:
    Jun 21, 2016
    Posts:
    265
    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:
    1,962
    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
     
  18. SparrowsNest

    SparrowsNest

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

    surajsirohi1008

    Joined:
    Jun 21, 2016
    Posts:
    265
    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:
    265
    I've a force multiplier, I've tried different values, the force is acting but not in the direction I want.
     
  21. SparrowsNest

    SparrowsNest

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

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    1,962
    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.
     
  23. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    1,962
    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. }
     
  24. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    1,962
    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.
     
    duckles101 and surajsirohi1008 like this.
  25. surajsirohi1008

    surajsirohi1008

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

    surajsirohi1008

    Joined:
    Jun 21, 2016
    Posts:
    265
    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:
    265
    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:
    1,962
    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.
     
    Ripunjoy likes 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:
    1,962
    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?
     
    Ripunjoy likes this.