Unity中制作角色血条

一、制作原理 

我们希望在一个模型的头顶放置一个UI,但是我们不可能直接挂一个UI在上面;因为我们的UI需要用一个单独的相机而非模型的相机来渲染,所以如果直接在模型的GameObject下直接挂一个子物体,渲染出来的结果肯定不对;

明白这一点后,我们就需要找到如果想要渲染到模型的顶部,我们得到一个UI的世界坐标使其在渲染到屏幕空间后,正好位于模型顶部;设UI的世界坐标Pos1,其计算方式为,首先得到模型顶部的世界坐标pos2,然后使用其场景相机将其转换到屏幕空间,这个点也正好是我们希望Pos1通过UI相机转换到屏幕空间的位置,所以直接反向求解即可;

以下是使用NGUI代码给出的简单算法实现:

    void Update()
    {
        Vector3 pt = Camera.main.WorldToScreenPoint(followTf.position + newOffsetPos);
        tf.position = UICamera.FindCameraForLayer(this.gameObject.layer).cachedCamera.ScreenToWorldPoint(new Vector3(pt.x, pt.y, pt.z));
    }

二、需求扩展

当相机靠近模型远离模型时,UI都是不会变化的,如果我们希望当模型远离相机时,或者相机的FOV改变的时候,UI也要随着改变,那如何处理,下面给出了一个方案,提供了一个CalibrateUITf()校验函数 ,它会根据相机距离的远近,FOV的大小来调整UI的scale以及UI到模型的距离;

    public Vector3 offsetPos;
    public Transform followTf;
    private Transform tf;
    // 默认相机的一系列参数
    private float originFOV;
    private float originDist2Camera;
    // UI的原始大小
    private Vector3 originScale;
    // Start is called before the first frame update
    void Start()
    {
        tf = this.transform;
        originFOV = Camera.main.fieldOfView;
        originDist2Camera = followTf.position.z - Camera.main.gameObject.transform.position.z;
        originScale = tf.localScale;
    }

    // Update is called once per frame
    void Update()
    {
        Vector3 newOffsetPos = CalibrateUITf();
        Vector3 pt = Camera.main.WorldToScreenPoint(followTf.position + newOffsetPos);
        tf.position = UICamera.FindCameraForLayer(this.gameObject.layer).cachedCamera.ScreenToWorldPoint(new Vector3(pt.x, pt.y, pt.z));
    }

    Vector3 CalibrateUITf(){
        float calibrationArg = 1; // 计算校正参数
        float currentFOV = Camera.main.fieldOfView;
        calibrationArg = currentFOV / originFOV;
        
        float d = followTf.position.z - Camera.main.gameObject.transform.position.z;
        calibrationArg *= d / originDist2Camera;
        
        tf.localScale = originScale / calibrationArg;
        Vector3 newOffsetPos = offsetPos * calibrationArg;
        return newOffsetPos;
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值