c# - Doom-like angle based sprite changing -
so, i'm trying make first person game used same sprite mechanics games doom, duke nukem , etc.
so far, can identify angle i'm @ in relation static objects, not rotating ones. have "enemies" change rotation , start following me, calculating tangent angle (mathf.atan2) doesn't take enemy's rotation in consideration.
here's code i'm using far, works objects dont rotate:
int getangleindex() { var dir = cam.transform.position - transform.parent.forward; var enemyangle = mathf.atan2(dir.z, dir.x) * mathf.rad2deg; if (enemyangle < 0.0f) enemyangle += 360; debug.log("angle player is: " + enemyangle); if (enemyangle >= 292.5f && enemyangle < 337.5f) return 8; else if (enemyangle >= 22.5f && enemyangle < 67.5f) return 2; else if (enemyangle >= 67.5f && enemyangle < 112.5f) return 3; else if (enemyangle >= 112.5f && enemyangle < 157.5f) return 4; else if (enemyangle >= 157.5f && enemyangle < 202.5f) return 5; else if (enemyangle >= 202.5f && enemyangle < 247.5f) return 6; else if (enemyangle >= 247.5f && enemyangle < 292.5f) return 7; else if (enemyangle >= 337.5f || enemyangle < 22.5f) return 1; else return 0; } i've searched hours , can't find solution :(
you [only] problem doesn't take rotation account - i'm guessing means you're not having trouble billboarding sprites, , rotation works when they're facing forward. end:
the dot product of vectors , b equal cos(theta)*magnitude(a)*magnitude(b). if vector camera object:
var = cam.transform.position - transform.parent.position and b object's forward:
var b = transform.parent.forward and know , b both have magnitude 1
a.normalize(); //b normalized then know equal cos(theta), theta angle between them.
var theta = mathf.acos(vector3.dot(a, b)) * mathf.rad2deg; however. theta shortest necessary angle - 0 180. given switch table there, know when we're hoping go around wrong way, we'll in wrong position. fix that:
if (a.x * a.z < 0) theta = 360.0f - theta; then plug in , go. here's full file in project:
using unityengine; public class spriteangler : monobehaviour { public transform toface; public spriterenderer tomanipulate; public sprite[] mysprites; private float theta; private vector3 a; void update() { tomanipulate.sprite = mysprites[getangleindex()]; } int getangleindex() { = toface.position - transform.position; a.normalize(); var b = transform.forward; theta = mathf.acos(vector3.dot(a, b)) * mathf.rad2deg; if (a.x * a.z < 0) theta = 360.0f - theta; if (theta >= 292.5f && theta < 337.5f) return 7; else if (theta >= 22.5f && theta < 67.5f) return 1; else if (theta >= 67.5f && theta < 112.5f) return 2; else if (theta >= 112.5f && theta < 157.5f) return 3; else if (theta >= 157.5f && theta < 202.5f) return 4; else if (theta >= 202.5f && theta < 247.5f) return 5; else if (theta >= 247.5f && theta < 292.5f) return 6; else if (theta >= 337.5f || theta < 22.5f) return 0; else return 0; } private rect guipos = new rect(0, 0, 720, 30); void ongui() { gui.label(guipos, "angle player is: " + theta + " , forward=" + transform.forward + " , vectortotarget=" + a); } } and if needs little more context, here's project: https://github.com/adamrgrey/22623013
i'd recommend hitting play watching scene window instead of game window.
Comments
Post a Comment