Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Addforce, ForceMode.Acceleration

Discussion in 'Scripting' started by denis-andreevich, Aug 23, 2016.

  1. denis-andreevich

    denis-andreevich

    Joined:
    Aug 21, 2016
    Posts:
    50
    Hi, how are you Game Devs?
    I'm practice with AddForce in Unity 5.4.
    I was faced with problem. The idea, click on Sphere, which will roll on surface. But when I click on the sphere, it rolls anywhere and often, in whatever part of the sphere I'm not pressed, her movements are always repeated.
    I made a small scene at the URL:
    http://денис-андреевич.рф/wp-content/uploads/web/

    Tell me in theory, how to force Sphere roll only forward?
    Thanks, Denis.
     
  2. denis-andreevich

    denis-andreevich

    Joined:
    Aug 21, 2016
    Posts:
    50
    What I'm expecting. When I click on the center of the sphere, it will go straight to the end. But in fact, the sphere behaves very predictable. Though often the movements are repeated.
     

    Attached Files:

  3. lloydsummers

    lloydsummers

    Joined:
    May 17, 2013
    Posts:
    343
    I'd really need to see the scripts to be honest.

    It will only roll the wrong way for two reasons. It collided with a collider. Or it had the force applied in the wrong place.
     
  4. NoBrainer-David

    NoBrainer-David

    Joined:
    Jan 5, 2014
    Posts:
    34
    It might be a wrong vector transformation or any number of things. I doubt anyone can help you without seeing some code.
     
  5. DonLoquacious

    DonLoquacious

    Joined:
    Feb 24, 2013
    Posts:
    1,667
    "Forward" is really dependent on the angle and direction of the camera to the object, and not the object's current rotation. What I think you'd need to do is raycast to the point you click on the screen (Camera.ScreenPointToRay then raycast against the sphere's layer), then if the sphere is hit, grab the position the hit is made (this is given in the result of a RaycastHit). Take that hit position, use the sphere's Transform.InverseTransformPoint(hitPosition) to get a local vector direction from that point to the center of the sphere, and apply the force in the OPPOSITE of that vector to the sphere's rigidbody. That way, you can click the side of the sphere and force it to move to the side, or click right in the middle and force it to move forward (like playing pool).

    If, instead, you only want to move it perfectly forward in relation to the camera, then instead of Camera.ScreenPointToRay on the click position, just use the camera's current rotation as the basis for the force being applied (not the sphere, since you have no way of knowing how the sphere is rotated at any given time).
     
  6. denis-andreevich

    denis-andreevich

    Joined:
    Aug 21, 2016
    Posts:
    50
    Source very simple:
    Code (csharp):
    1.  
    2. public class mouse : MonoBehaviour {
    3.  
    4.     public Renderer rd;
    5.     public Rigidbody rb;
    6.     public float force = 900;
    7.  
    8.     // Use this for initialization
    9.     void Start () {
    10.         rd = GetComponent<Renderer>();
    11.         rb = GetComponent<Rigidbody>();
    12.     }
    13.  
    14.     // Update is called once per frame
    15.     void Update () {
    16.      
    17.     }
    18.  
    19.     void OnMouseDown()
    20.     {
    21.         Debug.Log("Click!");
    22.         rb.AddForce(-transform.forward * force, ForceMode.Acceleration);
    23.     }
    24.  
    25.     void OnMouseEnter()
    26.     {
    27.         Debug.Log("Entered");
    28.         rd.material.color = Color.red;
    29.     }
    30.  
    31.     void OnMouseExit()
    32.     {
    33.         rd.material.color = Color.white;
    34.     }
    35. }
    36.  
    I understand that you wanted to tell me.
     
  7. DonLoquacious

    DonLoquacious

    Joined:
    Feb 24, 2013
    Posts:
    1,667
    Yeah, if it's just "pushing it straight in one direction regardless of where you click on it", try just using the Transform.forward for the camera * force, instead of the Transform.forward for the sphere. You really have no idea which direction the sphere will be facing.
     
  8. NoBrainer-David

    NoBrainer-David

    Joined:
    Jan 5, 2014
    Posts:
    34
    Being a bit pedantic, but using camera.transform.forward would only be correct for the center-most pixel or when you are using an orthographic camera.

    See Camera.ScreenPointToRay for how to get a direction from a pixel. Then apply the direction of this ray as the force to the object.

    Edit: Sorry, Lysander, I just realized you posted all of that above.
     
    Last edited: Aug 23, 2016
  9. denis-andreevich

    denis-andreevich

    Joined:
    Aug 21, 2016
    Posts:
    50
    This is incredible. I just wanted to push the subject forward. Thanks for the help :)
     
  10. DonLoquacious

    DonLoquacious

    Joined:
    Feb 24, 2013
    Posts:
    1,667
    @DerDude87 Not pedantic, no worries, but I chose the less precise approach here for a reason. ScreenPointToRay was mentioned, and it works great for the more dynamic use-case I first outlined, but the impression I got from the screenshot and description is "forward in relation to the camera". If the camera is imprecisely placed behind the sphere by even a small margin (whether accidentally, or by design as an over-the-shoulder kind of view), using ScreenPointToRay would cause a trajectory that's also slightly skewed to the side, whereas the camera's transform.forward will give a clear +Z movement away.

    On the other hand, if the sphere is placed precisely centered in the camera's view, both options will give the same results. Ideally, the Y value of the vector should be manually zeroed out of the force being imparted in both cases. It's worth noting that, in the screenshot, the ScreenPointToRay approach would actually be a more jarring vertical force here if that step is skipped (as the sphere is in the bottom half of the camera's view, it would impart a lot of force in a downward angle).

    Just wanted to clarify my reasoning a bit there ^_^. Good luck denis!
     
    Last edited: Aug 23, 2016
  11. ericbegue

    ericbegue

    Joined:
    May 31, 2013
    Posts:
    1,353
    I guess what you want, at the end, is to be able to "poke" the ball around using the mouse.
    If that the case, you would need to determine where the mouse pointer is on the ball. You can get that position by raycasting the mouse pointer from the camera to the ball. Then you'll obtain where ray hits the ball, that's where you want to apply your force using AddForceAtPosition.