Jittery 3D Turning
I've been trying to make a player character that will move around based on the perspective of an isometric camera looking at it. The catch is that when the character is facing away from the direction you want it to go, it will only rotate until it faces close enough to the inputted direction. My problem is that turning certain ways causes the character to stop moving sporadically. I used transform.forward to see where the player is facing and made a Vector3 called keyHeading to see where the inputted direction want the player to go.
Sorry if the code is weird/sloppy, I'm super new to the whole thing.
Thank you!
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TankMovement : MonoBehaviour
{
//variables dictating key direction
Vector3 keyVertical, keyHorizontal;
//variables that will indicate camera orientation
Vector3 camVertical, camHorizontal;
//variables dictating player model heading and speed
public float maxSpeed = 5f;
public float minSpeed = 0f;
public float acceleration = 0.5f;
public float deceleration = 1f;
private float curSpeed = 0.0f;
//variables to smooth vectors
public float smoothHeading = 0.125f;
bool sameHeading;
void Start()
{
//set camera variables to camera orientation
camVertical = Camera.main.transform.forward;
camVertical.y = 0;
camVertical = Vector3.Normalize(camVertical);
camHorizontal = Quaternion.Euler(new Vector3(0, 90, 0)) * camVertical;
}
void Update()
{
//run the movement meathod every frame
if (Input.anyKey)
{
Rotate();
ShouldMove();
}
//check current speed
Acceleration();
}
void Rotate()
{
//use vectors that tell if left/right/up/down are pressed
keyHorizontal = camHorizontal * curSpeed * Time.deltaTime * Input.GetAxis("HorizontalKey");
keyVertical = camVertical * curSpeed * Time.deltaTime * Input.GetAxis("VerticalKey");
//create a vector that points in the combined direction of pressed a/d/w/s buttons
Vector3 keyHeading = Vector3.Normalize(keyHorizontal + keyVertical);
//player model is rotated to match keyheading
transform.forward += keyHeading + transform.forward;
}
void Acceleration()
{
transform.position += transform.forward * curSpeed * Time.deltaTime;
if (Input.anyKey && sameHeading == true)
{
curSpeed += acceleration * Time.deltaTime;
}
else
{
curSpeed -= deceleration * Time.deltaTime;
}
if (curSpeed > maxSpeed)
curSpeed = maxSpeed;
if (curSpeed < minSpeed)
curSpeed = minSpeed;
}
void ShouldMove()
{
//variable to reference player model heading
float playerHeading = transform.eulerAngles.y;
//use vectors that tell if left/right/up/down are pressed
keyHorizontal = camHorizontal * curSpeed * Time.deltaTime * Input.GetAxis("HorizontalKey");
keyVertical = camVertical * curSpeed * Time.deltaTime * Input.GetAxis("VerticalKey");
//create a vector that points in the combined direction of pressed a/d/w/s buttons
Vector3 keyHeading = Vector3.Normalize(keyHorizontal + keyVertical);
//check up
if (keyHeading.x >= 0 && keyHeading.z >= 0 && playerHeading >= 0 && playerHeading <= 90)
{
sameHeading = true;
}
//check down
else if (keyHeading.x <= 0 && keyHeading.z <= 0 && playerHeading >= 180 && playerHeading <= 270)
{
sameHeading = true;
}
//check left
else if (keyHeading.x <= 0 && keyHeading.z >= 0 && playerHeading >= 270 && playerHeading <= 360)
{
sameHeading = true;
}
//check right
else if (keyHeading.x >= 0 && keyHeading.z <= 0 && playerHeading >= 90 && playerHeading <= 180)
{
sameHeading = true;
}
else
{
sameHeading = false;
//Debug.Log("Player Heading = " + playerHeading);
Debug.Log("Key Heading = " + keyHeading);
}
}
}
Answer by lgarczyn · Oct 09, 2019 at 11:22 PM
Your code appears to be very complex to do a simple thing. There are a lot of weird things, like initializing camHorizontal to the normalized y component of camVertical times 90.
To check if the player is going in the same direction as the heading, simply do something like:
float keyAngle = Mathf.Tan(keyHeading.y / keyHeading.x);
if ((int)(keyAngle / 90f) == (int)(playerHeading / 90f))
sameHeading = true;
A somewhat better way would be to use Vector2.Angle
, and calculate if the difference is acceptable, but that's up to you.
Your system to rotate the character is... Bad. I wasn't even aware you could assign a value to transform.forward, but it's not the way to go. Simply apply a RotateAxis
quaternion to transform.rotation
, or use a Slerp or RotateTowards.
I still am not sure what you are doing with camVertical and camHorizontal.
Cleanup this issues could fix your code, but here it's very complicated to guess what is going wrong.
Your answer
Follow this Question
Related Questions
make a gameobject move to another gameobject that was selected by mouse click? 1 Answer
Why is my Camera not rotating properly? 1 Answer
How to Destroy game object horizontally and vertically , when hit by a Raycast 0 Answers
Always wondered how to sync animations with attack effects 0 Answers
My 2d movement script isn't working 0 Answers