Reputation: 18
I currently have this script (don't read too much into the code, not everything is pasted here, only what is needed to understand the question):
Touch[] touches = Input.touches;
Vector2 dir = (Camera.main.ScreenPointToRay (touches [i].position).GetPoint (0) - obj.getGameObject ().transform.position).normalized * speed;
obj.getGameObject ().GetComponent<Rigidbody2D> ().velocity = dir;
The problem is that the speed of the rigidbody is different based on distance from the object to the touched point, so the speed will be 2x or more if you touch a point distant from the gameobject, compared to a point close to the gameobject.
How would I go about fixing this, so I can achieve a constant velocity which isn't based on distance from the gameobject?
Upvotes: 0
Views: 590
Reputation: 12258
The core of the problem lies within this line:
Vector2 dir = (Camera.main.ScreenPointToRay (touches [i].position).GetPoint (0) - obj.getGameObject ().transform.position).normalized * speed;
When you calculate this difference between the touch position and the object position with Camera.main.ScreenPointToRay (touches [i].position).GetPoint (0) - obj.getGameObject ().transform.position
, you have to remember that this result may not be 2D - it is a Vector3
. This means that it may have a non-zero z-value, if the result of GetPoint (0)
and transform.position
are not at the same position on the z-axis.
When you normalize the Vector3
, its length becomes 1, but only if its z-value is taken into account. When you store this value in Vector2 dir
, that Vector3
is cast to a Vector2
and its z-value is discarded. This means that the length of the previously-normalized vector is no longer guaranteed to be 1; it can vary anywhere in the range of [0,1].
If you multiply this new Vector2
with speed
and use it to set the velocity of a rigidbody, the magnitude of the rigidbody's velocity will be between 0 and speed
, rather than always speed
. The reason why the object goes faster if your touch is farther, and slower if it is closer, is because the z-value (which will be constant) will become less relative to your x- and y-values the farther away your touch is. Here's an illustration to show how this will affect the cast Vector2
:
Note how casting the normalized Vector3
will result in a longer Vector2
if the z-value is smaller relative to the other values. (The diagram assume x = 0, to make it easier to read.)
Fixing this problem isn't too difficult - you just need to normalize the vector once the z-value has become 0, whether by cast or by explicit assignment. Then your direction is guaranteed to be a length of 1, and your speed will be constant. Here's an example:
Touch[] touches = Input.touches;
Vector3 dirRaw = Camera.main.ScreenPointToRay (touches [i].position).GetPoint (0) - obj.getGameObject ().transform.position;
dirRaw.z = 0;
Vector2 dir = dirRaw.normalized * speed;
obj.getGameObject ().GetComponent<Rigidbody2D> ().velocity = dir;
Hope this helps! Let me know if you have any questions.
Upvotes: 1