zoukankan      html  css  js  c++  java
  • Unity3D学习笔记(二十):Rect、Canvas、Toggle、Slider、ScrollBar

     
    Rect Transform(锚点):图片中心的四个点,界面以雪花形式显示
    当四个点在一起的时候组成锚点,当四个点分开的时候组成锚框(合则锚点,分则锚框)

    Anchors:
    ----Min x:控制左两个点,当为0的时候,左两个点在父物体边框的左边缘,当为1时,左两个点在父物体边框的右边缘(取值范围并不是0~1)
    ----Min y:控制下两个点,当为0的时候,下两个点在父物体边框的下边缘,当为1时,下两个点在父物体边框的上边缘(取值范围并不是0~1)
    ----Max x:控制右两个点,当为0的时候,右两个点在父物体边框的左边缘,当为1时,右两个点在父物体边框的右边缘(取值范围并不是0~1)
    ----Max y:控制上两个点,当为0的时候,上两个点在父物体边框的下边缘,当为1时,上两个点在父物体边框的上边缘(取值范围并不是0~1)

    当四个点在一起时:
    ----Pos X, Pos Y, Pos Z(锚点坐标):图片中心点相对于锚点的坐标
    ----Width, hight:图片的宽高
    当四个点分开的时:
    ----Left:物体的左边框距离左两个锚点组成左锚框的距离;正值表示左锚框在左边框的左边,负值相反
    ----Top:物体的上边框距离上两个锚点组成上锚框的距离;正值表示上锚框在上边框的上方,负值相反
    ----Right:物体的右边框距离右两个锚点组成右锚框的距离;正值表示右锚框在右边框的右边,负值相反
    ----Bottom:物体的下边框距离下两个锚点组成下锚框的距离;正值表示下锚框在下边框的下方,负值相反
    锚点作用:子物体自适应父物体拉伸的变化,父物体挤压过度,子物体会消失
    Rect Transform的两个可选的编辑模式:Width, hight后的两个按钮。
    第一个按钮(虚方框):如果选择后,不能鼠标旋转图片。
    第二个按钮(R):如果选择后,当改变中心点的值时,中心点不动,图片移动。
    Pivot(中心点,轴心点):旋转中心
    ----X:0时,在物体左边框的位置,1时,物体右边框的位置(取值范围并不是0~1)
    ----Y:0时,在物体下边框的位置,1时,物体上边框的位置(取值范围并不是0~1)

    框的显示:快捷键T

    代码操作,继承Transform

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    public class UGUI_RectTransform : MonoBehaviour {
        public Canvas canvas;
        //1、手动拖拽
        private RectTransform rt;
           // Use this for initialization
           void Start () {
            //2、获取方式
            rt = GetComponent<RectTransform>();
            //3、里氏转换原则
            rt = transform as RectTransform;
            //锚点坐标(物体中心点相对于锚点的坐标)
            //rt.anchoredPosition = new Vector2(50, 100);
            //世界坐标
            //rt.position = Vector3.zero;
            //相对于父物体坐标系的坐标, 跟锚点坐标不一样。
            //rt.localPosition = new Vector2(50, 100);
            //设置物体的宽高。只有四个点在一起组成锚点时使用
            //rt.sizeDelta = new Vector2(500, 400);
            //设置锚点
            //rt.anchorMax = Vector2.one * 0.5f;
            //rt.anchorMin = Vector2.one * 0.5f;
            //当四个点不在一起组成锚框时
            //设置的是Left和Bottom,界面的值就是100, 50
            //rt.offsetMin = new Vector2(100, 50);
            //设置的是Right和Top,界面的值是设置值的负值 -100  50
            //rt.offsetMax = new Vector2(100, 50);
            //设置中心点
            rt.pivot = Vector2.one;
            InstanceImage();
        }
           
           // Update is called once per frame
           void Update () {
            //if (Input.GetMouseButton(0))
            //{
            //    rt.anchoredPosition = new Vector2(500, 400);
            //}
            //if (Input.GetMouseButton(1))
            //{
            //    rt.position = Vector3.zero;
            //}
            //if (Input.GetMouseButton(2))
            //{
            //    rt.localPosition = new Vector2(50,100);
            //}
        } 
        void InstanceImage()//加载图片,默认生成在层级面板的根目录下
        {
            GameObject prefab = Resources.Load<GameObject>("prefab");
            GameObject obj = Instantiate(prefab, canvas.transform);
        }
    }
     
    Canvas(画布):所有的UGUI的组件都需要放在Canvas下才能显示
    Render Mode(渲染模式):
    ----Screen Space – Overlay(屏幕空间-覆盖):这种模式下,所有的UI都会放在最前方,会覆盖掉其他物体显示。
    --------Sort Order:当多个Canvas时,如果所有的Canvas都是Screen Space – Overlay这种模式,那么当Sort Order的值越大,该Canvas越后渲染,越显示在屏幕的最前方。
    ----Screen space – Camera(屏幕空间-相机渲染):该模式下,必须指定一个渲染该Canvas的摄像机,3D物体可以遮挡住UI。Rect Transorm不可修改,随相机深度进行缩放
    --------Plane Distance:Canvas画布距离渲染相机的距离
    --------该模式下,不同的Canvas渲染的关系:
    --------首先判断Sorting Layer:值越靠后越后渲染。
    --------如果Sorting Layer值相同,再判断order in layer:值越大越后渲染,越再屏幕的前方。
    --------如果order in layer值也相同,再判断plane distance:距离相机越近,越显示在屏幕的前方。
    --------优先级:Sorting Layer -> Order in Layer -> Plane Distance

    ----World Space(世界空间):只有该模式下Canvas的Rect Transorm才能编辑,并且纵深Z值有效了。

    Canvas Scaler(画布缩放):
    ----UI Scale Mode
    --------ConstantPixel Size:画布的尺寸像素会随着屏幕的变化而变化(少用)
    --------Scale With Screen Size:画布的尺寸像素跟屏幕分辨率无关,需要指定画布的尺寸像素(常用)
    ------------Reference Resolution:指定画布的尺寸。
    --------Constant Physical Size:每个屏幕渲染多少个DPI(很少用)
    --------Screen Match Mode:
    ------------Match With or Heitht:以屏幕宽或者高作为适配
    ------------Expand:不管屏幕分辨率是多少,画布的内容一定要全部显示出来
    ------------Shrink:不管屏幕分辨率是多少,一定要使用画布的内容充满整个屏幕

    Graphic Raycaster
    Ignore Reversed Graphics:是否忽略反面的射线检测
    Blocking Objects:指定物体对UI射线检测产生影响(非overlay的情况)
    Blocking Mask:指定哪一个层的物体对UI射线检测产生影响;
    Toggle(单选框)
    交互、过渡、导航
    Is On:是否选中
    Toggle Transition(过渡效果):无,淡入淡出
    Graphic:选中时显示的图片,默认对勾图片
    Group(单选框组):
    OnValueChanged:当Is On改变的时候,执行里面存储的所有方法
    ----1、拖拽形式,方法必须是公共的,可以有参可以无参,注意:有bool型参数的时候注意可变参数和固定参数。
    ----2、代码注册事件的形式:注意只能把无返回值,有bool型参数的方法注册进去。
    Button的OnClick无参,方块代表是固定参数
    Toggle的OnValueChanged有参,方块代表是可变参数
    代码操作
    Toggle -> ToggleEvent -> UnityEvent -> UnityAction
    ToggleEvent:参数T0 = bool

    UnityEvent:Invoke方法也需要有一个bool类型的参数

    UnityAction:无返回值的泛型委托,参数未指定

    Toggle Group(单选框组):实现一组Toggle的单选效果,只有一个Group内的Toggle才是一个组。

    Allow Switch off
    勾选:可全部为空
    取消:必须选一个
    Slider组件(滑动条)
    Fill Rect:填充的就行,进度的图片
    Handle Rect:句柄,索引的图片
    Direction:方向
    Min/Max Value:最大值,最小值
    Whole Numbers:是否整数变化
    Value:值,进度值
    OnValueChanged:当Value值变化时执行里边所有的方法
    ----1、拖拽方式,方法必须是公共的,注意固定参数和可变参数。
    ----2、代码注册事件的方式:方法必须是无返回值,有一个float类型的参数的方法。
    自制滑动条
    同一Canvas下,越靠下的位置越靠前
    代码操作
    slider.normalizedValue:为值的百分比
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.UI;
    public class UGUI_Slider : MonoBehaviour {
        private Slider slider;
        private float value = 0f;
        // Use this for initialization
        void Start () {
            slider = GetComponent<Slider>();
            //slider.value为实际的值
            Debug.Log("Value: " + slider.value);
            //slider.normalizedValue为值的百分比
            Debug.Log("Value: " + slider.normalizedValue);
            slider.value = 0f;
            slider.onValueChanged.AddListener(AddValueChanged);
        }
        // Update is called once per frame
        void Update () {
            value += Time.deltaTime;
            slider.value = value;
           }
        public void OnValueChanged(float value)
        {
            Debug.Log("手动添加的value:" + value);
        }
        private void AddValueChanged(float value)
        {
            Debug.Log("代码添加的value:" + value);
        }
    }

    精灵图片批量添加动画:1、全选拖入,2、修改帧数

    综合练习-音乐开关
    图片挤压问题,图片格式改成水平填充

    滑动值改为整数

    代码操作

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.UI;
    public class UGUI_SliderMusic : MonoBehaviour {
        private Slider slider;
        private AudioSource source;
        private void Awake()
        {
            source = gameObject.AddComponent<AudioSource>();
            AudioClip clip = Resources.Load<AudioClip>("OnOff/SingleDog");
            source.clip = clip;
            source.Play();
            slider = GetComponent<Slider>();
            slider.onValueChanged.AddListener(OnValueChanged);
        }
        // Use this for initialization
        void Start () {
            slider.value = 0;
        }
           
           // Update is called once per frame
           void Update () {
            slider.value = 0;
        }
        private void OnValueChanged(float value)
        {
            if (value > 0.5f)//打开音乐
            {
                source.volume = 1;
            }
            else//关闭音乐
            {
                source.volume = 0;
            }
        }
    }
    ScrollBar组件(滚动条)
    Value:类型float,范围0~1
    Size:句柄的宽度,范围0~1
    Number Of Steps:有几个滑动位置,0和1表示无限制,最大值为11,11个位置10段

    自制滚动条

    OnValueChanged:可变参数

    OnValueChanged(float):固定参数

    把锚点和图片的中心点,设置在左边框,则ScrollBar从0~1,就是图片从0~-1720(1720为图片宽度减画布宽度,负号因为和锚点方向相反)
    代码操作
    GameObeject.find,类名.方法名,静态
    transform.find,对象名.方法名
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.UI;
    public class UGUI_ScrollBar : MonoBehaviour {
        private Scrollbar bar;
           // Use this for initialization
           void Start () {
            bar = GetComponent<Scrollbar>();
            bar.value = 0.5f;//改变Scrollbar的值
            bar.size = 0.4f;//改变句柄大小
            bar.onValueChanged.AddListener(OnValueChanged);
        }
           
           // Update is called once per frame
           void Update () {
                  
           }
        public void OnValueChanged(float value)
        {
            Debug.Log("值变了:" + value);
        }
    }
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.UI;
    public class UGUI_ScrollBar_Image : MonoBehaviour {
        private Scrollbar bar;//滚动条
        private RectTransform imageX;//图片
        private float canvasX = 1920f;//画布
        private float offset;//偏移量
        private void Awake()
        {
            //
            //GameObeject.Find();
            //从子物体里寻找物体,参数是路径,并且支持层级结构
            bar = transform.Find("Canvas/Scrollbar").GetComponent<Scrollbar>();
            //通过方法找到物体的transform直接转换成Rect Transform
            imageX = transform.Find("Canvas/Image") as RectTransform;
            bar.onValueChanged.AddListener(OnValueChanged);
        }
        // Use this for initialization
        void Start () {
            // - (图片的宽度 - 画布的宽度)
            offset = canvasX - imageX.sizeDelta.x;
            //当图片宽度小于画布宽度时,滚动条没有意义,不需要显示
            //offset 大于 0 的时候证明图片的宽度小于画布的宽度
            if (offset >= 0)
            {
                bar.gameObject.SetActive(false);
            }
            else
            {
                bar.gameObject.SetActive(true);
            }
            bar.value = 0;
           }
           
           // Update is called once per frame
           void Update () {
                  
           }
        //当Scroll bar的值改变时,执行的方法
        private void OnValueChanged(float value)
        {
            //根据value的值去改变图片的位置
            float posX = value * offset;
            imageX.anchoredPosition = new Vector2(posX, imageX.anchoredPosition.y);
        }
    }
    补充内容-Rect Transform
    当锚点分开时,怎么使用anchoredPosition移动图片到中心点的位置
    设置位置:
    参考锚点的计算公式
    anchoredPosition是锚点指向中心点的向量

    设置大小:
    锚框的计算公式
    sizeDelta的值和宽高无关
    代码逻辑
    锚线的设置
    水平锚线:y相等,x不等
    垂直锚线:x相等,y不等
    算出参考锚点,偏移参考锚点
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.UI;
    public class RectTransformTest : MonoBehaviour
    {
        public RectTransform leftImg;   // 设置的是锚点
        public RectTransform rightImg;  // 设置的是锚框
        public RectTransform upImg;     // 设置的是水平锚线
        public RectTransform downImg;   // 设置的是垂直锚线
        void Start()
        {
            // 设置图片的尺寸为 400,300
            // 设置图片的位置为 父物体的中心位置
            // ========================== leftImg 设置的是锚点
            if (leftImg.anchorMin.x == leftImg.anchorMax.x && leftImg.anchorMin.y == leftImg.anchorMax.y)
            {
                // 设置位置
                leftImg.anchoredPosition = Vector2.zero;
                // 设置图片尺寸
                leftImg.sizeDelta = new Vector2(400, 300);
            }
            // ========================== rightImg 设置的是锚框
            if (rightImg.anchorMin.x != rightImg.anchorMax.x && rightImg.anchorMin.y != rightImg.anchorMax.y)
            {
                // 设置位置
                float anchorReferensePointX = (1 - rightImg.pivot.x) * rightImg.anchorMin.x + rightImg.pivot.x * rightImg.anchorMax.x;
                float anchorReferensePointY = (1 - rightImg.pivot.y) * rightImg.anchorMin.y + rightImg.pivot.y * rightImg.anchorMax.y;
                rightImg.anchoredPosition = rightImg.pivot - new Vector2(anchorReferensePointX, anchorReferensePointY);
                // 设置图片尺寸
                //rightImg.offsetMin = new Vector2(100, 100);
                //rightImg.offsetMax = new Vector2(-100, -100);
                rightImg.sizeDelta = new Vector2(-200, -200);
                //Debug.Log("RightImg sizeDelta : " + rightImg.sizeDelta);   // sizeDelta = offsetMax - offsetMin; 结果: (-200, -200)
            }
            // ========================== upImg 设置的是水平锚线 (上方)
            if(upImg.anchorMin.y == upImg.anchorMax.y && upImg.anchorMin.x != upImg.anchorMax.x)
            {
                // 设置位置
                float anchorReferensePointX = (1 - upImg.pivot.x) * upImg.anchorMin.x + upImg.pivot.x * upImg.anchorMax.x;
                float anchorReferensePointY = (1 - upImg.pivot.y) * upImg.anchorMin.y + upImg.pivot.y * upImg.anchorMax.y;
                Vector2 anchorPos = upImg.pivot - new Vector2(anchorReferensePointX, anchorReferensePointY);
                RectTransform parentTrans = upImg.parent as RectTransform;
                anchorPos.y -= parentTrans.rect.height / 2;
                upImg.anchoredPosition = anchorPos;
                // 设置图片尺寸
                upImg.offsetMin = new Vector2(100, -400);
                upImg.offsetMax = new Vector2(-100, -100);
                //upImg.sizeDelta = new Vector2(-200, 300);
            }
            // ========================== downImg 设置的是垂直锚线 (左方)
            if (downImg.anchorMin.x == downImg.anchorMax.x && downImg.anchorMin.y != downImg.anchorMax.y)
            {
                // 设置位置
                float anchorReferensePointX = (1 - downImg.pivot.x) * downImg.anchorMin.x + downImg.pivot.x * downImg.anchorMax.x;
                float anchorReferensePointY = (1 - downImg.pivot.y) * downImg.anchorMin.y + downImg.pivot.y * downImg.anchorMax.y;
                Vector2 anchorPos = downImg.pivot - new Vector2(anchorReferensePointX, anchorReferensePointY);
                RectTransform parentTrans = downImg.parent as RectTransform;
                anchorPos.x += parentTrans.rect.width / 2;
                downImg.anchoredPosition = anchorPos;
                // 设置图片尺寸
                downImg.offsetMin = new Vector2(100, 100);
                downImg.offsetMax = new Vector2(500, -100);
                //downImg.sizeDelta = new Vector2(400, -200);
            }
        }
        void Update()
        {
        }
    }

    补充内容-Unity的委托和事件

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.Events;  // Unity中使用的委托和事件的命名空间
    // C#中使用的委托
    // using System;  // Action、Action<T>、Action<T, A> .....Action<A, B, C, .....>  没有返回值的
    // Func<TResult>、Func<T, TResult>、Func<A, B, .... TResult>    有返回值的
    // Predicate<T> 有一个参数,返回值是bool类型
    // Comparison<T>(T x, T y) 返回值是int型
    public class UnityEventTest : MonoBehaviour
    {
        public UnityAction myAction;
        public UnityEvent myEvent1;   // 可以在检视面板中显示 用法同UI
        public MyEvent2 myEvent2;
        void Start()
        {
            #region Unity中提供的委托
            // 没有返回值 没有参数 相当于C#中的 Action
            UnityAction del1 = delegate ()
            {
                Debug.Log("delegate");
            };
            del1 += () => { Debug.Log("Lambda"); };
            del1 += Fun1;
            del1();
            UnityAction<int> del2 = delegate (int num) { Debug.Log(num); };
            // 有参的匿名委托,Unity委托中参数的个数最多4个
            UnityAction<int, int, int, int> del3 = (a, b, c, d) => { Debug.Log(a + b + c + d); };
            #endregion
            #region Unity中的事件
            UnityEvent myEvent = new UnityEvent();
            // 注册方法
            myEvent.AddListener(
                  () =>
                  {
                      Debug.Log("这是Unity中的事件");
                  }
                );
            myEvent.AddListener(Fun1);
            // 取消注册
            myEvent.RemoveListener(Fun1);
            myEvent.RemoveAllListeners();//无返回值无参数的事件,匿名委托只能用RemoveAllListeners();
            // 调用
            myEvent.Invoke();
            // Unity中有参数的事件 需要自己写一个类去继承 UnityEvent<T> 参数个数:最多4个
            // 通过自己的类去创建对象
            MyEvent2 myEvent2 = new MyEvent2();
            // 注册和取消注册同上
            // 调用
            myEvent2.Invoke(10);
            #endregion
        }
        void Update()
        {
        }
        public void Fun1()
        {
        }
    }
    public class MyEvent2 : UnityEvent<int> { }
    public class MyEvent3 : UnityEvent<int, float, bool, string> { }
  • 相关阅读:
    Codeforces Round #481 (Div. 3)题解
    陕西师范大学第七届程序设计竞赛网络同步赛题解
    Codeforces Round #479 (Div. 3)题解
    2018年北京信息科技大学第十届程序设计竞赛暨ACM选拔赛题解
    江西财经大学第一届程序设计竞赛题解
    2018年湘潭大学程序设计竞赛G又见斐波那契
    2018年长沙理工大学第十三届程序设计竞赛题解
    JDBC连接SQL server2014代码
    数据定义伪指令语句
    JDBC连接数据库
  • 原文地址:https://www.cnblogs.com/vuciao/p/10363450.html
Copyright © 2011-2022 走看看