获取敌人在屏幕的方向并显示箭头

思路:只考虑xz平面,摄像机前向与敌人的方向夹角即目标为屏幕y轴夹角α,然后通过屏幕宽高计算边缘坐标。

代码如下:

public class Arrow : MonoBehaviour
{
    public Transform target;
    public Image ui;
    public Transform player;

    void Start()
    {
        player = transform;
    }

    void Update()
    {
        //获取目标的向量
        var tForward = target.position - player.position;
        tForward.y = 0;

        //获取玩家前向向量 即为屏幕的y轴
        var pForward = Quaternion.AngleAxis(player.eulerAngles.y, Vector3.up) * Vector3.forward;

        //获取玩家前向向量到目标向量夹角
       var rotAngle = Vector3.SignedAngle(pForward, tForward, Vector3.up);

        var tRot = Quaternion.AngleAxis(rotAngle, Vector3.up) * Vector3.forward;
        tRot.Set(tRot.x, tRot.z, 0);


        //ugui是在uicamera前面 图片的旋转 
        ui.transform.localEulerAngles = new Vector3(0, 0, -rotAngle);


        //位置方案1 绕着屏幕中点转圈
        //ui.transform.localPosition = tRot.normalized * 50;


        //位置方案2 在屏幕边缘显示
        float halfWidth = Screen.width / 2 - (ui.transform as RectTransform).rect.width / 2;
        float halfHeight = Screen.height / 2 - (ui.transform as RectTransform).rect.width / 2;
        //屏幕中点到中上和右上的夹角
        var screenRightTopRad = Mathf.Atan(halfWidth / halfHeight);

        //转成0-PI的弧度
        var rotRad = Mathf.Deg2Rad * Mathf.Abs(rotAngle);
        //区分屏幕上面和下面
        bool isTop = rotRad < Mathf.PI / 2;
        //下半使用-y轴计算
        rotRad = isTop ? rotRad : Mathf.PI - rotRad;

        float x = 0, y = 0;
        //弧度比屏幕右上的夹角小,需要计算x坐标  否则计算y坐标
        if (rotRad < screenRightTopRad)
        {
            x = halfHeight * Mathf.Tan(rotRad) * Math.Sign(rotAngle);
            y = halfHeight;
        }
        else
        {
            x = halfWidth * Math.Sign(rotAngle);
            y = halfWidth * Mathf.Tan(Mathf.PI / 2 - rotRad);
        }

        y = isTop ? y : -y;
        ui.transform.localPosition = new Vector2(x, y);
    }
}

效果图如下,圆球为角色,方块为敌人,摄像机跟随在角色身后

摄像机没有旋转:

摄像机旋转: 

 

 

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值