1. 程式人生 > >Unity3D學習筆記(二十):Rect、Canvas、Toggle、Slider、ScrollBar

Unity3D學習筆記(二十):Rect、Canvas、Toggle、Slider、ScrollBar

png 批量添加 事件 func 快捷鍵 resource engine 選中 創建

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> { }

Unity3D學習筆記(二十):Rect、Canvas、Toggle、Slider、ScrollBar