- Home /
Rotating the player animation also rotates the player
I'm pretty new to unity and C# in general, but I'm having this issue I've been struggling with for a while. I'm working on a 2D platformer in my spare time, and early on figured out rigidbody for this style of game was a very bad idea, so I'm using raycasting, which is working amazingly and gives me a lot more control. Issue is, I applied animations to the character and am having issues flipping the sprite.
The big problem for me is whenever i flip the animation, it also seems to flip my controls. This results in me hitting left and moving fine, but when i hit right my character will flip correctly with the animation but continue moving left. I didn't have this problem with a similar setup using rigidbody but now I can't seem to figure out the cause.
I have two scripts relevant to this, the primary one is my input script. The other one is my physics script, which is only relevant because I'm referencing its directionalInput. I have tried merging these two together and got the same result, but here is my input script:
using UnityEngine;
using System.Collections;
[RequireComponent(typeof(CharPhysics))]
public class CharInput :MonoBehaviour {
CharPhysics player;
CharController playerInput;
private Animator anim;
[HideInInspector]
public bool facingRight = true;
void Start() {
player = GetComponent<CharPhysics>();
anim = GetComponent<Animator>();
playerInput = GetComponent<CharController>();
}
//Used to set the input controls on the player
void Update() {
Vector2 directionalInput = new Vector2(Input.GetAxisRaw("Horizontal"),Input.GetAxisRaw("Vertical"));
player.SetDirectionalInput(directionalInput);
Animate(directionalInput);
if (Input.GetButtonUp("Jump")) {
player.OnJumpInputUp();
}
}
void Flip() {
facingRight = !facingRight;
anim.transform.Rotate(0,180,0);
}
void Animate(Vector2 directionalInput) {
if (Mathf.Abs(directionalInput.x) > 0) {
anim.SetFloat("Move",Mathf.Abs(directionalInput.x));
} else {
anim.SetFloat("Move",0.0f);
}
if (directionalInput.x < 0 && !facingRight) {
Flip();
} else if (directionalInput.x > 0 && facingRight) {
Flip();
}
}
}
Here is the "physics" script:
using UnityEngine;
using System.Collections;
[RequireComponent (typeof (CharController))]
public class CharPhysics : MonoBehaviour {
float moveSpeed = 6; //Determines X axis movement. Uses no hard coded values outside of itself
float arialAcceleration = .2f; //Control while in air. Higher numbers for less control.
float groundedAcceleration = .1f; //Control while on the ground. Higher numbers for less control.
public float maxJumpHeight = 4;
public float minJumpHeight = 1;
public float timeToJump = .4f;
public float wallSlideSpeedMax = 3;
public Vector2 wallLeap;
public Vector2 wallFall;
public bool doubleJump;
Vector3 velocity; //Direction player is moving??
float velocityXSmoothing; //Used to determine accelleration in ground and air [See <<PHYSICS UPDATE>>]
float gravity; //Uses jumpHeight and timeToJump to get the gravity of the player (mostly determines height)
float maxJumpVelocity;
float minJumpVelocity;
CharController controller;
Vector2 directionalInput;
bool wallSliding;
int wallDirX;
private Animator anim;
//**Sets up gravity based off jump time/height and gets components**//
void Start () {
controller = GetComponent<CharController> ();
//<<JUMP FORMULA>>//
gravity = -(2 * maxJumpHeight) / Mathf.Pow(timeToJump, 2);
maxJumpVelocity = Mathf.Abs(gravity) * timeToJump;
minJumpVelocity = Mathf.Sqrt (2 * Mathf.Abs (gravity) * minJumpHeight);
print ("Gravity: " + gravity + " Jump Velocity: " + maxJumpVelocity);
}
void Update() {
CalculateVelocity();
HandleWallSliding();
//<<PHYSICS UPDATE>>//
controller.Move(velocity * Time.deltaTime,directionalInput);
//**Sets velocity to 0 while having a vertical collision. Without this, rays get longer and adds gravity**//
if (controller.collisions.above || controller.collisions.below) {
velocity.y = 0;
}
}
public void SetDirectionalInput (Vector2 input) {
directionalInput = input;
}
//Used to control jump inputs from the player
public void OnJumpInputUp() {
if (velocity.y > minJumpVelocity) {
velocity.y = minJumpVelocity;
}
}
public void OnJumpInputDown() {
if (wallSliding) {
if (directionalInput.x == 0) {
velocity.x = -wallDirX * wallFall.x;
velocity.y = wallFall.y;
} else {
velocity.x = -wallDirX * wallLeap.x;
velocity.y = wallLeap.y;
}
}
if (controller.collisions.below) {
velocity.y = maxJumpVelocity;
doubleJump = true;
anim.SetTrigger("Grounded");
} else {
if (doubleJump && !wallSliding) {
doubleJump = false;
velocity.y = maxJumpVelocity / 1.5f;
}
}
}
//TODO: Comment for wall slide
void HandleWallSliding() {
wallDirX = (controller.collisions.left) ? -1 : 1;
wallSliding = false;
if ((controller.collisions.left || controller.collisions.right) && !controller.collisions.below && velocity.y < 0) {
wallSliding = true;
if (velocity.y < -wallSlideSpeedMax) {
velocity.y = -wallSlideSpeedMax;
}
}
}
//TODO: Comment for Velocity
void CalculateVelocity () {
float targetVelocityX = directionalInput.x * moveSpeed;
velocity.x = Mathf.SmoothDamp(velocity.x,targetVelocityX,ref velocityXSmoothing,(controller.collisions.below) ? groundedAcceleration : arialAcceleration);
velocity.y += gravity * Time.deltaTime;
}
}
I've mostly learned from random tutorials and piecing things together, just kinda messing around and learning, so excuse any bad coding please!
Anyone have any ideas?
Answer by Shlankwald · Oct 12, 2016 at 03:22 AM
So found the fix. instead of rotating the animation, I just flipped the sprite renderer.... Not really sure why one works but not the other, the result is still the same.
flip.flipX = !flip.flipX;
Answer by jrocamora · Oct 12, 2016 at 06:56 PM
The problem was that you were flipping the transform that the animator used, which other parts of your object also references for coordinates.