- Home /
Have 2D Sprite Follow the Mouse in Straight Line
First Question: Have 2D Sprite Follow the Mouse
Alright so I am creating a "2D Tank" game where the player controls a 2D tank that you move around with your mouse. It simply will follow the mouse around. What I'm stuck on is actually getting that to work :-\ I've tried everything that I am aware of, but I just can't get it to move the way I would like it too.
It would simply move at a slow speed and follow wherever the mouse is, and if it ever reaches the mouse it just stays put.
So to my understanding it would move the X and Y to the mouse. Could anybody help me with some example code? I just need the basic, everything else I can pretty much do myself. Even just a link to a Doc would be amazing.
Here is some code I have:
private var mouseX: int;
private var mouseY: int;
function Update() {
mouseX = Input.mousePosition.x;
mouseY = Input.mousePosition.y;
worldPos = camera.main.ScreenToWorldPoint(Vector3(mouseX, mouseY, 10));
if (worldPos.y > transform.position.y) {
transform.Translate(Vector3.up * Time.deltaTime);
} else if (worldPos.y < transform.position.y) {
transform.Translate(Vector3(0, -1, 0) * Time.deltaTime);
}
if (worldPos.x > transform.position.x) {
transform.Translate(Vector3.right * Time.deltaTime);
} else if (worldPos.x < transform.position.x) {
transform.Translate(Vector3(-1, 0, 0) * Time.deltaTime);
}
}
This, however, causes the tank to drive faster one way (Y or X) and then even out, rather than move in a straight line. Here is an image of what I mean:
Updated the question with what I actually need, I found out my other question about rotation already. I just need to know how to get the 2D Sprite to follow the mouse in a straight line now.
Answer by hunter789 · Jan 18, 2012 at 01:33 AM
First thing I'd check is if worldPos
gives a logical position. If your input data is bad, your output result will of course be as bad ;)
Then :
Algorithm:
DistanceBetweenDestinationAndTank = SquareRoot((Destination.x - Tank.x)^2 + (Destination.y - Tank.y)^2)
// The following allows the tank to go always at the same speed, without going over the mouse position
MaxDistance = TankSpeedPerSecond * TimeSinceLastFrameInSeconds
If DistanceBetweenDestinationAndTank > MaxDistance Then
DistanceToGo = MaxDistance
Else
DistanceToGo = DistanceBetweenDestinationAndTank
EndIf
// Unit vector is of length 1, but with the correct orientation
UnitVector.x = (Destination.x - Tank.x)/DistanceBetweenDestinationAndTank
UnitVector.y = (Destination.y - Tank.y)/DistanceBetweenDestinationAndTank
// Get the vector at the desired length, which give the x/y movement required
TranslationVector.x = UnitVector.x * DistanceToGo
TranslationVector.y = UnitVector.y * DistanceToGo
// Update the tank position with the calculated translation
Tank.x = Tank.x + TranslationVector.x
Tank.y = Tank.y + TranslationVector.y
^2
means to put that value at square (value*value). Check your language proper syntax for that.
I hope this helps :)
Here is my code - http://pastebin.com/jvgCftw2
For some reason, even though everything looks correct, my tank is moving AWAY from my mouse and doesn't stop. Did I do something wrong? :O
Yes, but it's only because I gave bad indications :P I've updated my answer: you have to swap tankObject.position
with worldPos
when calculating (x|y)Position
and UnitVector
.
That worked perfectly! :) Thank you Hunter!
Now I just have to figure out how to get this to work with a Bullet as well... I'm thinking of just duplicating the script but ins$$anonymous$$d of going to the mouse, have it keep going in the direction of the mouse unless it collides with another Object.
Also, when the Tank is located on the mouse, I get this error:
transform.position assign attempt for 'Blue Tank' is not valid. Input position is { 4.508229, NaN, 0.000000 }. UnityEngine.Transform:set_position(Vector3)
Np :) Don't forget to accept the answer as it could prove useful for other users.
For your bullet, on the mouseclick, compute the unit vector immediately and keep that value in a variable of the bullet (as all the bullets won't go in the same direction). Then use that value to compute translation every frame!
I think you should let Unity manage the collision, as it can be really tricky ;)
Have fun!
Oh, by the way, I have left the answer open for edit, perhaps you could post your code below the algorithm there!
Answer by Sericet · Jan 17, 2012 at 01:48 AM
I'm new to unity but this should work, In your update function create a variable that holds the position of the mouse, this will be updated every sec. Make another one that holds the position of your tank.
Make an if statement like so.
If ( mouse.position.x>tank.position.x) { Tank.position.x+=speed; } Else { Tank.position.x-=speed; }
This causes my tank to fly across the world uncontrollably.