Controller keeps facing north when there are no imputs

Updated 2 days ago in Answers
Share on Facebook0Tweet about this on TwitterShare on Google+0Share on Reddit0
8 on June 9, 2018

This is super annoying and I’m probably missing something simple but my character only faces the direction he is moving in if I’m controlling it. When the character stays still. It faces north.

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Playables;
 
public class Aerial_Controler : MonoBehaviour {
 
public CharacterController MyController;
 // Update is called once per frame
 public float GroundSpeed = 7f;
 public float CurrentSpeed;
 public float SprintSpeed = 10f;
 public float TimeZeroToMax = 2.5f;
 float accelRatePerSec;
 public float AerialSpeed = 2f;
 public float GravityStrength = 5f;
 public float JumpSpeed = 10f;
 public Transform CameraTransform; 
 bool canJump = false;
 float verticalVelocity;
 Vector3 velocity;
 Vector3 groundedVelocity;
 Vector3 normal;
 bool onWall = false;
 
private void Start()
 {
 accelRatePerSec = SprintSpeed / TimeZeroToMax;
 CurrentSpeed = 0f;
 MyController = GetComponent();
 
}
 
void Update()
 {
 bool run = Input.GetKey(KeyCode.M);
 
 if (run)
 {
 CurrentSpeed += accelRatePerSec * Time.deltaTime;
 CurrentSpeed = Mathf.Min(CurrentSpeed, SprintSpeed);
 }
 
else
 {
 CurrentSpeed = GroundSpeed;
 }
 
if (Input.GetKeyUp(KeyCode.M))
 {
 CurrentSpeed += accelRatePerSec * Time.deltaTime;
 CurrentSpeed = Mathf.Max(GroundSpeed, CurrentSpeed);
 }
 
if (run && !MyController.isGrounded)
 {
 CurrentSpeed = GroundSpeed + AerialSpeed;
 }
 
Physics.IgnoreLayerCollision(9, 10);
 
Vector3 myVector = Vector3.zero;
 
//get input from the player
 Vector3 input = Vector3.zero;
 input.x = Input.GetAxis("Horizontal");
 input.z = Input.GetAxis("Vertical");
 input = Vector3.ClampMagnitude(input, 1f);
 transform.rotation = Quaternion.LookRotation(groundedVelocity);
 
 if (MyController.isGrounded)
 {
 myVector = input;
 //Quaternion inputRotation = Quaternion.LookRotation(Vector3.ProjectOnPlane(CameraTransform.forward, Vector3.up), Vector3.up);
 //myVector = inputRotation * myVector; //rotate input by direction of the camera
 myVector *= CurrentSpeed;
 }
 else
 {
 //Quaternion inputRotation = Quaternion.LookRotation(Vector3.ProjectOnPlane(CameraTransform.forward, Vector3.up), Vector3.up);
 //input = inputRotation * input;
 myVector = groundedVelocity;
 myVector += input * AerialSpeed;
 }
 
myVector = Vector3.ClampMagnitude(myVector, CurrentSpeed);
 myVector = myVector * Time.deltaTime;
 
 verticalVelocity = verticalVelocity - GravityStrength * Time.deltaTime;
 if (Input.GetButtonDown("Jump"))
 {
 if (onWall)
 {
 Vector3 reflection = Vector3.Reflect(velocity, normal);
 
Vector3 projected = Vector3.ProjectOnPlane(reflection, Vector3.up);
 groundedVelocity = projected.normalized * CurrentSpeed + normal * AerialSpeed;
 }
 //add Jumped to vertical velocity
 if (canJump)
 verticalVelocity += JumpSpeed;
 }
 myVector.y = verticalVelocity * Time.deltaTime; //add new speed, to old speed, for acceleration
 
//use input to move the character
 CollisionFlags flags = MyController.Move(myVector);
 velocity = myVector / Time.deltaTime;
 print(velocity);
 //use flags to determine if character can jump or not
 //if on ground
 //set canJump to true
 if ((flags & CollisionFlags.Below) != 0)
 {
 groundedVelocity = Vector3.ProjectOnPlane(velocity, Vector3.up);
 canJump = true;
 verticalVelocity = -3f;
 onWall = false;
 }
 else if ((flags & CollisionFlags.Sides) != 0)
 {
 canJump = true;
 onWall = true;
 }
 else
 {
 canJump = false;
 onWall = false;
 }
 }
 
private void OnControllerColliderHit(ControllerColliderHit hit)
 {
 normal = hit.normal;
 }
}
  • Liked by
Reply
1 on June 10, 2018

How about only updating whatever you use for determining direction when the controller move is in use via an IF Statement?

I’d try give you something more accurate but you haven’t used the code tags so it’s hard to read your code. Using them, your code should look like this:

if( playerPressButton() )
{
    updatePlayerDirectionVector();
}

Try updating your post and/or trying to implement my suggestion if you haven’t already tried to.

on June 10, 2018

Thank you I’ve been trying to figure out how to do that. 

Edit: There we go, is this better?

Show more replies
  • Liked by
Reply
Cancel
5 on June 11, 2018

Here’s how you implement the aforementioned fix (line 52), the whole idea is that you don’t want to update the rotation if there is no input. While you can certainly improve this solution, it does the job.

 public CharacterController MyController;
 // Update is called once per frame
 public float GroundSpeed = 7f;
 public float CurrentSpeed;
 public float SprintSpeed = 10f;
 public float TimeZeroToMax = 2.5f;
 float accelRatePerSec;
 public float AerialSpeed = 2f;
 public float GravityStrength = 5f;
 public float JumpSpeed = 10f;
 public Transform CameraTransform;
 bool canJump = false;
 float verticalVelocity;
 Vector3 velocity;
 Vector3 groundedVelocity;
 Vector3 normal;
 bool onWall = false;
private void Start()
 {
 accelRatePerSec = SprintSpeed / TimeZeroToMax;
 CurrentSpeed = 0f;
 MyController = GetComponent<CharacterController>();
}
void Update()
 {
 bool run = Input.GetKey(KeyCode.M);
if (run)
 {
 CurrentSpeed += accelRatePerSec * Time.deltaTime;
 CurrentSpeed = Mathf.Min(CurrentSpeed, SprintSpeed);
 }
else
 {
 CurrentSpeed = GroundSpeed;
 }
if (Input.GetKeyUp(KeyCode.M))
 {
 CurrentSpeed += accelRatePerSec * Time.deltaTime;
 CurrentSpeed = Mathf.Max(GroundSpeed, CurrentSpeed);
 }
if (run && !MyController.isGrounded)
 {
 CurrentSpeed = GroundSpeed + AerialSpeed;
 }
Physics.IgnoreLayerCollision(9, 10);
Vector3 myVector = Vector3.zero;
Vector3 input = Vector3.zero;
 //get input from the player
 input.x = Input.GetAxis("Horizontal");
 input.z = Input.GetAxis("Vertical");
 input = Vector3.ClampMagnitude(input, 1f);
if (Input.GetAxis("Horizontal") != 0 || Input.GetAxis("Vertical") != 0)
 { 
 transform.rotation = Quaternion.LookRotation(groundedVelocity);
 }
 if (MyController.isGrounded)
 { 
 myVector = input;
 //Quaternion inputRotation = Quaternion.LookRotation(Vector3.ProjectOnPlane(CameraTransform.forward, Vector3.up), Vector3.up);
 //myVector = inputRotation * myVector; //rotate input by direction of the camera
 myVector *= CurrentSpeed;
 }
 else
 {
 //Quaternion inputRotation = Quaternion.LookRotation(Vector3.ProjectOnPlane(CameraTransform.forward, Vector3.up), Vector3.up);
 //input = inputRotation * input;
 myVector = groundedVelocity;
 myVector += input * AerialSpeed;
 }
myVector = Vector3.ClampMagnitude(myVector, CurrentSpeed);
 myVector = myVector * Time.deltaTime;
verticalVelocity = verticalVelocity - GravityStrength * Time.deltaTime;
 if (Input.GetButtonDown("Jump"))
 {
 if (onWall)
 {
 Vector3 reflection = Vector3.Reflect(velocity, normal);
Vector3 projected = Vector3.ProjectOnPlane(reflection, Vector3.up);
 groundedVelocity = projected.normalized * CurrentSpeed + normal * AerialSpeed;
 }
 //add Jumped to vertical velocity
 if (canJump)
 verticalVelocity += JumpSpeed;
 }
 myVector.y = verticalVelocity * Time.deltaTime; //add new speed, to old speed, for acceleration
//use input to move the character
 CollisionFlags flags = MyController.Move(myVector);
 velocity = myVector / Time.deltaTime;
 print(velocity);
 //use flags to determine if character can jump or not
 //if on ground
 //set canJump to true
 if ((flags & CollisionFlags.Below) != 0)
 {
 groundedVelocity = Vector3.ProjectOnPlane(velocity, Vector3.up);
 canJump = true;
 verticalVelocity = -3f;
 onWall = false;
 }
 else if ((flags & CollisionFlags.Sides) != 0)
 {
 canJump = true;
 onWall = true;
 }
 else
 {
 canJump = false;
 onWall = false;
 }
 }
private void OnControllerColliderHit(ControllerColliderHit hit)
 {
 normal = hit.normal;
 }
on June 11, 2018

Thank you for your help. It did work…..Kind of. There is something in this code that is actually forcing this character face north. For one frame the character faces north and if you stand still, then jump. the character faces north when you move around int the air. I think that line of code you told me to right only bypasses what ever is forcing this to happen. I’m not entirely sure how to track this down. This is getting frustrating now lol

on June 11, 2018

I’ve noticed this problem happens if I set the speed to Zero (so that that character doesn’t move) I even use the 

transform.rotation = Quaternion.LookRotation(moveVector);

even with the if statement, and this happens whenever I’m not moving and just looking around.

Devoted
on June 13, 2018

[see below]

Devoted
on June 14, 2018

[FIX]
I think I found the issue when playing around with your code, I found changing how fast the character rotates seems to fix the issue. Just replace your rotation code with this:

 Vector3 NextDir = new Vector3(Input.GetAxisRaw("Horizontal"), 0, Input.GetAxisRaw("Vertical"));
  
 if (NextDir != Vector3.zero)
 {
    transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(NextDir), 0.15f);
 }

2 days ago

Sorry for late reply I did manage to find a solution. I changed this code

 

groundedVelocity = Vector3.ProjectOnPlane(velocity, Vector3.up);

 

To this code

 {
 if (Input.GetAxis("Horizontal") != 0 || Input.GetAxis("Vertical") != 0)
 {
 groundedVelocity = Vector3.ProjectOnPlane(velocity, Vector3.up);
 }
Show more replies
  • Liked by
Reply
Cancel