Unity3D學習筆記(二十):Rect、Canvas、Toggle、Slider、ScrollBar
阿新 • • 發佈:2019-02-12
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、手動拖拽 privateCanvas(畫布):所有的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 DistanceRectTransform 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); } }
----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 = boolUnityEvent: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