NGUI源码分析(六) UIProgressBar和UISlider

UISlider继承于UIProgressBar 它们是非常重要和实用的类,UIProgressBar它实现了进度条的功能,UISlider在UIProgressBar的基础上实现了拖拽

 UIProgressBar 介绍:

一.重要属性:

//方向:左到右,右到左,下到上,上到下
public enum FillDirection
{
    LeftToRight,
    RightToLeft,
    BottomToTop,
    TopToBottom,
}

protected UIWidget mBG; //背景
protected UIWidget mFG;//前景
protected float mValue = 1f;//进度百分比值
protected FillDirection mFill = FillDirection.LeftToRight;//默认左到右

public int numberOfSteps = 0;//步长 如果为5 意思是滑动条分为5步,每一步的百分比分别为0, 0.25, 0.5, 0.75, 1.0.

二.主要方法 

ForceUpdate() 核心方法 根据Value更新滑条

//获得前景Sprite
UIBasicSprite sprite = mFG as UIBasicSprite;
if (isHorizontal)
{
    //如果类型是填充类型
    if (sprite != null && sprite.type == UIBasicSprite.Type.Filled)
    {
        if (sprite.fillDirection == UIBasicSprite.FillDirection.Horizontal ||
        sprite.fillDirection == UIBasicSprite.FillDirection.Vertical)
        {
            sprite.fillDirection = UIBasicSprite.FillDirection.Horizontal;
            sprite.invert = isInverted;
        }
        //设置前景Sprite填充百分比
        sprite.fillAmount = value;
    }
    else
    {
        //设置前景Sprite 显示区域
        mFG.drawRegion = isInverted ?
        new Vector4(1f - value, 0f, 1f, 1f) :
        new Vector4(0f, 0f, value, 1f);
        mFG.enabled = value > 0.001f;
    }
}

UISlider介绍:
一.重要方法: 

//在OnStart中检测背景是否有碰撞组件 然后监听背景的拖拽
protected override void OnStart ()
{
    GameObject bg = (mBG != null && (mBG.collider != null || mBG.GetComponent<Collider2D>() != null)) ? mBG.gameObject : gameObject;
    UIEventListener bgl = UIEventListener.Get(bg);
    //监听按下
    bgl.onPress += OnPressBackground;
    //监听拖拽
    bgl.onDrag += OnDragBackground;
    
    .....
}

//按下事件处理
protected void OnPressBackground (GameObject go, bool isPressed)
{
    if (UICamera.currentScheme == UICamera.ControlScheme.Controller) return;
    //获得当前相机
    mCam = UICamera.currentCamera;
    //通过屏幕点击位置获得进度百分比
    value = ScreenToValue(UICamera.lastTouchPosition);
    //拖拽结束回调
    if (!isPressed && onDragFinished != null) onDragFinished();
}

//通过屏幕点击位置获得进度百分比
protected float ScreenToValue (Vector2 screenPos)
{
    Transform trans = cachedTransform;
    //以当前Slider对象为基点 以屏幕向外为法线 创建一个平面
    Plane plane = new Plane(trans.rotation * Vector3.back, trans.position);

    float dist;
    //从屏幕点击的位置为起始 生成一条射线 
    Ray ray = cachedCamera.ScreenPointToRay(screenPos);


    //检测射线是否穿啊过平面
    if (!plane.Raycast(ray, out dist)) return value;

    //如果穿过平面,先用ray.GetPoint(dist)获得射线与平面的相交点 再通过InverseTransformPoint方法把相交点从世界坐标系转换为局部坐标
    //最后通过这个局部坐标获得进度百分比值
    return LocalToValue(trans.InverseTransformPoint(ray.GetPoint(dist)));
}


//通过局部坐标计算出进度百分比值
protected virtual float LocalToValue (Vector2 localPos)
{
    if (mFG != null)
    {
        //获得局部矩形顶点
        Vector3[] corners = mFG.localCorners;
        //用右上点-左上点计算出尺寸
        Vector3 size = (corners[2] - corners[0]);

        if (isHorizontal)
        {
            //(点击位置 -  左边x坐标) / 宽度
            float diff = (localPos.x - corners[0].x) / size.x;
            return isInverted ? 1f - diff : diff;
        }
        else
        {
            //(点击位置 -  左下Y坐标) / 高度
            float diff = (localPos.y - corners[0].y) / size.y;
            return isInverted ? 1f - diff : diff;
        }
    }
    return value;
}


原文地址:http://www.cnblogs.com/rocky300/articles/4682648.html

猜你喜欢

转载自blog.csdn.net/Marccco/article/details/84637306