Unity入门之U2D——UGUI

UI的成像平面(首先需要设置Canvas的Render Mode为Screen Space-Camera):可以在Canvas->Plane Distance中设置它距离摄像机多远
摄像机的近裁剪平面和远裁剪平面:3D空间的物体,超出此范围会被“裁剪”(不渲染),为了提高渲染效率
Scaler组件:
当我们新建四个按钮:
在这里插入图片描述
如果左右拉伸屏幕,会看到按钮的相对位置会随屏幕分辨率变化而变化,甚至超出屏幕范围
在这里插入图片描述
选择Canvas Scaler的UI Scale Mode的Scale With Screen Size以及Screen Match Mode的Expand,就可实现随屏幕大小缩放
在这里插入图片描述

注:UI Scale Mode各选项的意义——
· Constant:UI不随屏幕大小而改变
· Scale With Screen Size:UI随屏幕大小缩放
    · Expand:匹配宽度
    · Shrinke:匹配高度
 
RecTransform组件:
用于二维物体缩放,继承自Transform类
Pivot:选中的单个物体的正中心
Center:多个物体围成的包围盒的中心
Anchor:锚点,它的改变会使得物体的Position也发生变化,即以该锚点为原点,向右向下为正坐标值
Image控件:
Image Type:Filed模式:可用于制作各类进度条。ClockWise勾选表示顺时针填充,不勾选是逆时针。
Sliced模式:用于制作九宫格——一种可以指定外部区域不缩放,内部区域缩放的图片类型
Tiled模式:重叠模式
Preserve Aspect:使图片缩放不超过其Rect(图片不失真)

练习:编程控制技能CD(技能冷却时间)的刷新,比如技能CD为2秒,则从 Unity脚本启动后直接进入CD状态,2秒后取消CD
新建Image,在Source Image里将技能图拖拽进去,在其下面新建一个子Image,并在Rect Transform处设置锚点,选择stretch右下角加Alt键
在这里插入图片描述
拖拽一个白底图给子Image,并调节其透明度
在这里插入图片描述
选择Fill Method为Radical 360, 不勾选Clockwise,那么Fill Amount从1到0的过程就是顺时针冷却完毕技能的过程
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
给父Image新建一个SkillCD脚本,进行编程

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

public class SkillCD : MonoBehaviour
{
    public Image cdImage;
    public float totalCdSec;//cd总时间
    public bool isCooldown;//是否开始cd
    private float curCdSec;//当前cd时间进度
    // Start is called before the first frame update
    void Start()
    {
        isCooldown = false;
        curCdSec = 0;
    }

    // Update is called once per frame
    void Update()
    {
        if (isCooldown)
        {
            curCdSec += Time.deltaTime;
            cdImage.fillAmount = Mathf.Max(1 - curCdSec / totalCdSec,0);
            if (curCdSec > totalCdSec)
            {
                isCooldown = false;
                curCdSec = 0;
            }
        }
    }
}

RawImage控件:
与Image控件的区别:
Image用于显示Sprite类型的图片
RawImage显示Texture类型的贴图、网络下载的图片
新建一个RawImage,添加一个脚本,实现网络下载图片并显示功能
用到WWW和协程下载图片以及显示:

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

public class DownloadImage : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        StartCoroutine(Download());
    }
    IEnumerator Download()
    {
        WWW www = new WWW("https://gss0.baidu.com/94o3dSag_xI4khGko9WTAnF6hhy/zhidao/wh%3D600%2C800/sign=ecfa515c8e0a19d8cb568c0303caaeb3/64380cd7912397dd810190e95782b2b7d1a287e6.jpg");
        yield return www;//等待协程下载图片完毕,程序才会继续往下执行
        GetComponent<RawImage>().texture = www.texture;
    }
    // Update is called once per frame
    void Update()
    {
        
    }
}

注:若显示的图片是一个红色问号,最大的原因是图片链接不正确,在网上选择图片后,不要直接复制地址,要先右键->检查->Network->F5刷新,选择Img
在这里插入图片描述
选中自己想要的图片对应的链接才是可在代码里下载的链接
在这里插入图片描述
可交互的组合控件(Button、Slider、InputField)
可交互控件——继承自Selectable类
不可交互控件——继承自MaskableGraphic
Button控件
聚合了Image和Button组件
Slider控件:
聚合了Slider组件。由多个部分构成:
Background:背景部分
Fill:进度条填充部分
Handle:句柄部分
Transition TargetGraphic:用于指定交互效果控制哪个对象的图形效果
Navigation :指定可交互控件之间的前后顺序(上下键切换)
InputField控件:
可输入文字

UI层级
子节点覆盖父节点
下节点覆盖上节点
调整层级,RectTransform:
SetAsFirstSibling
SetAsLastSibling
SetSiblingIndex
GetsiblingIndex
如:
子节点Button1覆盖Button2
在这里插入图片描述

同层级的Button1和Button2,在下面的Button2覆盖Button1
在这里插入图片描述

事件监听
给Button1新建一个Button1脚本,并添加OnClick方法
在这里插入图片描述
在Unity的Button控件中,拖拽Button1以及选择Button1的OnClick()方法到On Click()窗口下
在这里插入图片描述
运行,点击Button1按钮可以看到控制台打印出Button1
在这里插入图片描述
新建一个Slider控件,设置其Max Value为10
在这里插入图片描述

给Slider控件添加一个Slider脚本,添加事件代码
在这里插入图片描述
同理拖拽
在这里插入图片描述

在这里插入图片描述
聊天框制作
Image组件做背景,然后添加∶
· Text显示文本,调到能显示全部文本
· ScrollRect用于关联文本滚动(水平、垂直)
· Mask用于文本遮盖
· Scrollbar :关联给ScrollRect.VerticalScrollbar
拖拽事件︰
using UnityEngine.EventSystems
Implements IBeginDragHandler, IEndDragHandler
关联脚本到Image组件

步骤:
新建一个Panel,将其缩小并移动到左下角
在这里插入图片描述

在其子层级新建一个GameObject,并重命名为InputArea
在这里插入图片描述
压缩其大小并移到底部
在这里插入图片描述

在InputArea下新建一个InputField并移动到最左边,新建一个Button改文本为发送并移到最右边
在这里插入图片描述
在Plane下新建一个ScrollView并调节到合适位置
在这里插入图片描述
勾掉Horizontal表示不能左右滚动,只能上下滚动
在这里插入图片描述
在InputField下新建一个Text
在这里插入图片描述
调节到合适位置
在这里插入图片描述
为了实现输入文字点发送按钮后能够发送,给Button添加脚本编写代码
在这里插入图片描述

保存以后在unity里拖拽到对应位置
在这里插入图片描述
onClick()也拖拽和选择
在这里插入图片描述
在这里插入图片描述
运行代码,发现输入文字并点发送后,滚动条自己滚到最底端,而ScrollView的Content上移到顶端,导致发送的文字不在显示范围里
在这里插入图片描述
要往上拖滚动条才能看到

在这里插入图片描述
解决方法是给Content组件添加Vertical layout Group(让content的高度随文本高度适配)
在这里插入图片描述
同时再增加一个ContentSizeFitter组件并选择Vertical Fit的Preferred Size
在这里插入图片描述
运行后,可以看到Content的大小根据文字而适配
在这里插入图片描述
但是发现,每次发送完后定位的是发送前的最后一行
在这里插入图片描述
输入111111111,发送后
在这里插入图片描述
并没有跳到最底层的1111显示,而是依然定位在发送前的位置,直到往下拖动滚动条才能看到
在这里插入图片描述
因此定位部分需要使用协程来修改:
在这里插入图片描述
自动布局
· LayoutElement提供最小、最合适、最大大小信息。
      · lmage实现了ILayoutElement接口,但如果用户额外增加了组件LayoutElement,则Image上实现的ILayoutElement接口失效。
      · IgnoreLayout:有些组件必须放在LayoutGroup下,但是又不想受其控制,就勾选。
· LayoutGroup:该组件所在对象的Width和Height控制子节点的大小和位置(但自身不受控制)
      · Child Force Expand:强制拉伸子节点,使其在水平或垂直方向铺满当前节点
      · Control Child Size: 让子节点大小受LayoutElement组件控制
      · Paddingn:控制最边缘子节点的边缘离LayoutGroup 的内边距(要与ChildAlignment配合使用)
· LayoutControl:
      · Content Size Fitter:控制节点的大小,使其匹配LayoutElement组件的大小(Text、lmage等非组合控件都拥有LayoutElement组件)
      · LayoutGroup控件下不能摆放此控件,因为这两个都能控制大小,会冲突但是LayoutGroup控件可以和此控件放在同一对象上,一个控制分组元素的布局,一个控制分组元素集合的总大小
思考:如果给拥有LayoutEement组件的对象再单独添加LayoutEement组件并指定Min Size、Preferred Size会怎样?
GridLayoutGroup
模拟背包:新建一个Panel,调节大小,在其下新建Image并命名为Item,调节大小后复制八份
在这里插入图片描述

给Panel新添一个Grid Layout Group
在这里插入图片描述
调节各项数值
在这里插入图片描述
在这里插入图片描述
要给背包添加一个标题,在Panel下新建一个Text,但是发现无法自由移动,因为它默认并入了其他Item的布局
在这里插入图片描述
因此对Text新建一个Layout Element并勾选Ignore layout
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
给UI元素添加事件处理功能
方法一:实现相应的事件接口:参考UnityEngine.EventSystems命名空间
例:之前的SendText代码,可以通过实现IPointerClickHandler接口来触发事件,而不用去界面组件上拖拽
在这里插入图片描述

方法二:添加Event Trigger组件,并指定事件处理器
方法三:程序动态添加

可以通过视图->对象浏览器查看接口
在这里插入图片描述
实现通过拖拽窗口的标题来移动窗口位置

在这里插入图片描述
在这里插入图片描述
代码脚本挂载在Drag Zone下
程序思路是:首先通过鼠标点击事件获取当前点击处的位置,通过鼠标拖拽事件获取拖拽后的位置,拖拽后的位置减去拖拽前的位置即为Panel的偏移量,在鼠标点击事件中通过this.transform.parent(即Panel).localPosition可获得拖拽前Panel的位置(以界面的左上角点为锚点),该位置加上偏移量即为拖拽后Panel的位置
在这里插入图片描述
注:RectTransformUtility.ScreenPointToLocalPointInRectangle(RectTransform rect, Vector2 screenPoint, Camera cam, out Vector2 localPoint)
将屏幕空间点变换到矩形变换的局部空间中位于矩形平面上的位置

实现通过拖拽窗口角点来调整大小
在这里插入图片描述
实现Mylighting——能通过拖拽滑杆来调节面板颜色
新建Panel,并设其透明度为255
在这里插入图片描述
新建三个Slider并重命名为红绿蓝
在这里插入图片描述
将其Fill Area的fill的color颜色改为对应的红绿蓝色
在这里插入图片描述

在这里插入图片描述
给Panel新建脚本
在这里插入图片描述
在各个Slider里的On Value Changed中拖拽和选择
在这里插入图片描述

在这里插入图片描述
渲染纹理
新建一个RawImage并strech
在这里插入图片描述
新建一个Render Texture并命名为Render Texture
在这里插入图片描述
拖拽到RawImage的Texture里
在这里插入图片描述
将模型导入并拖拽到Hierarchy
在这里插入图片描述
新建平行光
在这里插入图片描述
选择Global并将模型移到场景外
在这里插入图片描述
(未完)

拖拽物品到背包,若未拖拽到指定位置则恢复初始位置
思路:
在这里插入图片描述

新建一个Image对象并命名为DragImage,拖拽图片
在这里插入图片描述
给DragImage添加一个脚本,编写代码

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

public class DragImage : MonoBehaviour,IPointerClickHandler
{

    // Start is called before the first frame update
    private void OnEnable()
    {
        //在Dragimage的位置创建一个相同的图片,起名为icon
        GameObject icon = new GameObject("icon");//新建icon对象
        GameObject canvas=GameObject.Find("Canvas");
        icon.transform.position = this.transform.position;//icon跟随DragImage的位置
        icon.transform.SetParent(canvas.transform, true);//设置icon为Canvas的子节点,true表示保持icon在上一步中设置好的场景中的位置不变
        Image img = icon.AddComponent<Image>();//给icon新增Image组件并赋给变量img
        img.sprite = this.GetComponent<Image>().sprite;//icon的图片与DragImage的同步

    }

    public void OnPointerClick(PointerEventData eventData)
    {
        print("你点击了Dragimage");
    }

}

写到这一步的时候,保存并运行测试,发现不论怎么点击DragImage始终不会打印“你点击了DragImage”,因为生成的icon位于DragImage的同层级下方,点击的时候默认点击的icon
在这里插入图片描述
所以要给icon添加一个Canvas Group组件并还要勾掉Blocks Raycasts,像下面这样
在这里插入图片描述
在代码中加入下面这行

 icon.AddComponent<CanvasGroup>().blocksRaycasts = false;//防止icon阻挡鼠标点击其背后的DragImage

完整代码为

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

public class DragImage : MonoBehaviour,IBeginDragHandler,IDragHandler,IEndDragHandler
{

    private Vector3 m_offset;//以图片中心为终点,以鼠标位置为起点的向量
    private GameObject m_icon;
    private RectTransform m_canvas;
    private void OnEnable()
    {
        m_canvas = GameObject.Find("Canvas").transform as RectTransform;
        //在Dragimage的位置创建一个相同的图片,起名为m_icon
        m_icon = new GameObject("icon");//新建m_icon对象
        m_icon.transform.position = this.transform.position;//m_icon跟随DragImage的位置
        m_icon.transform.SetParent(m_canvas.transform, true);//设置m_icon为Canvas的子节点,true表示保持m_icon在上一步中设置好的场景中的位置不变
        Image img = m_icon.AddComponent<Image>();//给m_icon新增Image组件并赋给变量img
        img.sprite = this.GetComponent<Image>().sprite;//m_icon的图片与DragImage的同步
        m_icon.AddComponent<CanvasGroup>().blocksRaycasts = false;//防止m_icon阻挡鼠标点击其背后的DragImage
    }


    public void OnBeginDrag(PointerEventData eventData)
    {
        Vector3 imgPos;
        RectTransformUtility.ScreenPointToWorldPointInRectangle(m_canvas, this.transform.position, eventData.pressEventCamera, out imgPos);
        Vector3 cursorPos;
        RectTransformUtility.ScreenPointToWorldPointInRectangle(m_canvas, eventData.position, eventData.pressEventCamera, out cursorPos);

        m_offset = imgPos - cursorPos;
    }

    public void OnDrag(PointerEventData eventData)
    {
        Vector3 cursorPos;
        RectTransformUtility.ScreenPointToWorldPointInRectangle(m_canvas, eventData.position, eventData.pressEventCamera, out cursorPos);
        Vector3 imgPos;
        imgPos = cursorPos + m_offset;
        m_icon.transform.position = imgPos;
    }

    public void OnEndDrag(PointerEventData eventData)
    {
        m_icon.transform.position = this.transform.position;//this表示DragImage,一直没有动
    }
}

下面来实现拖拽到指定位置放下:
新建一个Image为DropSlot,将表示篮筐的透明图片拖拽到里面,给DropSlot添加代码:

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

public class MyDropImage : MonoBehaviour, IDropHandler
{
    // Start is called before the first frame update
    public void OnDrop(PointerEventData eventData)
    {
        this.GetComponent<Image>().sprite = eventData.pointerDrag.GetComponent<Image>().sprite;
        this.GetComponent<Image>().color = eventData.pointerDrag.GetComponent<Image>().color;
    }
}

(未完待续…)

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值