当前位置 主页 > 网站技术 > 代码类 >

    Unity UI拖拽模型选择功能

    栏目:代码类 时间:2020-01-07 15:05

    指定一块区域,玩家鼠标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();
      }
    
    
    }