所以,我正在尝试制作第一人称游戏,使用与Doom,Duke Nukem等游戏相同的精灵机制。
到目前为止,我可以识别出与静态物体相关的角度,而不是旋转物体的角度。我有一些“敌人”可以改变旋转并开始跟随我,但计算切线角度(Mathf.Atan2)并不考虑敌人的旋转。
这是我到目前为止使用的代码,它适用于不旋转的对象:
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 from the 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;
}
我搜索了几个小时,但我找不到解决方案:(
答案 0 :(得分:4)
你说你的[唯一]问题是它没有考虑他们的轮换 - 我猜这意味着你没有麻烦你的精灵广告,你的轮换工作时他们面向前方。为此:
矢量a和b的点积等于cos(θ)*幅度(a)*幅度(b)。因此,如果a是从相机到对象的向量:
var a = cam.transform.position - transform.parent.position
和b是对象的前锋:
var b = transform.parent.forward
我们知道a和b都有1级
a.Normalize();
//b is already normalized
然后我们知道这等于cos(theta),其中theta是它们之间的角度。
var theta = Mathf.Acos(Vector3.Dot(a, b)) * Mathf.Rad2Deg;
然而。 Theta是最短的必要角度 - 因此它将从0到180.鉴于你的切换表,我们知道当我们希望绕错路时,我们会在错误的立场。所以解决这个问题:
if (a.x * a.z < 0)
theta = 360.0f - theta;
然后我们只需将其插入即可。这是我项目中的完整文件:
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()
{
a = 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 from the Player is: " + theta + " and forward=" + transform.forward + " and vectorToTarget=" + a);
}
}
如果需要更多上下文,这是我的项目:https://github.com/AdamRGrey/22623013
我建议按下游戏但是观看场景窗口而不是游戏窗口。
答案 1 :(得分:-2)
也许我不理解您在此处尝试创建的确切效果(如果是这样,请提供更多信息,例如帖子中的屏幕截图),但您应该能够简单地使用Transform.LookAt()。这些通常称为 Billboard Sprites 。
示例:
Transform.LookAt(Camera.main.transform.position, Vector3.up)
答案 2 :(得分:-2)
我想你提到的是Billboards的概念。
以下是统一维基中的示例,用于创建始终面向相机的广告牌,继续尝试。
http://wiki.unity3d.com/index.php?title=CameraFacingBillboard