- Home /
Rotating player but the forward move vector is fixed, how do I get forward vector to move with player?
I am new to unity and c#, and have been building a game as i learn the UI and c# code. Things have been going good until now. What i am stuck on is how to get the forward vector to move with the player when i rotate. Here is the code, i am using the new input system and have the movement on the left stick of gamepad and the rotate on the right stick. Using the readvalue of the input from the right stick, i pass that to float and use the variable in Quaternion.LookRotation , as said , player rotates and moves ,but the forward vector does not. Also, i have the camera simply attached to a game object that is child of player, no camera follow script, not sure if that has anything to do with problem. Thanks in advance for any help
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Security.Permissions;
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
private PlayerInputActions inputActions;
private Animator animator;
private Vector2 movementInput;
private Rigidbody rb;
private Vector2 rotateInput;
private readonly float moveSpeed = 24.0f;
private float jumpHeight = 10.0f;
private Vector3 inputDirection;
private Vector3 inputRotate;
private Vector3 moveVector;
private Quaternion currentRotation;
private bool isJump;
private bool isAttack2;
private bool isAttack;
private bool isRun;
private bool isSpecial;
private float animationFinishTime = 0.9f;
void Awake()
{
inputActions = new PlayerInputActions();
inputActions.Player.Jump.performed += context => Jump();
inputActions.Player.Special.performed += context => Special();
inputActions.Player.Attack.performed += context => Attack();
inputActions.Player.Attack2.performed += context => Attack2();
inputActions.Player.Movement.performed += context => movementInput = context.ReadValue<Vector2>();
inputActions.Player.Turn.performed += context => rotateInput = context.ReadValue<Vector2>();
animator = GetComponent<Animator>();
rb = GetComponent<Rigidbody>();
}
void FixedUpdate()
{
float h = movementInput.x;
float v = movementInput.y;
float hor = rotateInput.x;
float ver = rotateInput.y;
Vector3 movement = new Vector3(h, 0.0f, v);
transform.rotation = Quaternion.LookRotation(movement);
transform.position += movement * moveSpeed * Time.deltaTime;
// Vector3 targetInput = new Vector3(h, 0f, v);
// inputDirection = Vector3.Lerp(inputDirection, targetInput, Time.deltaTime * 10f);
Vector3 targetRotate = new Vector3(hor, 0f, ver);
inputRotate = Vector3.Lerp(inputRotate, targetRotate, Time.deltaTime * 5f);
animator.SetFloat("isRunX", h);
animator.SetFloat("isRunY", v);
// moveVector.Set(inputDirection.x, 0f, inputDirection.z);
/// moveVector = moveVector * moveSpeed * Time.deltaTime;
//transform.position += moveVector;
if (inputRotate.x > 0.1 || inputRotate.x < -0.1)
{
currentRotation = Quaternion.LookRotation(inputRotate);
transform.rotation = currentRotation;
}
else
transform.rotation = currentRotation;
}
private bool IsGrounded()
{
return Physics.Raycast(transform.position, Vector3.down, 3.0f);
}
void Update()
{
if (isJump && animator.GetCurrentAnimatorStateInfo(1).normalizedTime >= animationFinishTime)
{
isJump = false;
}
if (isSpecial && animator.GetCurrentAnimatorStateInfo(1).normalizedTime >= animationFinishTime)
{
isSpecial = false;
}
if (isAttack2 && animator.GetCurrentAnimatorStateInfo(1).normalizedTime >= animationFinishTime)
{
isAttack2 = false;
}
if (isAttack && animator.GetCurrentAnimatorStateInfo(1).normalizedTime >= animationFinishTime)
{
isAttack = false;
}
}
void Jump()
{
if (!isJump && IsGrounded())
{
rb.AddForce(Vector3.up * jumpHeight, ForceMode.Impulse);
animator.SetTrigger("isJump");
StartCoroutine(InitialiseJump());
}
}
void Special()
{
if (!isSpecial)
{
animator.SetTrigger("isSpecial");
StartCoroutine(InitialiseAttack());
}
}
void Attack2()
{
if (!isAttack2)
{
animator.SetTrigger("isAttack2");
StartCoroutine(InitialiseAttack());
}
}
void Attack()
{ if (!isAttack)
{
animator.SetTrigger("isAttack");
StartCoroutine(InitialiseAttack());
}
}
IEnumerator InitialiseAttack()
{
yield return new WaitForSeconds(0.1f);
isAttack = true;
}
IEnumerator InitialiseJump()
{
yield return new WaitForSeconds(0.1f);
isJump = true;
}
// void Move(Vector3 Direction)
// {
// moveVector.Set(Direction.x, 0f, Direction.z);
// moveVector = moveVector * moveSpeed * Time.deltaTime;
// transform.position += moveVector;
// }
// void Turn(Vector3 Direction)
// {
// if ((Direction.x > 0.1 || Direction.x < -0.1 || Direction.z > 0.1 || Direction.z < -0.1))
// {
// currentRotation = Quaternion.LookRotation(Direction);
// transform.rotation = currentRotation;
// }
// else
// transform.rotation = currentRotation;
// }
private void OnEnable()
{
inputActions.Enable();
}
private void OnDisable()
{
inputActions.Disable();
}
}
Answer by unity_ek98vnTRplGj8Q · Aug 26, 2020 at 09:13 PM
You are setting you movement vectors in terms of world coordinates. The easiest fix for you would be to just apply your characters rotation to you movement variable so that it orients the movement vector relative to the player's orientation rather than relative to the world orientation.
float h = movementInput.x;
float v = movementInput.y;
float hor = rotateInput.x;
float ver = rotateInput.y;
Vector3 movement = (new Vector3(h, 0.0f, v));
transform.rotation = Quaternion.LookRotation(movement);
Vector3 playerMovement = tranform.rotation * movement;
transform.position += playerMovement * moveSpeed * Time.deltaTime;
Thank you for that info, i probably need to declare player$$anonymous$$ovement , i will look through unity docs for this topic,,thank you
I added that to script , and, still have same issue, but i get the concept of what you are saying, i will investigate that avenue
Looking at you code it looks like you are setting the rotation multiple times... make sure you are only moving your character after you are done rotating him, and make sure that the movement vector you use is rotated by the final player rotation. $$anonymous$$y original code probably won't work because you end up re-rotating the player again later in the same function.
thanks again for answer, i figured it out, since there is a significant difference between rigidbody vs. transform translate movement, it seems the physics system needs to know(by creating a variable for rigidbody), which direction is forward, otherwise it defaults to world space.
Your answer
Follow this Question
Related Questions
When I hit play the character rotates 2 Answers
Maybe easy to do, but: How? 2 Answers
how to make NPCs face my player? I'm a beginner 1 Answer
GameObject wont stop rotating ? 1 Answer
Rotating a character 4 Answers