Hi there, so right now I’m trying to create the foundation of a third-person adventure game like not really like Tomb Raider but I’m playing it right now and it gave me inspiration to work on something with the same movement and controls. I am designing it around the usage of an xbox controller as I just had shoulder surgery and keyboard and mouse isn’t really possible for me. So the movement is meant to be centered around joystick movement. Not sure if that’s necessary information, but I’m trying to be thorough.
So I have the character controller set-up and I want it to:
Rotate to face the direction the joystick is being pushed and then start moving in that direction
Move dependent on the direction the camera is facing.
If the camera is moved forward is always moving away from the camera.
Here is the code I’m using, it is mainly just the Controller.Move API reference material and some mecanim stuff.:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovement : MonoBehaviour {
public float speed = 6.0f;
private float playerSpeed;
private float playerDirection;
public float jumpSpeed = 8.0f;
public float gravity = 20.0f;
Vector3 moveDirection = Vector3.zero;
Quaternion targetRotation;
public float rotationSpeed = 0.7f;
private Animator anim;
private void Start()
{
anim = GetComponent<Animator>();
}
// Update is called once per frame
void Update () {
CharacterController character = GetComponent<CharacterController>();
if (character.isGrounded)
{
moveDirection = new Vector3(Input.GetAxisRaw("Horizontal"), 0, Input.GetAxisRaw("Vertical"));
if(moveDirection != Vector3.zero)
{
transform.forward = moveDirection;
}
moveDirection = transform.TransformDirection(moveDirection);
moveDirection *= speed;
playerSpeed = Input.GetAxisRaw("Vertical");
playerDirection = Input.GetAxisRaw("Horizontal");
if (Input.GetButton("Jump"))
{
moveDirection.y = jumpSpeed;
}
}
moveDirection.y -= gravity * Time.deltaTime;
character.Move(moveDirection * Time.deltaTime);
anim.SetFloat("Speed", playerSpeed);
}
}
So you can see I tried to use transform.forward but that turns the character instantly which I know I can fix using a Quaternion.Slerp but it then strafes instead of then moving to the right of the camera.
Any help would be appreciated thanks!
If you need reference material from the game I can provide that too if you have not played it.
you actually want to use the camera forward(after flattening it on the y axis) and right vectors. then you just need to rotate your players forward vector to match the cameras forward vector. so the move direction would actually be:
after that you could then rotate your players forward to match the direction, or, get the angle and speed at feed that to the animator to move with animations, if you wanted to.
I think I can solve the instantaneous turning with something like Quaternion.Slerp(transform.rotation, Quaternion.LookRotation, rotationSpeed * Time.deltaTime) but the relative movement to the camera is the biggest thing I’m stumped on and haven’t found anything helpful through a lot of Googling.
Relative to the camera is a little tough because the camera is facing downwards. One thing you might try is parenting the camera to an empty, and moving the empty around. That would be at least facing in the direction we sort of think the camera is facing. Then I think you would use the camera parent transform forward, right, and back rather than the player. I haven’t done any of this, btw. There are all kinds of 3rd person controller vids on youtube that would probably be helpful.
In that implementation horizontal movement of the analog stick either to the left or right causes the character to move forward and backward. I attempted implementing the rotation as it was before but this doesn’t seem to work. I’m assuming the forward and backward movement is intended as if the character rotates sideways it would then be continuing to move forward? I could be wrong here though.
EDIT: Oof I see the mistake with using transform.forward twice. I will do some more tests.
Well my camera is actually facing forwards in a behind the back sort of thing, I’ve looked into a few of the youtube ones that I’ve found which seem to want to make tank controls rather than what I’m trying to implement. It also saves on needed animations as I can just use the same walk to jog animation in every direction.
So after fixing the movement which works exactly as I wanted my issue now falls on the proper rotation as using transform.forward cause the character to turn and face to the right but then begin sliding to it’s now right or towards the camera rather than continue to run to what would now be forwards. Does this have to do with where I am implementing the rotation? I think it needs to be checking what direction the camera is facing after the direction change.
//move dir is as before
float smoothing = 5;
Quaternion desiredRotation = Quaternion.LookDirection(moveDir);
playerTransform.rotation = Quarternio. Slerp(playerTransfor.rotation, moveDir, smoothing * Time.deltaTime) ;
Keep in mind that to move the character controller you want to either use root motion, or you want to move it using the cameras forward and right vectors, not the players vectors.
This is with the additions, where you included moveDirection isn’t allowed since it’s a Vector3 so I assumed you meant the targetRotaion/ desiredRotation value.
Yes! That is exactly what I was looking for! Thanks so much for the help! Sorry I didn’t get back to you sooner had some stuff going on. I greatly appreciate the time you took to help me.