Search Unity

AddForce to GameObject using Touch position

Discussion in 'Scripting' started by Metamalt, Dec 10, 2018.

  1. Metamalt

    Metamalt

    Joined:
    Jan 23, 2015
    Posts:
    5
    Hi guys,
    Maybe someone can help me understand what I am doing wrong or why I can't do this.

    I would like to move a gameobject to the position of my touch. Actually I want to be able to drag an object.

    I have successfully managed using the following code:
    Code (CSharp):
    1. void Update()
    2.     {
    3.         for (int i = 0; i < Input.touchCount; i++)
    4.         {
    5.             Touch touch = Input.touches[i];
    6.             Vector2 touchPosition = Camera.main.ScreenToWorldPoint(touch.position);
    7.             Ray ray = Camera.main.ScreenPointToRay(touchPosition);
    8.             RaycastHit2D hit = Physics2D.Raycast(touchPosition, new Vector2(0, 0));
    9.             if (hit.transform != null)
    10.             {
    11.                 if (hit.transform.gameObject.Equals(gameObject))
    12.                 {
    13.                     rb.position = touchPosition;
    14.                 }
    15.             }
    16.         }
    17.     }
    This however introduced unexpected behaviour. The user can now overlap objects when placing and moving things around.

    I read that if you add force then physics is not ignored. So I modified it to this:

    Code (CSharp):
    1. void Update()
    2.     {
    3.         for (int i = 0; i < Input.touchCount; i++)
    4.         {
    5.             Touch touch = Input.touches[i];
    6.             Vector2 touchPosition = Camera.main.ScreenToWorldPoint(touch.position);
    7.             Ray ray = Camera.main.ScreenPointToRay(touchPosition);
    8.             RaycastHit2D hit = Physics2D.Raycast(touchPosition, new Vector2(0, 0));
    9.             if (hit.transform != null)
    10.             {
    11.                 if (hit.transform.gameObject.Equals(gameObject))
    12.                 {
    13.                     Attract(touchPosition);
    14.                     //transform.position = touchPosition;
    15.                     Debug.Log("This is User Created.");
    16.                 }
    17.             }
    18.         }
    19.     }
    20.  
    21.     void Attract(Vector2 target)
    22.     {
    23.         Debug.Log(rb.tag);
    24.         // Calculate forces
    25.         Vector2 direction = rb.position - target;
    26.         float distance = direction.magnitude;
    27.         Debug.Log("Distance: " + distance);
    28.         Vector2 force = direction.normalized * followSpeed;
    29.         Debug.Log("Force: " + force);
    30.         rb.AddForce(force);
    31.     }
    The issue is that the object now does not move at all. Any suggestions or tips?

    While we are at it. If these is a way to get this to work, what would be the best way to go about it in terms of Update vs FixedUpdate. I would like to use Attract() in FixedUpdate() however when I change my Update() to FixedUpdate() then I get no touch readings, however AddForce() is a physics method and as such should be used in FixedUpdate().

    Thank all.
     
  2. PGJ

    PGJ

    Joined:
    Jan 21, 2014
    Posts:
    899
    Have you tried using Rigidbody2D.MovePosition, instead of rb.position? MovePosition takes colliders into account when moving.
     
  3. MadeFromPolygons

    MadeFromPolygons

    Joined:
    Oct 5, 2013
    Posts:
    3,983
    You need to read the touch in update, and do the transformation in fixed update.

    You shouldnt read input in fixed update, and you should not move rigidbodies in update. Hope that helps

    So essentially:

    take the top bit of code and put into update. Change it to not call attract on hit, but to set a bool to true or false depending if it hit. Then in fixed update, apply attract if the bool is true, otherwise dont.

    EDIT:

    Code (CSharp):
    1. bool isAttracting = false;
    2. Vector2 touchPosition;
    3. void Update()
    4.     {
    5.         for (int i = 0; i < Input.touchCount; i++)
    6.         {
    7.             Touch touch = Input.touches[i];
    8.             touchPosition = Camera.main.ScreenToWorldPoint(touch.position);
    9.             Ray ray = Camera.main.ScreenPointToRay(touchPosition);
    10.             RaycastHit2D hit = Physics2D.Raycast(touchPosition, new Vector2(0, 0));
    11.             if (hit.transform != null)
    12.             {
    13.                 if (hit.transform.gameObject.Equals(gameObject))
    14.                 {
    15.                     isAttracting = true;
    16.                
    17.                     //transform.position = touchPosition;
    18.                     Debug.Log("This is User Created.");
    19.                 }
    20. else
    21. {
    22.      isAttracting = false;
    23. }
    24.             }
    25.         }
    26.     }
    27.  
    28. void FixedUpdate()
    29. {
    30.     if(isAttracting) Attract(touchPosition);
    31. }
    32.     void Attract(Vector2 target)
    33.     {
    34.         Debug.Log(rb.tag);
    35.         // Calculate forces
    36.         Vector2 direction = rb.position - target;
    37.         float distance = direction.magnitude;
    38.         Debug.Log("Distance: " + distance);
    39.         Vector2 force = direction.normalized * followSpeed;
    40.         Debug.Log("Force: " + force);
    41.         rb.AddForce(force);
    42.     }
    EDIT2: this was all done off top of my head, may not compile but should give you the idea of what I am recommending you do. Essentially you save the touch position in update and set the flag, so you can use these in fixedupdate.

    Also if adding a force over time, I would use time within the calculation. So multiply the force by Time.fixedDeltaTime
     
    Last edited: Dec 11, 2018
  4. Metamalt

    Metamalt

    Joined:
    Jan 23, 2015
    Posts:
    5
    Cheers I'll give that a go. Just what I was looking for :)
     
  5. Metamalt

    Metamalt

    Joined:
    Jan 23, 2015
    Posts:
    5
    I had a feeling that that would be the answer. Actually had tried something similar and thought that I was hacking things up. Thanks for the explanation.
     
    MadeFromPolygons likes this.