My character moves according to global Vectors
This seems like it should be something simple, i'm moving my character by changing his velocity with a camera locked behind my player, which i can rotate it around and snap it back behind him whenever he change his direction.
The problem is when i move my player, for exemple, to the right and snap the camera behind him to look at his forward vector then try to move forward, my character will move toward the global forward Vector (in this exemple you'll see your character going to the left)
Anyone have any ideas?
Here's My HeroControll Script:
using UnityEngine;
using System.Collections;
[RequireComponent(typeof(Rigidbody))]
[RequireComponent(typeof(Animator))]
[RequireComponent(typeof(CapsuleCollider))]
public class HeroControll : MonoBehaviour {
public float PlayerSpeed,jumpHeight;
public bool grounded,moving;
public GameObject Camera;
private Rigidbody rg;
private Animator anim;
private float forwardInput, turnInput;
private bool runInput;
private int r;
private RaycastHit hit;
// Use this for initialization
void Start () {
rg = GetComponent<Rigidbody>();
anim = GetComponent<Animator>();
forwardInput = turnInput = 0;
jumpHeight = 10f;
PlayerSpeed = 10f;
grounded = true;
moving = false;
}
// Update is called once per frame
void FixedUpdate () {
//Get Inputs
forwardInput = Input.GetAxis("Vertical");
turnInput = Input.GetAxis("Horizontal");
runInput = Input.GetKey(KeyCode.LeftShift);
//Set Animations
if ((turnInput != 0) || (forwardInput != 0))
{
moving = true;
anim.SetBool("walking", true);
}
else
{
moving = false;
anim.SetBool("walking", false);
}
//Update velocity
rg.velocity = new Vector3(PlayerSpeed * turnInput, rg.velocity.y, PlayerSpeed * forwardInput);
//Set Directions
moveDirection = new Vector3(turnInput, 0, forwardInput);
if (moveDirection != Vector3.zero)
{
Quaternion newRotation = Quaternion.LookRotation(moveDirection);
transform.rotation = Quaternion.Slerp(transform.rotation, newRotation, Time.deltaTime * 8);
}
}
}
and My CameraControll Script :
using UnityEngine;
using System.Collections;
public class CameraZelda : MonoBehaviour {
private GameObject player;
private float smooth,orb;
public Transform target;
private Vector3 offset;
// Use this for initialization
void Start () {
player = GameObject.FindGameObjectWithTag("Player");
smooth = 30f;
offset = player.transform.position - transform.position;
}
// Update is called once per frame
void Update () {
transform.position = player.transform.position - offset;
orb = Input.GetAxis("orb");
transform.RotateAround(player.transform.localPosition, Vector3.up, smooth * orb * Time.deltaTime);
changeTarget();
}
void changeTarget()
{
if (Input.GetKey(KeyCode.C))
{
transform.position = Vector3.Slerp(transform.position, target.position, smooth * Time.deltaTime);
offset = player.transform.position - transform.position;
Quaternion rotation = Quaternion.LookRotation(player.transform.forward);
transform.rotation = rotation;
transform.eulerAngles = new Vector3(20f, transform.eulerAngles.y, transform.eulerAngles.z);
}
}
}
Answer by KGC · Jan 05, 2017 at 03:09 PM
The solution is to convert your movement vectors from global to local (relative to the camera). Found another question for this with a solution. Link: http://answers.unity3d.com/questions/8444/moving-player-relative-to-camera.html
Commented version of the code, and some examples of how to integrate with your code (not tested):
// Get local camera forward axis aligned with floor plane
// Convert global forward to localspace forward for camera's transform
Vector3 forward = Camera.transform.TransformDirection(Vector3.forward);
// Get rid of the Y value to align it with floor plane (could also project the vector, but this is easier to understand)
forward.y = 0f;
// Ensure it is a direction (normalized) and not a position
forward = forward.normalized;
// Calculate relative right vector for localspace forward vector from camera
Vector3 right = new Vector3(forward.z, 0.0f, -forward.x);
// Update velocity
// Add forward and turn vectors together (which are both scaled to speed and input)
rg.velocity = (forward * PlayerSpeed * turnInput) + (right * PlayerSpeed * forwardInput);
//Set Directions
// Why not just sample from the rigidbody's velocity?
moveDirection = rg.velocity.normalized;
$$anonymous$$mmm, Okey i see what u'r talking about, i'll try to follow this logic. thx :D
Alternatively, you could use rg.transform.forward ins$$anonymous$$d of trying to calculate forward using the camera. It gives a different feel to the controls - for it to feel like it based on the camera, you'd need to move the camera near-instantaneously to achieve the same effect (around the Y axis).