Unity基础学习(二)

在这里插入图片描述

二、Mono中的重要内容

在这里插入图片描述

1、延迟函数

(1)延迟函数定义

延迟执行的函数,可以设定要延迟执行的函数和具体延迟的时间

(2)延迟函数的使用

		#region 1、延迟函数//函数:Invoke(函数名/字符串,延迟时间/秒)//注意点//1.1 延迟函数第一个参数传入的是函数名字符串//1.2 延迟函数没有办法传入参数 #endregion#region 2、延迟重复执行函数//函数:InvokeRepeating(函数名,第一次执行的延迟时间,之后每次执行的间隔时间)#endregion#region 3、取消延迟函数//3.1 取消该脚本上的所有延迟函数//CancelInvoke()//3.2 指定函数名取消//CancelInvoke(函数名)#endregion#region 4、判断是否有延迟函数//IsInvoking()#endregion

(3)延迟函数受对象失活销毁影响

脚本依附对象失活 延迟函数可以继续执行
脚本依附对象销毁或脚本删除 延迟对象无法继续执行

2、协同程序

(1)Unity是否支持多线程

Unity中支持多线程,不过新开的线程无法访问Unity场景中对象的内容
Unity中的多线程,即使没有点击运行,它也会一直执行,所以要记得关闭
多线程一般用于一些复杂计算,将输出的结果存在公共变量中,供Unity主程序使用

(2)协同程序

(a)定义

协同程序是假的多线程,不是多线程

(b)作用

将代码分时分步执行,不卡主线程
可以设置什么时候执行哪个步骤,多久时间执行下一步

(c)主要使用场景

异步加载文件
异步下载文件
场景异步加载
批量创建时防止卡顿

(3)协程的使用

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Lesson9 : MonoBehaviour
{// Start is called before the first frame updatevoid Start(){//第二步   开启协程函数Coroutine c1=StartCoroutine(MyFunc(1,"123"));Coroutine c2= StartCoroutine(MyFunc(1, "123"));//第三步   关闭协程//关闭所有StopAllCoroutines();//关闭指定协程StopCoroutine(c1);}IEnumerator MyFunc(int i,string str){//第一步   声明协程函数//1.1   返回值为IEnumerator类型及其子类//1.2   函数通过yield return 返回值 进行返回//执行第一部分print(i);yield return new WaitForSeconds(5f);//执行第二部分print(str);yield return new WaitForSeconds(5f);//执行第三部分print("123456");//协程内允许写死循环while (true){print("死循环,等3秒打印");yield return new WaitForSeconds(3f);}}
}

(4)yield return 不同内容的含义

在这里插入图片描述

(5)协程受对象和组件失活销毁的影响

协程开启后
组件和物体销毁 协程不执行
物体失活协程不执行,组件(脚本)失活协程执行

3、协同程序原理

(1)协程的本质

协程的本质是一个C#的迭代器方法,主要分为 协程函数本体 和 协程调度器 两个部分

(a)协程函数本体

协程函数本体是一个能够中间暂停返回的函数

(b)协程调度器

协程调度器是Unity内部实现的,会在对应的时机帮助我们继续执行协程函数

(2)总结

协程的本质,就是利用C#迭代器函数分布执行的特点,加上协程调度逻辑实现的一套分时执行函数的规则

三、Resources资源动态加载

在这里插入图片描述

1、Resources同步加载

(1)Resources资源动态加载的作用

通过代码动态加载Resources文件夹下指定路径资源
避免繁琐的拖曳操作
一个工程中可以有多个Resources文件夹,通过API加载时,会自动去寻找同名文件

(2)常用资源类型

预设体对象——GameObject 注意:预设体对象加载需要实例化,其他资源可以直接用
音效文件——AudioClip
文本文件——TextAsset 注意:支持的文本资源格式 txt xml bytes json html csv
图片文件——Texture
其他类型——需要什么类型用什么类型

(3)资源同步加载 普通方法

Object obj= Resources.Load("资源所在Resources文件夹下的路径");//加载指定类型的资源
Resources.Load("资源名",typeof(资源类型));
//加载指定名字的所有资源
Object[] objs= Resources.LoadAll("资源名");

(4)资源同步加载 泛型方法

Resources.Load<资源类型>("资源名");

2、Resources异步加载

(1)异步加载介绍

当加载过大的资源会造成程序卡顿,Resources异步加载就是内部新开一个线程进行资源加载,不会造成主线程卡顿

(2)异步加载方法

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Lesson11 : MonoBehaviour
{// Start is called before the first frame updatevoid Start(){print("开始加载,当前帧为"+Time.frameCount);//异步加载不能马上得到加载的资源   至少需要等一帧//1.通过异步加载中的完成时间监听  使用加载的资源//这句代码表示 Unity开了一个线程进行资源加载ResourceRequest rq = Resources.LoadAsync<GameObject>("Cube");//为 资源下载结束时   添加的一个监听事件rq.completed += LoadOver;//2.通过协程使用加载的资源StartCoroutine(Load());}private void LoadOver(AsyncOperation rq){print("结束加载,当前帧为" + Time.frameCount);//加载结束  才能对资源进行使用Instantiate((rq  as ResourceRequest).asset);}IEnumerator Load(){ResourceRequest rq = Resources.LoadAsync<GameObject>("Sphere");//打印加载进度while (!rq.isDone){print("当前加载进度:" + rq.progress);yield return null;}//第一部分yield return rq;//Unity会自己判断 资源是否加载完毕 加载完毕后才会继续执行后面的代码//实例化预制体Instantiate(rq.asset);//yield return null;第二部分//yield return new WaitForSeconds(3);第三部分}
}

(3)总结

1.完成事件监听异步加载 ”线性加载“
优点:写法简单
缺点:只能在资源加载结束后进行处理
2.协程异步加载 ”并行加载“
好处:可以在协程中处理复杂逻辑,比如同时加载多个资源,加载进度条更新等
坏处:写法较为复杂

3、Resources卸载资源

(1)Resources重复加载资源会浪费内存吗

Resources加载一次资源后,该资源一直放在内存中作为缓存,二次加载时发现内存中存在该资源就会直接取出使用
所有多次加载资源不会浪费内存,但是会浪费性能

(2)如何手动释放掉缓存中的资源

		 //卸载资源//1.卸载指定资源Resources.UnloadAsset(资源名称);//注意:该方法 不能释放 GameObject对象 因为它会用于实例化对象//它只能用于一些 不需要实例化的内容 比如 图片 音效 文本等//一般情况很少单独使用//2.卸载未使用的资源Resources.UnloadUnusedAssets();//该方法一般在过场景和GC一起使用

四、场景异步切换

1、场景同步切换

SceneManager.LoadScene(“场景名称”);
缺点:
使用同步切换回删除当前场景上所有对象,并去加载下一个场景的相关信息。如果当前场景或者下一个场景内容过多,就会导致同步切换过程耗时很久

2、场景异步切换

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;public class Lesson12 : MonoBehaviour
{// Start is called before the first frame updatevoid Start(){//同步场景切换SceneManager.LoadScene("Lesson12Test");//异步场景切换//1.通过事件回调函数 异步加载//AsyncOperation ao= SceneManager.LoadSceneAsync("Lesson12Test");//ao.completed += LoadSceneOver;//2.通过协程异步加载//注意:加载场景会把当前场景上没有特别处理的对象都删除了,所以协程中的部分逻辑可能是执行不了的//解决思路:让处理场景加载的脚本依附的对象,过场景时不被移除DontDestroyOnLoad(this.gameObject);StartCoroutine(LoadScene("Lesson12Test"));   }private void LoadSceneOver(AsyncOperation ao){print("场景加载结束");}IEnumerator LoadScene(string name){//异步加载AsyncOperation ao = SceneManager.LoadSceneAsync(name);//等待场景加载完成//可以在加载过程中,做别的事情print("异步加载过程中,打印的信息");yield return ao;//场景加载完 再执行下面的逻辑print("异步加载结束后,打印的信息");}
}

五、辅助功能Linerender

1、Linerender介绍

Linerender是Unity提供的一个用于画线的组件
用途:
绘制攻击范围
武器红外线
辅助功能
其他画线功能

2、Linerender参数相关

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3、Linerender代码相关

		//动态添加一个线段GameObject line = new GameObject();line.name = "Line";LineRenderer lineRenderer= line.AddComponent<LineRenderer>();//首尾相连lineRenderer.loop = true;//开始结束宽lineRenderer.startWidth = 0.02f;lineRenderer.endWidth = 1f;//开始结束颜色lineRenderer.startColor = Color.white;lineRenderer.endColor = Color.black;//设置材质lineRenderer.material = material;//设置点//要先设置点的个数lineRenderer.positionCount = 4;//设置对应每个点的位置lineRenderer.SetPositions(new Vector3[] {new Vector3(0,0,0),new Vector3(0,0,5),new Vector3(5,0,5),new Vector3(0,5,5)});//指定设置某个点lineRenderer.SetPosition(3, new Vector3(1, 5, 6));//设置是否使用世界坐标系//决定了 是否随对象移动而移动 false——会跟随对象移动,true——不会跟随对象移动lineRenderer.useWorldSpace = false;//让线段受光影响 会接受光数据 进行着色器计算lineRenderer.generateLightingData = true;

六、核心系统

1、物理系统之范围检测

(1)物理系统之碰撞检测

碰撞产生必要条件:至少一个物体有刚体,两个物体都必须有碰撞器
碰撞和触发:碰撞会产生实际的物理效果,触发看起来不产生碰撞但是可以通过函数监听触发
碰撞检测主要用于实体物体之间产生物理效果时使用

(2)范围检测介绍

在指定位置 进行 范围判断 我们可以得到处于指定范围内的 对象
目标是对 范围内的对象进行处理 比如,受伤,掉血等
例如植物大战僵尸的食人花

(3)如何进行范围检测

//范围检测//必备条件:想要被范围检测到的对象,必须具备碰撞器//注意点://1.范围检测相关API 只有当执行该句代码时 进行一次范围检测 它是瞬时的//2.范围检测相关API 并不会真正产生一个碰撞器 只是碰撞判断计算而已//1.盒装范围检测//返回在该范围内的触发器  = Physics.OverlapBox(立方体中心点,立方体三边大小,立方体角度,//                          检测指定层级(不填检测所有层),是否忽略触发器(UseGlobal-使用全局设置,可以在Project Setting-PyPhysics中进行设置,//                          Collide-检测触发器 Ignore-忽略触发器 不填使用UseGlobal))Collider[] colliders  =Physics.OverlapBox(Vector3.zero, Vector3.one, Quaternion.AngleAxis(45, Vector3.up), 1 << LayerMask.NameToLayer("UI"));//重点知识//关于层级//通过名字得到层级编号    LayerMask.NameToLayer//我们需要通过编号左移构建二进制数//这样每一个编号的层级 都是 对应位为1的2进制数//我们通过位运算可以选择想要的检测层级//好处 一个int 就可以表示所有想要检测的层级信息//另一个API//返回值:碰撞到的碰撞器数量//参数:传入一个数组进行存储Physics.OverlapBoxNonAlloc(Vector3.zero, Vector3.one, colliders);//2.球形范围检测// Physics.OverlapSphere(中心点,球形半径,层级)Collider[] colliders1=Physics.OverlapSphere(Vector3.zero, 5f, 1 << LayerMask.NameToLayer("UI"));//另一个APIPhysics.OverlapSphereNonAlloc(Vector3.zero, 5f, colliders1);//3.胶囊范围检测//Physics.OverlapCapsule(上半圆中心点位置,下半圆中心点位置,圆的半径,层级)Collider[] colliders2 = Physics.OverlapCapsule(Vector3.zero, Vector3.up, 1, 1 << LayerMask.NameToLayer("UI"));//另一个APIPhysics.OverlapCapsuleNonAlloc(Vector3.zero, Vector3.up, 1, colliders2);

2、物理系统之射线检测

(1)射线检测介绍

射线检测可以在指定点发射一个指定方向的射线,判断该射线与哪一些碰撞器相交,得到对应对象

(2)射线对象

		//1.声明一个射线对象//Ray(起点,方向)Ray ray = new Ray(Vector3.right, Vector3.forward);print(ray.origin);//起点print(ray.direction);//方向//2.摄像机发射出的射线//模拟鼠标点击发出射线Ray ray1 = Camera.main.ScreenPointToRay(Input.mousePosition); 

(3)碰撞器检测函数

//碰撞检测函数//射线检测也是瞬时的,执行代码时进行一次射线检测//1.最原始的射线检测Ray ray = new Ray(Vector3.zero, Vector3.forward);//返回一个布尔值 = Physics.Raycast(射线对象,最远距离/米,层级,是否忽略发射器)bool isColl =Physics.Raycast(ray, 1000, 1 << LayerMask.NameToLayer("UI"));//2.获取相交物体的信息//物体信息类 RaycastHitRaycastHit hitInfo;//Physics.Raycast(射线对象,物体信息类,最远距离,层级)if (Physics.Raycast(ray,out hitInfo,1000, 1 << LayerMask.NameToLayer("UI"))){print(hitInfo.collider);//碰撞器信息print(hitInfo.point);//碰撞到的点print(hitInfo.normal);//法线信息print(hitInfo.transform.position);//碰到对象的位置信息print(hitInfo.distance);//碰撞对象与发射对象的距离}//3.获取相交的多个对象RaycastHit[] raycastHits = Physics.RaycastAll(ray, 1000, 1 << LayerMask.NameToLayer("UI"));int count = Physics.RaycastNonAlloc(ray, raycastHits, 1000, 1 << LayerMask.NameToLayer("UI"));

(4)使用时注意的问题

距离和层级 都是int类型
当我们传入参数时,一定要明确传入的参数代表的是距离还是层数

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/70679.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

20250212:ZLKMedia 推流

1:资料 快速开始 ZLMediaKit/ZLMediaKit Wiki GitHub GitHub - ZLMediaKit/ZLMediaKit: WebRTC/RTSP/RTMP/HTTP/HLS/HTTP-FLV/WebSocket-FLV/HTTP-TS/HTTP-fMP4/WebSocket-TS/WebSocket-fMP4/GB28181/SRT server and client framework based on C++11 文档里面提供了各个系…

Holoens2开发报错记录02_通过主机获取彩色和深度数据流常见错误

01.E1696 E1696 无法打开源文件 “stdio.h” 解决方法&#xff1a; 更新一下SDK 1&#xff09;打开Visual Studio Installer&#xff0c;点击修改 2&#xff09;安装详细信息中自己系统对应的SDK&#xff0c;点击修改即可 02.WinError 10060 方法来源 解决方法&#xff1a…

【Qt之QQuickWidget】QML嵌入QWidget中

由于我项目开始使用Widgets,换公司后直接使用QML开发&#xff0c;没有了解过如何实现widget到qml过渡&#xff0c;恰逢面试时遇到一家公司希望从widget迁移到qml开发&#xff0c;询问相关实现&#xff0c;一时语塞&#xff0c;很尴尬&#xff0c;粗略研究并总结下。 对qwidget嵌…

从单片机的启动说起一个单片机到点灯发生了什么下——使用GPIO点一个灯

目录 前言 HAL库对GPIO的抽象 核心分析&#xff1a;HAL_GPIO_Init 前言 我们终于到达了熟悉的地方&#xff0c;对GPIO的初始化。经过漫长的铺垫&#xff0c;我们终于历经千辛万苦&#xff0c;来到了这里。关于GPIO的八种模式等更加详细的细节&#xff0c;由于只是点个灯&am…

ESP32S3:解决RWDT无法触发中断问题,二次开发者怎么才能使用内部RTC看门狗中断RWDT呢?

目录 基于ESP32S3:解决RWDT无法触发中断问题引言解决方案1. 查看报错日志2. 分析报错及一步一步找到解决方法3.小结我的源码基于ESP32S3:解决RWDT无法触发中断问题 引言 在嵌入式系统中,RWDT(看门狗定时器)是确保系统稳定性的重要组件。然而,在某些情况下,RWDT可能无法…

对计算机中缓存的理解和使用Redis作为缓存

使用Redis作为缓存缓存例子缓存的引入 Redis缓存的实现 使用Redis作为缓存 缓存 ​什么是缓存&#xff0c;第一次接触这个东西是在考研学习408的时候&#xff0c;计算机组成原理里面学习到Cache缓存&#xff0c;用于降低由于内存和CPU的速度的差异带来的延迟。它是在CPU和内存…

vue3的实用工具库@vueuse/core

1.什么是vueuse/core 是一个基于 ‌Vue Composition API‌ 开发的实用工具库&#xff0c;旨在通过封装高频功能为可复用的组合式函数&#xff08;Composables&#xff09;&#xff0c;简化 Vue 应用的开发流程。 提供 ‌200 开箱即用的函数‌&#xff0c;覆盖状态管理、浏览器…

基于SSM的《计算机网络》题库管理系统(源码+lw+部署文档+讲解),源码可白嫖!

摘 要 《计算机网络》题库管理系统是一种新颖的考试管理模式&#xff0c;因为系统是用Java技术进行开发。系统分为三个用户进行登录并操作&#xff0c;分别是管理员、教师和学生。教师在系统后台新增试题和试卷&#xff0c;学生进行在线考试&#xff0c;还能对考生记录、错题…

C++初阶——简单实现stack和queue

目录 1、Deque(了解) 1.1 起源 1.2 结构 1.3 优缺点 1.4 应用 2、Stack 3、Queue 4、Priority_Queue 注意&#xff1a;stack&#xff0c;queue&#xff0c;priority_queue是容器适配器(container adaptor) &#xff0c;封装一个容器&#xff0c;按照某种规则使用&#…

第2课 树莓派镜像的烧录

树莓派的系统通常是安装在SD卡上的‌。SD卡作为启动设备,负责启动树莓派并加载操作系统。这种设计使得树莓派具有便携性和灵活性,用户可以通过更换SD卡来更换操作系统或恢复出厂设置。 烧录树莓派的镜像即是将树莓派镜像烧录到SD卡上,在此期间会格式化SD卡,如果SD卡…

【Unity】URP管线Shader编程实例详解 (1) : 漩涡效果shader

作者说 本系列教程适用于有编程基础和图形学基础知识的读者.如果对您有所帮助&#xff0c;请点个免费的赞和关注&#xff0c;您的支持就是我更新最大的动力&#xff01;如果你有任何想看的内容欢迎评论区留言&#xff01;本系列教程Github : https://github.com/Sky0Master/Un…

如何安装vm 和centos

安装 VMware Workstation&#xff08;以 Windows 系统为例&#xff09; 1. 下载 VMware Workstation 打开 VMware 官方网站&#xff08;Desktop Hypervisor Solutions | VMware &#xff09;&#xff0c;在页面中选择适合你系统的版本进行下载。如果你是个人非商业使用&#x…

STM32-心知天气项目

一、项目需求 使用 ESP8266 通过 HTTP 获取天气数据&#xff08;心知天气&#xff09;&#xff0c;并显示在 OLED 屏幕上。 按键 1 &#xff1a;循环切换今天 / 明天 / 后天天气数据&#xff1b; 按键 2 &#xff1a;更新天气。 二、项目框图 三、cjson作用 https://gi…

Wireshark简单教程

1.打开Wireshark,点击最上面栏目里面的“捕获”中的“选项” 2.进入网卡选择界面,选择需要捕获的选择&#xff0c;这里我选择WLAN 3.双击捕获选择出现下面界面 4.点击如下图红方框即可停止捕获 5.点击下图放大镜可以进行放大 6.你也可以查询tcp报文如下图

【Http和Https区别】

概念&#xff1a; 一、Http协议 HTTP&#xff08;超文本传输协议&#xff09;是一种用于传输超媒体文档&#xff08;如HTML&#xff09;的应用层协议&#xff0c;主要用于Web浏览器和服务器之间的通信。http也是客户端和服务器之间请求与响应的标准协议&#xff0c;客户端通常…

Unity Shader 学习13:屏幕后处理 - 使用高斯模糊的Bloom辉光效果

目录 一、基本的后处理流程 - 以将画面转化为灰度图为例 1. C#调用shader 2. Shader实现效果 二、Bloom辉光效果 1. 主要变量 2. Shader效果 &#xff08;1&#xff09;提取较亮区域 - pass1 &#xff08;2&#xff09;高斯模糊 - pass2&3 &#xff08;3&#xff…

【R语言】dplyr包经典函数summarise函数

dplyr包经典函数summarise函数&#xff0c;后面改名乘reframe函数了&#xff0c;但是summarise仍然适用 这个函数的返回结果是一个新的数据框&#xff0c;下面讲一下几种常见用法 示例数据为R自带的数据集mtcars 1.不分组 mtcars %>%summarise(mean mean(disp), n n()…

使用DeepSeek/ChatGPT等AI工具辅助编写wireshark过滤器

随着deepseek,chatgpt等大模型的能力越来越强大&#xff0c;本文将介绍借助deepseek&#xff0c;chatgpt等大模型工具&#xff0c;通过编写提示词&#xff0c;辅助生成全面的Wireshark显示过滤器的能力。 每一种协议的字段众多&#xff0c;流量分析的需求多种多样&#xff0c;…

vscode设置自动换行

vscode设置自动换行 方法 方法 点击文件->首选项->设置。搜索word wrap -> 选择 on 。 搜索Word Wrap&#xff0c;并把选项改为on。

QT 中的元对象系统(一):元对象和元数据

目录 1.为什么需要元系统 2.元数据 3.模拟元对象系统 3.1.元对象声明 3.2.对C扩展 3.3初始化元对象 3.4.使用元对象 4.QT的元系统 4.1.元对象系统基于QObject类、Q_OBJECT宏、元对象编译器MOC实现 4.2.元对象系统的功能 4.3.Q_PROPERTY()的使用 4.4.Q_INVOKABLE使用…