Unity3D學習筆記(二十二):ScrollView和事件接口


昨天問題
InputField光標被遮擋問題:背景圖片輸入層級高於光標的層級,把光標弄成子物體,子物體層級高

自制的滑動框,選項怎么對齊,把Template的Pivot.y改為1

分辨率的區別:16:9和1920x1080
16:9,屏幕像素按比例縮放,文本會變模糊
1920x1080,屏幕像素是固定的

Canvas Group:控制一組UI的某些屬性(所有子物體的UI組件的屬性)
Alpha:改變所有子物體的透明通道,0不顯示,1顯示
Interactable:改變所有子物體的交互狀態,可交互,不可交互
Blocks Raycasts:改變所有子物體的射線檢測,接受射線檢測,不接受射線檢測
Ignore Parent Group:是否忽略父物體的Canvas Group的影響

登錄界面的淡入淡出效果

Panel組件(少用)
作用:背景圖或父物體
 
ScrollView組件(拖動框)
Content:可拖動的物體,改變image的父物體Content的坐標
Horizontal、Vertical:是否可以水平、垂直拖動
Movement Type:移動類型
----Elastic:回彈原位,會自動回到對齊的位置
--------Elasticity回彈系數,值越大回彈越慢
----Unrestricted:自由拖動,無限制,拖到哪就是哪
----Clamped:有限制的,拖動物體的拖動框最多能跟視窗對齊,父物體邊緣限制在視窗邊緣
Inertia:慣性
----Deceleration Rate:慣性的衰減系數,0相當於沒有慣性,1
Scroll Sensitivity:鼠標滾輪的滾動系數
Viewport:視窗,如果未指定,則視窗默認為ScrollRect的范圍
Horizontal ScrollBar:水平滾動條
----Visibility:顯示方式
--------Permanent:永久顯示
--------Auto Hide:自動隱藏
--------Auto Hide And Expand Viewport:自動隱藏並且擴展視窗
Vertical ScrollBar:垂直滾動條
Mask遮罩:圖片圓形顯示
遮罩依賴於Image圖片形狀,必須與Image一起使用,否則無效
Show Mask Graphic:是否顯示遮罩的圖片

Viewport里的遮罩

自制拖動框

綜合練習-拖動框

Hrizontal Layout Group:水平自動布局組件(對自己的子物體)
Padding:距離四個邊緣的間距,距離四個變量的距離
Spacing:各個元素之間的間距
Child Alignment:子物體的對齊方式
Child Control Size:
----Width:是否強行擴大子物體的寬度,來填補額外的可用空間
----Height:是否強行擴大子物體的高度,來填補額外的可用空間
----勾選后,子物體的寬高會變成不可編輯
Child Force Expand:是否強行擴大物體間的橫向間隔,來填補額外的可用空間
Movement Type - Clamped:
需要在Content的長度比Viewport大的情況下才可以拖動
可以使用自動擴容組件,給Content動態添加長度
Content Size Fitter(自動擴容組件)
Horizontal Fit:水平自動擴容
----Unconstralned:不需要自動擴容
----Min Size:最小值
----Preferred Size:最合適的值(常用)
一般情況下,需要和自動布局組件或Text組件一起使用
自動擴容后,寬高變為不可修改

名稱顯示

代碼操作

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class SelectUI : MonoBehaviour {
    public Text nameText;
    public string playerName;
    private Toggle toggle;
    // Use this for initialization
    void Start () {
        toggle = GetComponent<Toggle>();
        toggle.onValueChanged.AddListener(OnValueChanged);
    }
       
       // Update is called once per frame
       void Update () {
              
       }
    void OnValueChanged(bool isOn)
    {
        Debug.Log("OnValueChanged");
        nameText.text = isOn ? playerName : "";
    }
}
UGUI事件接口
命名空間:using UnityEngine.EventSystems;
繼承了UGUI事件接口的類,掛載物體上,只要子物體或自己本身能接受射線檢測,接口就是可以執行的。
接口簡介:指針點擊接口
IPointerClickHandler:當鼠標指針點擊,執行接口里的方法(在圖片內點擊,在圖片內抬起)
IPointerDownHandler:當鼠標指針按下
IPointerUpHandler:當鼠標指針抬起,執行接口里的方法(在圖片內點擊,在圖片內外抬起)
IPointerEnterHandler:當鼠標指針進入
IPointerExitHandler:當鼠標指針離開
右鍵點擊按鈕

代碼操作

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class RightButton : MonoBehaviour,
    IPointerEnterHandler,
    IPointerExitHandler,
    IPointerDownHandler,
    IPointerUpHandler,
    IPointerClickHandler
{
    public Graphic graphic;//改變顏色的圖像
    public Color normalColor = Color.white;
    public Color enterColor = Color.white;//當鼠標進入時按鈕的顏色
    public Color pressColor = Color.white;//當鼠標按下時按鈕的顏色
    //onClick存儲所有的在點擊的時候執行的方法
    public RightButtonEvent onClick = new RightButtonEvent();
    private bool isExit = true;//鼠標是否離開圖片區域
    private void Awake()
    {
        if (graphic == null)
        {
            graphic = GetComponent<Graphic>();
        }
    }
    public void OnPointerEnter(PointerEventData eventData)
    {
        //當鼠標進入時改變顏色
        graphic.color = enterColor;
        isExit = false;
    }
    public void OnPointerExit(PointerEventData eventData)
    {
        graphic.color = normalColor;
        isExit = true;
    }
    public void OnPointerDown(PointerEventData eventData)
    {
        //只有按下鼠標右鍵才有效果
        if (eventData.button == PointerEventData.InputButton.Right)
        {
            graphic.color = pressColor;
        }
    }
    public void OnPointerUp(PointerEventData eventData)
    {
        if (eventData.button == PointerEventData.InputButton.Right)
        {
            //判斷鼠標是否在圖片內部
            if (isExit)
            {
                graphic.color = normalColor;
            }
            else
            {
                graphic.color = enterColor;
            }
        }
    }
    public void OnPointerClick(PointerEventData eventData)
    {
        if (eventData.button == PointerEventData.InputButton.Right)
        {
            onClick.Invoke();
        }
    }
    [System.Serializable]//這個類是可序列化的
    public class RightButtonEvent : UnityEvent
    {
    }
}
隱式實現
顯示實現,兩個接口有同名方法時使用

默認不區分鼠標左鍵右鍵和中鍵,可通過枚舉類型,判斷鼠標按鍵

給事件添加方法

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class RightButtonTest : MonoBehaviour
{
    private RightButton rightButton;
       // Use this for initialization
       void Start () {
        rightButton = GetComponent<RightButton>();
        rightButton.onClick.AddListener(Click);
    }
       
       // Update is called once per frame
       void Update () {
              
       }
    public void Click()
    {
        Debug.Log("點擊了右鍵按鈕");
    }
}

鼠標點擊,跟隨移動

PointerEventData類
button:鼠標按鍵的枚舉
position:當前鼠標在屏幕中的位置
pressPosition:按下時鼠標在屏幕中的位置
enterEventCamra:當進入時的事件相機(在overlay 模式下為null)
pressEventCamra:當按下時的事件相機(在overlay 模式下為null)
代碼操作
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class ClickButton : MonoBehaviour, IPointerClickHandler {
    public GameObject image;
    public void OnPointerClick(PointerEventData eventData)
    {
        //轉換坐標的API
        //轉換出來的是局部坐標,localPosition
        //第一個參數:想要以哪個坐標系為參考(一般情況下都是父物體坐標系)
        //第二個參數:屏幕坐標(鼠標所在的屏幕坐標)
        //第三個參數:相機
        //第四個參數:轉換成功之后的局部坐標
        //返回值
        Vector2 outPos;
        bool isSuccess = RectTransformUtility.ScreenPointToLocalPointInRectangle(
            image.transform.parent as RectTransform,
            eventData.position,
            Camera.main,//eventData.pressEventCamera,
            out outPos
            );
        if (isSuccess)
        {
            image.transform.localPosition = outPos;
        }
    }
    // Use this for initialization
    void Start () {
              
       }
       
       // Update is called once per frame
       void Update () {
              
       }
}

Overlay模式 ,代碼可以填寫null

Camera模式,可以填渲染攝像機

使用錨點坐標來移動的問題
將錨點設置在畫布的左下角(0,0),通過用錨點坐標改變圖片位置
但當錨點不在中心點時,屏幕分辨率變化,畫布變化,錨點也會改變
小地圖

添加Render Texture

畫布設置

相機設置

標簽設置

相機遮罩設置

角色展示
攝像機設置純色,剔除背景

角色旋轉代碼邏輯

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class LeonaRotate : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler
{
    public GameObject obj;
    bool isInImage = false;
    public void OnPointerEnter(PointerEventData eventData)
    {
        isInImage = true;
    }
    public void OnPointerExit(PointerEventData eventData)
    {
        isInImage = false;
    }
    // Update is called once per frame
    void Update()
    {
        if (isInImage && Input.GetMouseButton(0))
        {
            float offsetX = Input.GetAxis("Mouse X");
            obj.transform.rotation *= Quaternion.Euler(0, -offsetX * 60f, 0);
        }
        else
        {
            obj.transform.rotation = Quaternion.Slerp(obj.transform.rotation, Quaternion.Euler(0, 180, 0), 0.1f);
        }
    }
}

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM