8 Directional sprite in 3d world, how to retrieve angle?

I’m trying to do an 8 directional sprite in a 3d world like Doom. I managed to get it almost wworking, but my script is not very precise as ti try to retrieve absolute angles, and if the player move too fast sometime it skips part of the code, this is my actual script:

UPDATED With Professor Snake solution and Zeh suggestions:

using UnityEngine;
using System.Collections;

public class LookDirection : MonoBehaviour {

	Transform player;
	public float angle;
	Vector3 direction;
	public Renderer spriteObj;
	public Material[] mat;
	void Awake () {player = GameObject.FindWithTag("Player").transform;}
	void Update () {

		direction = player.transform.position - transform.position;
		angle = Mathf.Atan2(direction.x,direction.z) * Mathf.Rad2Deg;
		ChangeDirection ();

	void ChangeDirection () {
	    if (angle < 0) angle += 360; // Just in case
		spriteObj.renderer.sharedMaterial = mat[(int)Mathf.Round(angle / 360f * mat.Length) % mat.Length];

Consider that the public Material variables are just for testing now to see if it changes properly.

So as you see in the coroutine I just send the angle as string with the first 2 digits only on the overload method of the function ChangeDirection. And the switch check when the angle reach a certain angle, but is not that precise and sometime as I saied before it skips the angle strings.

Any suggestion on a better approach to get a precise angle reference?

Screenshot of what I’m doing:

Then what about a short yet clever algorithm? You could store the the different textures for the objects in an array, and then in every frame, you could use:


Untested, but it should work, assuming the angles go from 0 to 360.

(if angle<45, int.Parse(((int)angle+180)/45) should equal 0, if it’s between 45 and 90, int.Parse(angle/45) will equal 1 etc etc)

You’re testing for the right angles but not for the ranges the player can be in. At the very least, you’d need a numerical comparison of ranges. So you should never try that kind of comparison as strings.

But similarly to what ProfessorSnake said, because this is a sequence (of angle ranges) that maps to another sequence (of materials), you should just need an array of your angles and then calculate accordingly.

// Initialize the list of materials somewhere else
Material[] materials = new Material[8] {F, FR, R, BR, B, BL, L, FL};

// When you need to set the material depending on the angle
if (angle < 0) angle += 360; // Just in case
spriteObj.renderer.sharedMaterial = materials[Math.round(angle / 360f * array.Length) % array.Length];

The above code assumes 0" is front, and that rotation goes clockwise. If not, you’ll have to adjust the order of the array accordingly.

Also, are you sure you need StartCoroutine and yield? Your code can be vastly simplified by removing that.