泰斗破坏神的学习笔记

本篇只记录我个人觉得有难度,有用的知识点,也因为是写给自己看的,所以对于排版没有什么讲究!

第一章:用户的注册与登录的UI界面

UI界面一共五个面板,开始面板登录面板注册并登录面板服务器面板确定人物选择面板选择人物面板!!!

其中《开始面板》、《登录面板》、《注册面板》、《确定人物选择面板》,并没有什么难度,所以不进行叙述!
而面板之间的切换,也只是在每个面板中添加 NGUI 的 TweenScale 脚本,然后在脚本中写监听事件给面板的 Button 来进行切换!

1. 服务器面板:

红圈处就是我们要生成服务器的地方。
这里需要用动态列表生成
首先需要创建三个 panel(Slide-list-Frame、List、Grid) 和一个 Scrollbar
在这里插入图片描述
Slide-list-Frame、List、Grid 的Transform都在红圈内的!
《Slide-list-Frame》 添加 Scroll Rect 组件
《List》 添加 Mask 组件
在这里插入图片描述
目的: Scroll Rect 通常是和 Mask 组件一起使用的。 Mask 组件的功能是使滑动到 Scroll Rect 指定区域之外的内容隐藏。
ShowMaskGraphic: 决定了是否显示原 Image 纹理。若去掉勾选,则 Image 只被用作裁剪区域的选取之用,不会被渲染出来
通俗点说就是:勾选就显示 Image,不勾选就不显示 Image

以下是加 Mask 与没加 Mask 的区别:
在这里插入图片描述
在这里插入图片描述
ScrollRect 组件的参数:在这里插入图片描述
Content: 滑动的内容,也就是 Grid ,因为将在该物体下生成服务器(预制体)

Horizontal: 水平滑动

Vertical : 垂直滑动 (这里只需要垂直滑动,所以只勾选 Vertical)

Movement Type : 滑动状态

**unrestricted:** 没有回弹效果,实现效果非常生硬(具体自己可以测下,语言表达能力有限)  

**Elastic :** 最理想的滑动,有回弹 有摩擦力  

**Clamped:** 无滑动

**Elasticity:** 回弹的时间,越大越慢回到原来的位置

Inertia : 滑动结束时是否拥有惯性移动,为ture时会以Deceleration-Rate的值作为惯性的量!(勾上之后,滑动会顺畅很多)

**Decelaration-Rate:** 正常值为0 – 1 , 该值大于等于1时则永远不会减速,除非到达边界

**Scroll Sensitivity:** 对于鼠标滚动轮或触控板的敏感度,该值越大,对鼠标滑轮的滚动反应越大,可以自行测试,对手指滑动和鼠标拖动影

响不大(目前未看到明显影响);

Viewport: ScrollRect的可见视窗。其实就是指向一个有 Mask 组件的游戏对象。

HorizontalScrollbar、VerticalScrollbar: 分别对应横向的滑动控制条以及纵向的滑动控制条.

OnValueChanged(Vector2 ): 一个滚动回调。可以传递一个Vector2变量。 应该是每一帧滑动的变化量。(具体不清楚)

空一行,看的没那么累

最后在 Grid 添加 Content-Size-Fitter、Grid-Layout-Group 组件

Content-Size-Fitter:
使用 Content Size Fitter 组件,Rect-Transform 组件会发生响应的变化!!!
Horizontal-Fit 不为 Unconstrained 时,Width 不可修改,同理,Vertical-Fit 不为 Unconstrained 时,Height 不可修改!!!

Content-Size-Fitter 组件主要是用来设置UI的长宽

Content-Size-Fitter 参数:
Horizontal-Fit、Vertical-Fit: 分别是控制UI的宽和高,

Unconstrained: 组件不根据布局元素调整 ,可手动修改长宽的值

MinSize: 根据布局元素的最小值来调整,不能手动修改长宽的值

PreferredSize: 根据布局元素的内容来调整,不能手动修改长宽的值,也就是会自动根据内容来调整大小

在这里插入图片描述
(因为我们的列表是垂直的,所以将 Vertical-Fit 设置为 Preferred-Size ,这样的话,就算我们生成 100 个服务器(预制体),他也会自行调整长度)

Grid-Layout-Group

Grid-Layout-Group 的参数:
padding: 矩形偏移
在这里插入图片描述
Left、Right、Top、Bottom 分别对应 左边缘、右边缘、顶边缘、底边缘,具体效果自己测试,不过看名称都能理解的
在这里插入图片描述
Cell-Size: Vector2类型,默认值为(100,100),网格中的每个单元格的大小
像生成的服务器(预制体),他们的大小是(587,90),所以这里也就设置为 X(587)、Y(90),保证生成出来的服务器保持正常大小

Spacing: 这里的Spacing不同于水平布局、垂直布局,是Vector2类型,既然是网格布局,当然存在水平方向的间隔和垂直方向的间隔
例如我希望服务器与服务器的上下左右之间,保持一定距离,所以这里设置 X(10)、Y(10)

Start-Corner: 第一个单元格放在哪个角落,默认为 Upper-Left 左上角
《Upper-Left》、《Upper-Right》、《Lower-Left》、《Lower-Right》分别对应 左上角、右上角、左下角、右下角!!
这里我把第一单元格生成的位置设置成 Upper-Left!

Start-Axis: 设置你的优先排列单元格的方向,Horizontal(水平)、Vertical(垂直)
因为要 服务器(预制体)要 一排两个 这样生成,所以优先 Horizontal !!

Child-Alignment: 文本锚点
《UpperLeft 》《UpperCenter 》《UpperRight 》《MiddleLeft 》《MiddleCenter》《MiddleRight 》《LowerLeft 》《LowerCenter 》分别对应 上左、上中、上右、中左、中中、中右、下左、下中、下右
这里对于描点位置没有特殊要求,而有关描点的知识,另找

Constraint: 设置网格的行数、列数

Flexible: 不限制行数和列数

FixedColumnCount: 约束指定数量的列数

FixedRowCount: 约束指定数量的行数

空一行,看的没那么累
在这里插入图片描述

最后是当我点击绿圈的哪个服务器,红圈就显示哪个服务器!
方法:给服务器(预制体)添加一个脚本,用于点击事件,当我们点击哪个服务器,就将服务器的 Image.sprite、text.text 换成红圈 服务器的 Image.sprite、text.text
代码部分:

 public void OnPress()
    {
        if (audioClip != audioClip.isPlaying) audioClip.Play();

        //选择了 当前的服务器
        StartmenuController._instance.gameObject.SendMessage("OnServerSelect", this.gameObject, SendMessageOptions.RequireReceiver);
        
    }

服务器的 Image.sprite、text.text 的更换给《StartMenuController》脚本来处理,而服务器的脚本仅仅只是用于点击事件!

public void OnServerSelect(GameObject serverGo)
    {
        sp = serverGo.GetComponent<ServerProperty>();

        serverSelectedGO.GetComponent<Image>().sprite = serverGo.GetComponent<Image>().sprite;
        serverSelectedGO.transform.Find("Text").GetComponent<Text>().text = sp.serverName;
    }

空一行,看的没那么累

2. 选择人物面板
为了让3D物体在UI界面中可以进行互动,首先在 Hierarchy 面板中创建 RawImage 和 另一个 Camera,然后再到 Project 面板中创建 RebderTextTure。
RawImage:
RawImage 是将 Camera 记录的渲染纹理,赋值给 RawImage ,用于显示3D图像。
一般 RawImage 的大小跟 UI面板一致,除非有特殊要求 大小自己设置。

Camera:
将摄影机的 Audio-Listener 移除,不然 Console 会报警说场景中存在2个耳朵。

RenderTexture
这里不讨论它的深层含义,只解释它的参数
在这里插入图片描述
Dimension: 要渲染纹理的维度(类型)
2D、3D: 没啥好说的
Cube: 最常用于动态 cubemap 反射,见 Camera.RenderToCubemap 。一个 cubemap 渲染纹理必须有相同的宽度和高度,并且必须是两个大小。

Size: 默认是(256,256),通过增大数值可以让显示出现影像更加清晰,但同时性能也消耗越大。

Anti-Aliasing: 渲染纹理的抗锯齿级别。

Color-Forrmat: 渲染纹理的颜色格式。
参数过多,能力有限没法进行一一叙述,
ARGB32: 用于处理静态图片可以,动态渲染太慢
ARGB64: 适合用于动态渲染
Depth-Buffer、SRGB(Color-Render)、Enable-Mip-Maps、Autio-Generate-Mip-M、Dynamic-Scaling、Wrap-Mode、Filter-Mode: 本次项目未用到,就不进行深究。

空一行,看的没那么累

接下来是赋值:
RawImage 覆盖整个UI界面后,给 RawImage 新建一个Layer层级 《UGUI》

RenderTexture 赋值到 RawImageTexture

然后将 RenderTexture 也赋值到 CameraTargetTexture

CameraClear-Flags 设置 Depth-only (其实只要不是 Sky-Box 就行)

还有 Culling-Mask 设置 RawImageLayer《UGUI》

其他都不选,这样就只渲染 RawImage 的影像。

最后就是调3D物体的位置到我们想要的位置(个人觉得将 CameraProjection 设置成 Orthographic 比较好,具体如何自行测试!)

实现的效果:在这里插入图片描述
当我们鼠标点击人物后,该人物就被放大,点击另一个人物也放大,但同时之前的人物就变回原来的大小。
这里我用了笨方法(目前能想到):新建两个 Bottun 覆盖两个模型的影像(当然 Bottun 的透明值调到零),然后,当我点击模型也就是 Botton 就放大被覆盖的模型
这里的模型放大 用了 DoTweenDoScale 进行放大。

代码部分:

  /// <summary>
    /// 来回切换角色的大小
    /// </summary>
    /// <param name="go">点击的角色</param>
    /// <param name="characterScale">角色原来的大小</param>
    public void OnCharacterClick(GameObject go, Vector3 characterScale)
    {
        if (audioClip != audioClip.isPlaying) audioClip.Play(); //点击后,播放音效

        if (go == characterSelected) return; //当我点击同一个角色的时候,就不进行任何反馈

        go.transform.DOScale(go.transform.localScale + new Vector3(0.5f, 0.5f, 0.5f), 0.5f);
		
		//本代码的实现目的是:当我点击另一个角色,那原来的角色就变回原来的大小。
		//因为要选择的角色一开始为空, 所以当 characterSelected 为 null , null 又没法进行缩小就会报错
		//当我点击另一个角色,进行放大,然后characterSelected 也就是之前点击的角色),就进行缩小
        if (characterSelected != null)
        {
            characterSelected.transform.DOScale(characterScale, 0.5f); 
        }

        characterSelected = go;
    }

	其中 characterSelected 就是点击后,要选择的角色

实现的效果:
在这里插入图片描述

当我们选择好角色并命名后,点击确定,在 《确定人物选择面板》 就显示选择好的角色(名称和登录显示过于简单,不进行叙述)

我的方法是:声明一个数组变量,把两个人物放进去,然后用 for 循环进行遍历,当我选择的角色 和 遍历的角色 一致时,就得到该索引,然后在 《确定人物选择面板》 中设置到的位置,生成出来。并且设该位置的空物体 (characterPos) 为父级,同时人物的 Transform 的位置、旋转都设为原点,大小必须保持跟之前设置好的一样。(先在 Awake 中获得角色的 locaScale ,然后在 《确定人物选择面板》 中生成时,就将模型的大小赋值给生成的预制体),点击返回按钮也一样。 要先将原来的大小赋值给生成的预制体

代码部分:

  /// <summary>
    /// 选择角色面板中的确定按钮
    /// </summary>
    public void OnButtonSure()
    {
        if (audioClip != audioClip.isPlaying) audioClip.Play(); //点击后,播放音效

        //1、判断名称是否输入正确

        //2、判断是否选择了角色

        int index = -1;
        for (int i = 0; i < characterArray.Length; i++)
        {
            if (characterSelected == characterArray[i])
            {
                index = i;
                break;
            }
        }
        if (index == -1) return;

        GameObject go = Instantiate(characterArray[index], Vector3.zero, Quaternion.identity);
        go.transform.SetParent(characterSelectedBoyPos);
        characterSelectedBoyPos.localScale = characterScale;
        go.transform.localPosition = Vector3.zero;
        go.transform.localRotation = Quaternion.identity;
        go.transform.localScale = Vector3.one;

可这里有一个问题:当我生成好后,在点击 更换角色 时,生成的角色就出现在 《选择人物面板》 中,所以当我点击 更换角色 时,应该将生成的模型进行销毁,但一开始 《确定人物选择面板》 是没有模型可以进行销毁的,所以要判断下 (characterPos) 有没有子物体。

代码部分:

  /// <summary>
    /// 点击更换角色按钮的方法
    /// </summary>
    public void OnButtonCharavterClick()
    {
        if (audioClip != audioClip.isPlaying) audioClip.Play(); //点击后,播放音效

        //当我点击确定按钮,再更换面板中角色将会被销毁
        if (characterSelectedBoyPos.GetComponentsInChildren<Transform>(true).Length > 1)
        {
            characterSelectedBoyPos.localScale = Vector3.one;
        }

        //当我点击确定按钮,再更换面板中角色将会被销毁
        if (characterSelectedBoyPos.GetComponentsInChildren<Transform>(true).Length > 1)
        {
            Destroy(characterSelectedBoyPos.GetComponentInChildren<Animation>().gameObject);
        }

以上就是泰斗破坏神的UI界面视频教程的知识点,接下来就是主界面的开发视频教程!
为自己打气加油!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值