- Home /
How could I play the correct animations for a character who always rotates to look at the mouse, but takes World relative input?
I appreciate any and all help. I am creating a 3RD person game where my character moves along and x and z axis, and rotates along the y axis to look at the mouse. If I press up, he goes forward relative to the world. Likewise if I press down, he goes down, but while he does this, he is always looking at the mouse. It's aiming.
Now here is the problem: I have no way of knowing whether he is going forward, backward, left, or right, relative to himself, and because of this his animations are off. For example, he could be running straight to the left, but be turned to the right and be animated as though he were running to the right.
Here is the code I use to make him look at the mouse:
var playerPlane = new Plane (Vector3.up, transform.position);
var ray = Camera.main.ScreenPointToRay (Input.mousePosition);
var hitdist = 0.0;
if (playerPlane.Raycast (ray, hitdist)){
var targetPoint = ray.GetPoint (hitdist);
var targetRotation = Quaternion.LookRotation(targetPoint - transform.position);
transform.rotation = targetRotation;
}
And here is the code I use to make him move:
//basic horizontal movement
var horizontalMove : float = Input.GetAxis ("horizontal");
transform.Translate (Vector3(horizontalMove, 0, 0) * (Time.deltaTime * globalVariables.speed), Space.World);
//basic vertical movement
var verticalMove : float = Input.GetAxis ("vertical");
transform.Translate (Vector3(0, 0, verticalMove) * (Time.deltaTime * globalVariables.speed), Space.World);
And lastly, here is the code I use to set up mecanim animations:
//animation
if (verticalMove !=0 || horizontalMove !=0){
if (globalVariables.speedUpgrade == 1){
anim.SetBool("walking", true);
}
else{
anim.SetBool("running", true);
}
}
else{
if (globalVariables.speedUpgrade == 1){
anim.SetBool ("walking", false);
}
else
{
anim.SetBool ("running", false);
}
}
if (!grounded){
anim.SetBool("jumping", true);
}
else {
anim.SetBool ("jumping", false);
}
What I would like to accomplish is to have his running animation be relative not to the direction he is facing, but the direction he is moving. So say he is moving left, faced right, in that case I would want to play a "running backwards" animation. Thank you in advance for any and all help. I've been spending countless hours trying to figure this out and I don't know where else to ask. I appreciate all help.
Assu$$anonymous$$g that the character is facing towards the mouse cursor, all you would need to do is to check which side of the character the mouse cursor is located at. Say, the mouse cursor is on the right side of the screen and the character a bit to the left of the cursor, the character will be facing right, right? So if that's the case and you'd move right you would play the animation normally, but if you were to press left you'd play the animation backwards.
So something like this should work...
function moveRight(){//just for the right side button
if(mousePosition.x > playerPosition.x){
///play forward animation normally
} else {
//play animation backwards
}
}
The syntax is most probably incorrect, but you should get the idea..
Hmm I have been trying to get this just right since I've read your answer, but my problem seems to be that the mouse position is kind of random. When I use Input.mousePosition.y to get the coordinates of the mouse, it gives me wild numbers that are somehow way off from the actual world coordinates. If I could work around this I think my problem would be solved.
How are you trying to do that? Perhaps the value that you get is wrong because you keep moving the mouse, but the value stays the same from the point on where you got it? Or perhaps you are getting the wrong coordinates in world space? I can imagine that you would probably want to check the cursors coordinates in 3D space rather than screenSpace since the character is also moving in 3D, right? $$anonymous$$ake sure that you're not comparing 2D and 3D coordinates there.
Well, I managed to solve the problem. Although admittedly it is by no means an elegant solution, and I am sure that someone more experienced than I would have a much better way of doing it. But here it is anyways, in case anyone comes across this in the future with the same problem and needs a quick fix.
Simply put, what I did was create an object named direction tracker, and made it a child of the player object. I moved it slightly forward in the z axis, and then used it to check what direction the player is looking. And then, based on that, I went through every possible input combination manually, to deter$$anonymous$$e what animation should be played. Here is the code I used (I used this block twice, once for when the player faces upwards, and once when he faces down).
if (directionTracker.transform.position.z > transform.position.z){//if player is looking forward
if (vertical$$anonymous$$ove > 0 && horizontal$$anonymous$$ove == 0){//if player presses up
anim.SetBool ("walkback", false);
anim.SetBool("walking", true);
}
else if (vertical$$anonymous$$ove > 0 && horizontal$$anonymous$$ove > 0){//if player presses up and right
anim.SetBool ("walkback", false);
anim.SetBool("walking", true);
}
else if (vertical$$anonymous$$ove > 0 && horizontal$$anonymous$$ove <0){//if player presses up and left
anim.SetBool ("walkback", false);
anim.SetBool("walking", true);
}
else if (vertical$$anonymous$$ove < 0 && horizontal$$anonymous$$ove == 0){//if player presses down
anim.SetBool ("walkback", true);
anim.SetBool("walking", false);
}
else if (vertical$$anonymous$$ove < 0 && horizontal$$anonymous$$ove > 0){//if player presses down and right
anim.SetBool ("walkback", true);
anim.SetBool("walking", false);
}
else if (vertical$$anonymous$$ove < 0 && horizontal$$anonymous$$ove < 0){//if player presses down and left
anim.SetBool ("walkback", true);
anim.SetBool("walking", false);
}
else if (vertical$$anonymous$$ove == 0 && horizontal$$anonymous$$ove > 0){//if player presses right
if (directionTracker.transform.position.x > transform.position.x){//if the player is looking right while pressing right
anim.SetBool ("walkback", false);
anim.SetBool("walking", true);
}
else if (directionTracker.transform.position.x < transform.position.x) {//if the player is looking left while pressing right
anim.SetBool ("walkback", true);
anim.SetBool("walking", false);
}
}
else if (vertical$$anonymous$$ove == 0 && horizontal$$anonymous$$ove < 0){//if player presses left
if (directionTracker.transform.position.x > transform.position.x){//if the player is looking right while pressing left
anim.SetBool ("walkback", true);
anim.SetBool("walking", false);
}
else if (directionTracker.transform.position.x < transform.position.x){//if the player is looking left while pressing left
anim.SetBool ("walkback", false);
anim.SetBool("walking", true);
}
}
else{
anim.SetBool ("walkback", false);
anim.SetBool("walking", false);
}
}