Unity 仪表盘制作 自定义表盘的开始结束点 自动匹配指针位置

制作一个仪表

效果:

请添加图片描述

需求:

有几个不同的仪表盘(温湿度计,油温),区间范围不同,需要输入值显示在正确的位置上

思路:
  • 需要定义开始位置与结束位置的值,输入区间值,得到输入值在区间的百分比
  • 做三个指针,分别代表开始位置,结束位置,输入位置
  • 把得到的百分比值映射到指针上
  • 由于有时表盘上表示的密度不同(可能会越来越密集)需要添加一个额外的参数调节
  • 做好行为约束,指针位置(包括开始结束位置)不能超越范围

开始动手:

一个简单的公式就可以得到百分比:

在这里插入图片描述

 float percentage = 
 (pointerValue - startValue) / (endValue - startValue);
 //得到百分比
映射到角度上:

在这里插入图片描述

/2是算的中间位置,映射百分比应该是*百分比

百分比是0到1之前的浮点数,想要控制密度,我想到的只有是百分比相乘
至于相乘多少次,我们在外部调节
请添加图片描述

 pointerAngle.z = 
 EndAngle.z + (Mathf.Abs(EndAngle.z) + StartAngle.z) * Mathf.Pow(percentage, power);
 //转换为角度
约束:
  • 开始角度值不能一直增加,过了360或者-360就得清零,保证是正常角度,也好计算
  • 结束角度不会超过开始角度的范围
  • 指针角度在开始角度与结束角度之间
LimitAngle(ref startAngle);
if (endAngle > startAngle)
    endAngle = startAngle;
if (endAngle < startAngle - 360)
    endAngle = startAngle - 360;
if (pointerValue > endValue)
    pointerValue = endValue;
if (pointerValue < startValue)
    pointerValue = startValue;
void LimitAngle(ref float angle)
    {
    
    
        if (angle > 360)
        {
    
    
            angle -= 360;
        }
        if (angle < -360)
        {
    
    
            angle += 360;
        }
    }

其他:

其实这样就已经足够了,可以应对大部分的表盘,不过表盘有可能是右到左的样式
最后我又增加一个参数来调整是否反向
一开始我在想调整公式的计算,后来灵光一闪,直接调整百分比就行了,原理就是:1-百分比

完整代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Meter : MonoBehaviour
{
    
    
    public Transform pointer;
    public Transform startPoint;
    public Transform endPoint;
    public float startAngle = 0, endAngle = 0;
    public float pointerValue = 0;
    public float startValue = 0, endValue = 1;
    [Range(0, 10)]
    public float power = 1;
    public bool reverse = false;
    Vector3 pointerAngle;
    Vector3 StartAngle, EndAngle;
    public void UpdateMeter()
    {
    
    
        LimitAngle(ref startAngle);
        if (endAngle > startAngle)
            endAngle = startAngle;
        if (endAngle < startAngle - 360)
            endAngle = startAngle - 360;
        if (pointerValue > endValue)
            pointerValue = endValue;
        if (pointerValue < startValue)
            pointerValue = startValue;

        StartAngle = Vector3.zero;
        EndAngle = Vector3.zero;
        StartAngle.z = startAngle;
        EndAngle.z = endAngle;

        float percentage = (pointerValue - startValue) / (endValue - startValue);//得到百分比
        if (!reverse)
            percentage = 1- percentage;
        pointerAngle.z = EndAngle.z + (Mathf.Abs(EndAngle.z) + StartAngle.z) * Mathf.Pow(percentage, power);//转换为角度

        LimitAngle(pointer, ref pointerAngle);
        LimitAngle(startPoint, ref StartAngle);
        LimitAngle(endPoint, ref EndAngle);
    }
    void LimitAngle(ref float angle)
    {
    
    
        if (angle > 360)
        {
    
    
            angle -= 360;
        }
        if (angle < -360)
        {
    
    
            angle += 360;
        }
    }
    void LimitAngle(Transform target, ref Vector3 angle)
    {
    
    
        if (angle.z > 360)
        {
    
    
            angle.z -= 360;
        }
        if (angle.z < -360)
        {
    
    
            angle.z += 360;
        }
        target.localEulerAngles = angle;
    }
    private void OnValidate()
    {
    
    
        UpdateMeter();
    }
}

Demo下载连接: 点击下载

猜你喜欢

转载自blog.csdn.net/CTangZe/article/details/126489675