Search Unity

how to move my character around with forces.

Discussion in 'Scripting' started by KubiKub, Mar 23, 2014.

  1. KubiKub

    KubiKub

    Joined:
    Mar 22, 2014
    Posts:
    6
    Hi,

    I looked around and couldn't find exactly what i'm looking for. (im not english native speaker and i could miss some things by creating wrong queries).

    In my little project i have "character" in one point of screen. after i tap somewhere on screen i want this character to move to there. when i will tap other place it will continue going previous direction and slowly changing-accelerating-slowing down(depends on force added and position of tap) towards new tap point.
    I made something like adding force to my object and calculating force-direction vector from tap position. It is working but not as i want it to work. I want my object to slowly turning and moving towards tap point (not to tap position and stop there but only move to that direction - force added will depends from outside things and this is not important in this point). Please look on "technical" drawing of what i mean. I do not need exactly code, just point me in direction i should go :] Was thinking about adding force in front direction of my object and just slowly turning it's face towards tap point... maybe this will be better way to go.

    so far im using rigidbody2D->AddForce. maybe i should go different way.

    It's hard for me to explain exactly what im thinking about, but if someone wants to help i will answer additional questions.
    Thanks for any advices that will help me solve this problem. (im using C# but can use code in other languages - i will convert it).

    Picture:
    $pic1.jpg

    Code i have so far (works but not exactly what i want) with this code if my object is moving for example in only X-axis with for example speed/force =10 and i will tap somewhere with force/speed 8 where tap_x < object_x and tap_y > object_y then my object will only slow down in X-axis to speed/force 2 but it will accelerate to 8 in Y-axis means it will not move back to tap position but only slow down and move up. hope someone can understand what i mean.

    Code so far: (it is not cleaned or optimized it is just for test)
    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class TouchScript : MonoBehaviour {
    6.  
    7.     float time_pressed;
    8.     Touch myTouch;
    9.     float last_time;
    10.  
    11.     Vector3 force_vector;
    12.     Vector3 temp_force_vector;
    13.     Vector3 rigid_position;
    14.  
    15.  
    16.     void Update () {
    17.         if(Input.touchCount > 0)
    18.         {
    19.             myTouch = Input.GetTouch(0);
    20.  
    21.             if(myTouch.phase == TouchPhase.Began)
    22.             {
    23.                 temp_force_vector = myTouch.position;
    24.             }
    25.  
    26.  
    27.             if(myTouch.phase != TouchPhase.Ended)
    28.             {
    29.                 time_pressed += 10*Time.deltaTime;
    30.             }
    31.             else if(myTouch.phase == TouchPhase.Ended)
    32.             {
    33.  
    34.                 force_vector = temp_force_vector;
    35.                 force_vector.z = 0;
    36.                
    37.                 rigid_position.x = this.gameObject.rigidbody2D.transform.position.x;
    38.                 rigid_position.y = this.gameObject.rigidbody2D.transform.position.y;
    39.                 rigid_position.z = 0;
    40.  
    41.                 Vector3 forcevectorAtScreen = Camera.main.ScreenToWorldPoint(force_vector);
    42.  
    43.                 Vector3 direction = (forcevectorAtScreen - rigid_position);
    44.                        
    45.                 rigidbody2D.AddForce(direction.normalized * 100 * time_pressed);
    46.                 last_time = time_pressed;
    47.                 time_pressed = 0;
    48.             }
    49.         }
    50.  
    51.     }
    52.    
    53.    
    54. }
    55.  

    EDIT:

    ok i made my object to start rotating in time towards tap_point and added relative force to Vector3.up (my forward direction). now it works great but i have only one problem with this. force is added only once on beginning of movement/rotation and its travelling one way (where my forward was) and slowly rotating towards my tap_point. how to split/or do anything to this force to make my object always moving (adding force) to my forward direction.

    or really i should drop addrelativeforce idea and just calculate from my direction/rotation/speed and facing full way/distance of my object?

    i want my object to be limited in controls. want it more to be affected by force.

    thansk for any ideas with my problem.

    EDIT2:

    OK i've done it with velocity parameter :) works great now.

    Thread can be closed/deleted :]
     
    Last edited: Mar 23, 2014
  2. diegzumillo

    diegzumillo

    Joined:
    Jul 26, 2010
    Posts:
    418
    Using forces to make an object reach a specific destination is difficult. It works nicely when you use forces as a more direct input, up key makes a upward force etc. You have to do some math to find the correct force that will make an object move to a specific position, depending on its position and velocity. If you simply point the force to the position you want the object to go you are likely to end up with an orbiting behavior.

    Solutions: Do the math. Or don't use rigidbodies. Or alter the rigidbody's velocity instead.

    edit:

    Good to know :) But it's always good to keep threads alive for future reference. It's the reason we google things.
     
  3. KubiKub

    KubiKub

    Joined:
    Mar 22, 2014
    Posts:
    6
    Thanks for answer.

    i have new problem. all works fine but i have that orbiting problem you said about when i add to much force... as object is going/rotating to touch position not in touch direction... i want it just to turn once to touch direction and move with added force (it will stop as i have drag set up).

    im making some silly mistake and my brain is full for today.

    any idea how to turn object to direction once? i know it is 100% simple silly thing and im just tired. all works great for me. i just have to sort out that rotation. maybe i should just add some control variables like is_vaild_for_rotation and turn it off when facing tap_direction 1st time...but tomorrow :D
     
  4. KubiKub

    KubiKub

    Joined:
    Mar 22, 2014
    Posts:
    6
    Hi again,

    I had no time to finish it but i made it working. posting as maybe someone will try to make something similar and this will be helpfully.
    Can someone check this code please? (i'm doing this more like hobby than professional work :) )
    In next free time i will upgrade this with checking distance. closer touch is the faster object will rotate. if its to slow then vectors will be not close enough and object will start orbiting around touchpoint.

    Please let me know how can i upgrade my code to make it faster/more efficient or just make it works better :]

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class testRotate : MonoBehaviour {
    6.  
    7.     float time_pressed;
    8.    
    9.         Vector3 lookPos;
    10.     Vector3 curVel;
    11.     Vector3 test_vector2;          
    12.     Vector3 force_vector;
    13.     Vector3 temp_force_vector;
    14.     Vector3 touchPos;
    15.    
    16.         Quaternion newRotation;
    17.  
    18.     bool can_be_rotated = false;
    19.  
    20.                                        
    21.     void Update () {
    22.  
    23.         if(Input.touchCount > 0)
    24.         {
    25.             Touch myTouch = Input.GetTouch(0);
    26.  
    27.             if(myTouch.phase == TouchPhase.Began)
    28.             {
    29.                 time_pressed = 0;
    30.                 temp_force_vector = myTouch.position;
    31.             }
    32.  
    33.             if(myTouch.phase != TouchPhase.Ended)
    34.             {
    35.                 time_pressed += 10*Time.deltaTime;
    36.             }
    37.  
    38.             if(myTouch.phase == TouchPhase.Ended)
    39.             {
    40.  
    41.                 can_be_rotated = true;
    42.                 rigidbody.AddRelativeForce(Vector3.up.normalized * time_pressed*150);
    43.                 time_pressed = 0;
    44.                 touchPos = temp_force_vector;
    45.                 touchPos.z = 10.0f; //distance from the camera
    46.                 lookPos = Camera.main.ScreenToWorldPoint(touchPos);
    47.             }
    48.  
    49.  
    50.         }
    51.  
    52.         if(can_be_rotated==true){
    53.  
    54.             test_vector2 = lookPos - this.gameObject.transform.position;
    55.        
    56.             newRotation = Quaternion.LookRotation(this.gameObject.transform.position - lookPos, Vector3.forward);
    57.             newRotation.x = 0f;
    58.             newRotation.y = 0f;
    59.             transform.rotation = Quaternion.Slerp(transform.rotation, newRotation, 20*Time.deltaTime);
    60.  
    61.             if(Vector2.Angle(Vector3.zero - this.gameObject.transform.up, Vector3.zero -  test_vector2.normalized) < 10 )
    62.                 can_be_rotated = false;
    63.  
    64.         }
    65.  
    66.         rigidbody.velocity = transform.up * rigidbody.velocity.magnitude;
    67.  
    68.         /*
    69.         Debug.DrawLine(Vector3.zero , this.gameObject.transform.up, Color.red);
    70.         Debug.DrawLine(Vector3.zero , test_vector2.normalized, Color.green);
    71.         */
    72.     }
    73.  
    what this makes is:

    when u press it will add force to forward of object/player and will slowly rotate towards touch point(but will use addrelativeforce as movment). when it will face it - cant be turned again (block orbiting around touch point).

    Soon i will add: if it is close enough to touchpoint - block rotation, also clsoer touch is - faster it will rotate.

    If anyone can check that code i will appreciate that.
    Thanks