Unity 之 模拟滑动日历选择日期简例 (文末源码)

Unity 制作一个用于选择日期的小例子,,,
【经实践,此方式并不是很好,交互感很低(2019.02.23)推荐看下Demo2】
下面以选择月份为例:

搭建如下场景,,,对图中标记的地方的简要说明:SelectBg:模拟选中的当前日期,
month:做作为挂载脚本的物体,挂载Image组件将其透明度调为:0,,,然后创建其子物体,只挂载Text组件用于显示文字,并且为其命名1,2,3,4,5,,,以后获取的时候可以通过month.transform.getChild(2).GetComponent ().text --获取这个字符串的前两位
就是所选择的变量了,

111

完整代码如下:都需要挂载到month上,,,

【另:需把子物体的Text组件上的Raycast Target选项取消勾选,,,脚本不能挂载多个物体,使用多个是需代码移除和加载,】
如选择年月日不需分开,则可使用同一个物体下扩展,参考链接

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

/// <summary>
/// 日历
/// </summary>
public class Rili : MonoBehaviour, IPointerDownHandler
{
    public static Rili Singleton;

    public GameObject go;
    private List<GameObject> monthList = new List<GameObject>();
    public static int yearValue = 1;
    public static int monthValue = 1;
    public static int dayValue = 1;
    public static int hourValue = 1;
    public static int minValue = 1;

    private int curtime; //当前显示时间
    private int isClickDownNum;   //点击次数
    public bool isCanDrag = true; //是否可拖动(避免其他文字隐藏时可以拖动)

    void Awake()
    {
        Singleton = this;    
    }

    void Start()
    {
        go = this.gameObject;
        curtime = int.Parse(this.transform.GetChild(2).GetComponent<Text>().text.Substring(0, 2));
        //Debug.Log(go.name + "...日历选择的初始化操作............" + curtime);
    
        isClickDownNum = 1;
        for (int i = 0; i < this.transform.childCount; i++)
        {
            this.transform.GetChild(i).gameObject.SetActive(false);
        }
        this.transform.GetChild(2).gameObject.SetActive(true);      
      
        Init();
        UpdateTime();
     
        //Debug.Log(go.name + "...日历选择的初始化操作............" + this.transform.GetChild(2).GetComponent<Text>().text);
    }

    /// <summary>
    /// 初始化
    /// </summary>
    public void Init()
    {
   		//可以获取当前时间或者上传编辑时间
        yearValue = System.DateTime.Now.Year;
        monthValue = curtime;
        dayValue = curtime;
        hourValue = curtime;
        minValue = curtime;

        foreach (Transform item in go.transform)
        {
            monthList.Add(item.gameObject);
            item.gameObject.SetActive(true);
        }

        foreach (GameObject item in monthList)
        {
            string n = item.name;
            float alpha = 1 - ((Mathf.Abs(3.0f - float.Parse(n)))) / 3;
            item.gameObject.GetComponent<Text>().color = new Color(item.GetComponent<Text>().color.r, item.GetComponent<Text>().color.r, item.GetComponent<Text>().color.r, alpha);
            item.GetComponent<Text>().fontSize = 32 - Mathf.Abs(3 - int.Parse(n));
        }       
    }   
    
    /// <summary>
    /// 隐藏其他显示在外面的时间文字
    /// </summary>
    public void HideOther()
    {
        for (int i = 0; i < this.transform.childCount; i++)
        {
            this.transform.GetChild(i).gameObject.SetActive(false);
        }
        this.transform.GetChild(2).gameObject.SetActive(true);
    } 

    /// <summary>
    /// 更新显示时间
    /// </summary>
    public void UpdateTime()
    {
        if (go.name == "year")
        {
            foreach (GameObject go in monthList)
            {
                int nn = int.Parse(go.name);
                go.GetComponent<Text>().text = (nn - 3 + yearValue).ToString().Substring(2, 2) + "年";
            }
        }

        if (go.name == "month")
        {
            foreach (GameObject go in monthList)
            {
                int nn = int.Parse(go.name);
                int mm = Mathf.Abs(nn + monthValue - 3); 
                if (mm % 12 == 0)
                {
                    go.GetComponent<Text>().text = "12月";
                }
                else
                {
                    go.GetComponent<Text>().text = (Mathf.Abs(mm % 12) >= 10 ? Mathf.Abs(mm % 12).ToString() : "0" + Mathf.Abs(mm % 12)) + "月";
                }
            }
        }

        if (go.name == "day")
        {          
            foreach (GameObject go in monthList)
            {
                int nn = int.Parse(go.name);
                int mm = Mathf.Abs(nn + dayValue - 3);
                //编辑月份和年份时存储的当前月&年  使用PlayerPrefs.SetInt("PGMatchMonth",Value); 保存
                int dd = GetDayCount(PlayerPrefs.GetInt("PGMatchMonth"), PlayerPrefs.GetInt("PGMatchYear"));
                //Debug.Log(nn + "....mm.." + mm + "... dd.." + dd);
                if (mm % dd == 0)
                {
                    go.GetComponent<Text>().text = dd + "日";
                }
                else
                {
                    go.GetComponent<Text>().text = ((mm % dd >= 10) ? (mm % dd).ToString() : "0" + (mm % dd))+ "日";
                }
            }
        }

        if (go.name == "hour")
        {
            foreach (GameObject go in monthList)
            {
                int nn = int.Parse(go.name);
                int mm = nn + hourValue - 3;
                int hour = 24;
                //Debug.Log("nn"+ nn + "... mm" + mm+ "...minValue % hour"+ minValue % hour);
                if (mm % hour == 0)
                {
                    go.GetComponent<Text>().text = "00时";
                }
                else
                {
                    go.GetComponent<Text>().text = (Mathf.Abs(mm % hour) >= 10 ? (Mathf.Abs(mm % hour).ToString()) : "0" + Mathf.Abs(mm % hour)) + "时";
                }
            }
        }

        if (go.name == "min")
        {
            foreach (GameObject go in monthList)
            {
                int nn = int.Parse(go.name);
                int mm = nn + minValue - 3;
                if (mm % 60 == 0)
                {
                    go.GetComponent<Text>().text = "00分";
                }
                else
                {
                    go.GetComponent<Text>().text = (Mathf.Abs(mm % 60) >= 10 ? (Mathf.Abs(mm % 60).ToString()) : "0" + Mathf.Abs(mm % 60)) + "分";
                }
            }
        }
    }

    public void OnPointerDown(PointerEventData eventData)
    {
        Debug.Log("OnPointerDown...>>>>>>>>>>>>>>>>>> " + isClickDownNum);
        if (isClickDownNum == 1)
        {
            monthList.Clear();
            Init();
            isCanDrag = true;
        }
        else if (isClickDownNum == 2)
        {
            isCanDrag = true;
        }
        else if (isClickDownNum == 3)
        {            
            for (int i = 0; i < this.transform.childCount; i++)
            {
                this.transform.GetChild(i).gameObject.SetActive(false);
            }
            this.transform.GetChild(2).gameObject.SetActive(true);
            isClickDownNum = 0;
            isCanDrag = false;
        }
        isClickDownNum++;
    }      

    //返回有几天
    int GetDayCount(int month,int year)
    {
        //不符合条件的默认查的是1月
        if (month > 12 || month < 1) return 31;
        //是否是闰年,当前只用2019,  
        if (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0))
        {
            if (month == 2) return 29;
        }
        else
        {
            if (month == 2) return 28;
        }
        switch (month)
        {
            case 1:
            case 3:
            case 5:
            case 7:
            case 8:
            case 10:
            case 12:
                return 31;
            case 4:
            case 6:
            case 9:
            case 11:
                return 30;
            default:break;
        }
        return 31;     
    }
}



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

/// <summary>
///日期选择模拟拖动效果
/// </summary>
public class RiLiMove : MonoBehaviour,IPointerDownHandler, IPointerUpHandler
{
    public GameObject go;
    private string name;
    private bool isDown = false;
    Vector3 mouseDown_Pos;       //首次按下坐标
    Vector3 atDown_Pos;          //当前按下坐标   
    float distance = 0;          //距离 差值
    private float self_y;        //当前对象的y值

    void Awake () {
        go = this.gameObject;
        self_y = GetComponent<RectTransform>().localPosition.y;
        name = go.name;
	}
	
	// Update is called once per frame
	void Update () {
        if (isDown && Rili.Singleton.isCanDrag)
        {
            atDown_Pos = Input.mousePosition;
            distance = atDown_Pos.y - mouseDown_Pos.y;
            mouseDown_Pos = atDown_Pos;

            go.GetComponent<RectTransform>().localPosition += new Vector3(0, distance, 0);

            if (Mathf.Abs(self_y - GetComponent<RectTransform>().localPosition.y) >= 5)
            {
                //Debug.Log(self_y + "  ... " +GetComponent<RectTransform>().localPosition.y);
                if (self_y - GetComponent<RectTransform>().localPosition.y < 0)
                {
                    if (name == "year")
                        Rili.yearValue += 1;                    
                    if (name == "month")
                        Rili.monthValue += 1;
                    if (name == "day")
                        Rili.dayValue += 1;
                    if (name == "hour")
                        Rili.hourValue += 1;
                    if (name == "min")
                        Rili.minValue += 1;
                }
                else
                {
                    if (name == "year")
                        Rili.yearValue -= 1;
                    if (name == "month")
                        Rili.monthValue -= 1;
                    if (name == "day")
                        Rili.dayValue -= 1;
                    if (name == "hour")
                        Rili.hourValue -= 1;
                    if (name == "min")
                        Rili.minValue -= 1;
                }
            }
            Rili.Singleton.UpdateTime();
            go.GetComponent<RectTransform>().localPosition = new Vector3(go.GetComponent<RectTransform>().localPosition.x, self_y);
        }
       
    }

    public void OnPointerDown(PointerEventData eventData)
    {
        //Debug.Log("RiLiMove OnPointerDown ... <<<<<<<<<" + name);
        mouseDown_Pos = Input.mousePosition;
        isDown = true;
    }

    public void OnPointerUp(PointerEventData eventData)
    {
        //Debug.Log("RiLiMove OnPointerUp ... >>>>>>>>>" + name);
        isDown = false;
    }
}

看看效果图吧:
result
需要源码的童鞋可以点击链接下载



Demo2:
下载链接
讲解地址
rili

没有积分的同学可以V信搜"开发同学留步"或者扫描主页左侧二维码,回复“日历”获得两个Demo项目源码。

妳是我改卟了的bug CSDN认证博客专家 Unity C# Lua 游戏开发
一个从事游戏开发行业的U3D程序猿,本博客专注分享学到的知识和开发中遇到的问题;若有不足,敬请指正,共同学习,一起进步!!!
已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 黑客帝国 设计师:白松林 返回首页
实付 9.90元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值