Character faces the direction it moves.

I’m trying to get a character to move in 8 directions. And for the rotation to blend from one to the other. I’ve tried a bunch of different things. But I can’t figure out a way to blend the direction and get the character to face the correct direction when two keys are pressed at a time.

The picture shows what I am trying to do.

Note: the camera is locked…

What you may do , is simply get a normalized vector from your input, i suppose you are using getaxis function, so you will get from there a normalized vector that will represent your dir vector, then you need to align you forward character vector to that direction, usually you can use fct like

transform.TransformDirection(yourDirection) for that purpose

After that depends on how you want vizualize the charcter, you couls also have A and D, handling your character rotation, and then A to move forward, in that case you will use the same fct , but use the forward vector of your character.

You may want look at tutorial like penelope or latest angry bot, to give you some idee on the subject, you may able to pick some code from there to help you in understanding how to deal with this

I tried doing that. changing the forward direction. But it just cause the character to spin around when I push a button

bump

You can do something like this. I use some similar code in my game.

var rotSpeed : float;
var ForwardLook : Vector3;
var newForward : Vector3;
var direction : Vector3;

function Update(){
if(Input.GetKey("w")){
direction.z = 1;
}
else if(Input.GetKey("s")){
direction.z = -1;
}
if(Input.GetKey("a")){
direction.x = 1;
}
else if(Input.GetKey("d")){
direction.x = -1;
}
ForwardLook = Vector3(direction.x, 0, direction.z);
newForward = Vector3.Slerp(transform.forward, ForwardLook.normalized, rotSpeed * Time.deltaTime);
transform.forward = newForward;
}

I believe the character controller script that comes with Unity achieves this.

Look at the penelope example. Check the camera relative setup.

Well none of that stuff seemed work. Character controller scripts that come with unity are for some kind of 3rd person view where the camera can rotate around. Not what I’m seeking. My camera is locked.

The penelope stuff is sadly, just a bunch of garbage files on the asset store. I don’t even know why it is there.

Edit: Nevermind… got it with some modification to Astrauk’s code.

ForwardLook = Vector3(Input.GetAxis(“Horizontal”), 0,Input.GetAxis(“Vertical”));

i achieved this with 3 scripts:

  1. Movement
  2. CamY
  3. CamScript

Movement.cs:

using UnityEngine;
using System.Collections;

public class Movement : MonoBehaviour
{
    public float speed = 10;
    public float jumpHeight = 5;
    public float gravity = 9;
    public Transform cam;
    public CamScript camScript;
    public CamY camY;

    private Vector3 moveDir = Vector3.zero;
    public float y = 0;
    private CharacterController controller;
    private Vector3 forward;
    private float lastRot = 0;
    private float camLastDist;
    private bool wasInAir = false;

    void Awake()
    {
        controller = GetComponent<CharacterController>();
    }

    void Update()
    {
        moveDir.x = Input.GetAxis("Horizontal");
        moveDir.z = Input.GetAxis("Vertical");

        if (moveDir.magnitude > 1)
        {
            moveDir.Normalize();
        }

        if (Input.GetAxis("Horizontal") != 0 || Input.GetAxis("Vertical") != 0)
        {
            forward = camY.SendTransformPosition(moveDir);
            transform.eulerAngles = new Vector3(0, Mathf.MoveTowardsAngle(transform.eulerAngles.y, (Mathf.Atan2(forward.x, forward.z) * Mathf.Rad2Deg), Time.deltaTime * 500), 0);
        }
        else
        {
            forward = Vector3.zero;
        }


        if (controller.isGrounded)
        {
            if (wasInAir)
            {
                y = -gravity / 2;
                wasInAir = false;
            }

            if (Input.GetKeyDown("space"))
            {
                y = jumpHeight;
            }
        }
        else
        {
            wasInAir = true;
            y -= gravity * Time.deltaTime;
        }
        controller.Move(new Vector3(forward.x * speed, y, forward.z * speed) * Time.deltaTime);

        RaycastHit hitInfo;
        //Debug.DrawLine(transform.position, cam.position + Vector3.down * 0.4f, Color.blue);
        if (Physics.Linecast(transform.position, cam.position + Vector3.down * 0.4f, out hitInfo))
        {
            camScript.isColliding = true;
            camScript.distance = Vector3.Distance(hitInfo.point, transform.position) + 0.4f;
            camLastDist = camScript.distance;
        }
        else
        {
            camScript.isColliding = false;
            //Debug.DrawLine(transform.position, camScript.GetCamsLastPos(camLastDist), Color.red);

            if (!Physics.Linecast(transform.position, camScript.GetCamsLastPos(camLastDist))  !camScript.isChanging)
            {
                camScript.StartCoroutine(camScript.ReturnToNormalDistance());
            }
        }
    }
}

CamScript.cs:

using UnityEngine;
using System.Collections;

public class CamScript : MonoBehaviour
{
    public Transform target;

    public float distance = 10.0f;
    public float staticDist = 10.0f;
    public bool isColliding = false;
    public bool isChanging = false;

    public float xSpeed = 250.0f;
    public float ySpeed = 120.0f;
    public float yMinLimit = -20f;
    public float yMaxLimit = 80f;

    public float plusY = 0;
    public Transform camY;

    public float x = 0.0f;
    public float y = 0.0f;

    float xVelocity = 0;
    float yVelocity = 0;
    float distVelocity = 0;

    Quaternion rotation;
    Vector3 position;

    void Awake()
    {
        Transform camYInstance = Instantiate(camY) as Transform;
        camYInstance.GetComponent<CamY>().cam = transform;
        target.GetComponent<Movement>().camY = camYInstance.GetComponent<CamY>();
    }

    void Start()
    {
        Vector3 angles = transform.eulerAngles;
        x = angles.y;
        y = angles.x;
    }

    void LateUpdate()
    {
        if (Input.GetMouseButton(0))
        {
            x += Input.GetAxis("Mouse X") * xSpeed;
            y -= Input.GetAxis("Mouse Y") * ySpeed;
        }
        staticDist = Mathf.SmoothStep(staticDist, staticDist - Input.GetAxis("Mouse ScrollWheel") * 60, 25 * Time.deltaTime);

        staticDist = Mathf.Clamp(staticDist, 5, 30);

        y = ClampAngle(y, yMinLimit, yMaxLimit);

        rotation = Quaternion.Euler(y, x, 0);
        position = rotation * new Vector3(0.0f, 0.0f, -distance) + (target.position + Vector3.up * plusY);

        transform.rotation = rotation;
        transform.position = position;
    }

    static float ClampAngle(float angle, float min, float max)
    {
        if (angle < -360)
            angle += 360;
        if (angle > 360)
            angle -= 360;
        return Mathf.Clamp(angle, min, max);
    }

    public IEnumerator ReturnToNormalDistance()
    {
        isChanging = true;

        while (distance != staticDist  isColliding == false)
        {
            distance = Mathf.MoveTowards(distance, staticDist, Time.deltaTime * 10);
            yield return 0;
        }

        isChanging = false;
    }

    public Vector3 GetCamsLastPos(float lastDist)
    {
        return rotation * new Vector3(0.0f, 0.0f, -lastDist) + target.position;
    }
}

CamY.cs:

using UnityEngine;
using System.Collections;

public class CamY : MonoBehaviour
{
    public Transform cam;

    void Update()
    {
        transform.eulerAngles = new Vector3(0, cam.eulerAngles.y, 0);
    }

    public Vector3 SendTransformPosition(Vector3 dir)
    {
        return transform.TransformDirection(dir);
    }
}

you put the movement.cs in the character, make sure it has CharacterController attached to it, also set his layer to Ignore Raycast.
make a prefab of empty gameobject and put the CamY script in it.
attached CamScript.cs into your main camera, attach CamY prefab into your CamY variable in the CamScript inspector.
attach the player’s object into the variable “target” in the CamScript inspector.
set all the rest of the values… if you have problems with your camera’s collision detection, you will need to rewrite it, because i used it for my game’s needs. good luck.