Unity UI拖拽模型選擇

指定一塊區域,玩家鼠標or手指拖拽這個區域,模型會進行偏移,並用於進行人物、道具的選擇

給模型定義一些屬性


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

public class UIModelUtil : MonoBehaviour
{
    public Animator animator;
    public int id;
    public int index;

}

模型控制

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

public class UIModelControl : MonoBehaviour
{
    public Transform modelsParent;
    public Transform centerPos;
    public float interval;
    public  bool loop;

    List<UIModelUtil> models;
    bool isPressing;
    public UIDrag dragComp;


    Vector3 mousePos;

    private void Awake()
    {
        if(models == null)
        {
            int i = 0;
            models = new List<UIModelUtil>();
            foreach(UIModelUtil util in modelsParent.GetComponentsInChildren<UIModelUtil>())
            {
                models.Add(util);
                //util.index = i;
                Vector3 pos = Vector3.zero;
                pos.x = i * interval;
                util.transform.localPosition = pos;
                i++;
            }
        }
    }

    private void Start()
    {
        JumpToSelect();
    }

    
    private void Update()
    {
        //接受拖拽事件
        if (isPressing)
        {
            float x = GetInputDeltaX();
            int dir = 0;
            if (x > 0) dir = 1;
            else if (x < 0) dir = -1;

            //分辨率修正
            if (dir == 0) return;
            x = Mathf.Abs(x) / (Screen.width) * 800f;
            if (x > 800f) x = 800f;

            //偏移
            float currectX = Mathf.Lerp(0, interval, x / 800f) * dir;
            Vector3 pos = modelsParent.position;
            pos.x += currectX;



                Transform right = GetRight().transform;
                Transform left = GetLeft().transform;
            //不循環時候設置邊框
            if (models.Count > 2 || !loop || models.Count == 1)
            {
        

                if (right.localPosition.x + interval / 10 < -pos.x) pos.x = -(right.localPosition.x + interval / 10);
                else if (left.localPosition.x - interval / 10 > -pos.x) pos.x = -(left.localPosition.x - interval / 10);

                //modelsParent.position = pos;
            }
            //只有兩個循環的時候
            else if (models.Count == 2 && loop)
            {

                Transform selected = GetSelect().transform;
                //當前是右邊那個且向右拖拽
                if (selected == right && dir < 0)
                {
                    
                    Vector3 leftPos = left.localPosition;
                    leftPos.x = right.localPosition.x + interval;
                    left.localPosition = leftPos;
                }
                //當前是左邊那個且向左拖拽
                else if (selected == left && dir > 0)
                {
                    Vector3 rightPos = right.localPosition;
                    rightPos.x = left.localPosition.x - interval;
                    right.localPosition = rightPos;
                }
            }
            modelsParent.position = pos;
            
            AfterSelect();
        }
    }


    void AfterSelect()
    {
        foreach(UIModelUtil util in models)
        {
            float dis = GetXDis(util);
            //設置顯示
            if (dis > interval)
                util.gameObject.SetActive(false);
            else
            { 
                //越靠近中間越前
                util.gameObject.SetActive(true);
                float t = Mathf.Abs(dis) / interval;
                float y = Mathf.Lerp(centerPos.position.z, modelsParent.position.z, t);
                Vector3 pos = util.transform.position;
                pos.z = y;
                util.transform.position = pos;
            }

        }
        //循環時候位置修正
        if (loop && models.Count > 2)
        {
            Transform right = GetRight().transform;
            Transform left = GetLeft().transform;
            Transform selected = GetSelect().transform;
            if (selected == right)
            {
                Vector3 pos = right.position;
                pos.x += interval;
                left.position = pos;
            }
            else if (selected == left)
            {
                Vector3 pos = left.position;
                pos.x -= interval;
                right.position = pos;
            }
        }
        //設置UI選中狀況
        dragComp.OnSelected(GetSelect().id, GetSelect().index);
    }

    //通過id選中
     UIModelUtil GetById(int id)
    {
        if (models == null) return null;
        UIModelUtil target = null;

        foreach (UIModelUtil util in models)
        {
            if (util.id == id) return util;
        }
        return target;
    }

    //獲取當前選中
     UIModelUtil GetSelect()
    {
        if (models == null) return null;
        float min = 9999;

        UIModelUtil target = null;

        foreach(UIModelUtil util in models)
        {
            float dis = Mathf.Abs( GetXDis(util));
            if(dis < min)
            {
                target = util;
                min = dis;
            }
        }
        return target;
    }

    //所有模型最右邊的那個
     UIModelUtil GetRight()
    {
        if (models == null) return null;
        float max = -9999;

        UIModelUtil target = null;

        foreach(UIModelUtil util in models)
        {
            float dis = util.transform.localPosition.x;
            if(dis > max)
            {
                target = util;
                max = dis;
            }
        }

        return target;
    }

    //所有模型最左邊的那個
     UIModelUtil GetLeft()
    {
        if (models == null) return null;
        float min = 9999;

        UIModelUtil target = null;

        foreach(UIModelUtil util in models)
        {
            float dis = util.transform.localPosition.x;
            if(dis < min)
            {
                target = util;
                min = dis;
            }
        }


        return target;
    }

    //UI控件按下觸發
    public void OnPress()
    {
        if (isPressing) return;
        isPressing = true;

        if (Application.isEditor)
            mousePos = Input.mousePosition;
        else
            mousePos = Input.GetTouch(0).position;
        if (backing != null) StopCoroutine(backing);
    }

    //UI控件釋放觸發
    public void OnRelease()
    {
        backing = StartCoroutine(ToSelect());
        isPressing = false;
    }


    Coroutine backing;
    //釋放後偏移
    IEnumerator ToSelect()
    {


        UIModelUtil selected = GetSelect();
        float dis = GetXDis(selected);
        float time = Mathf.Lerp (0, 1f, Mathf.Abs(dis) / interval);
        float timer = 0;
        Vector3 from = modelsParent.localPosition;
        Vector3 to = from;
        to.x = -selected.transform.localPosition.x;

        while(timer < time)
        {
            timer += Time.deltaTime;
            float t = timer / time;
            Vector3 pos = Vector3.Lerp(from, to, t);
            modelsParent.localPosition = pos;
            AfterSelect();
            yield return null;
        }
        backing = null;

    }

    //獲取手指偏移量
    float GetInputDeltaX()
    {
        Vector3 pos;
        if (Application.isEditor)
            pos = Input.mousePosition;
        else
            pos = Input.GetTouch(0).position;
        Vector3 delta = pos - mousePos;
        //Debug.Log(pos +"/"+mousePos +"/"+ delta.x);
        mousePos = pos;
        return delta.x;
            
    }

    //計算偏移中心位置的X軸距離
    float GetXDis(UIModelUtil util)
    {
        return util.transform.position.x - centerPos.position.x;
    }

    // 跳轉到選中的id
    public void JumpToSelect()
    {
        int id = CharacterManager.characterId;
        Vector3 pos = modelsParent.localPosition;
        UIModelUtil selected = GetById(id);
        pos.x = -selected.transform.localPosition.x;
        modelsParent.localPosition = pos;

        AfterSelect();
    }





}

UI接受點擊事件:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class UIDrag : MonoBehaviour,IPointerDownHandler, IPointerUpHandler
{
    public UIModelControl control;

    virtual public void OnPointerDown(PointerEventData data)
    {
        control.OnPress();
    }

    virtual public void OnPointerUp(PointerEventData data)
    {
        control.OnRelease();
    }

    virtual public void OnSelected(int id, int index)
    {

    }
}
發佈了47 篇原創文章 · 獲贊 8 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章