基于厄运的角度精灵变化

时间:2014-03-25 00:02:38

标签: c# rotation unity3d

所以,我正在尝试制作第一人称游戏,使用与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;
}

我搜索了几个小时,但我找不到解决方案:(

3 个答案:

答案 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