自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

zheliku的博客

记录学习的点点滴滴~

  • 博客(252)
  • 收藏
  • 关注

原创 2024-04-08 NO.6 Quest3 自定义交互事件

​ 在开始操作前,我们导入上次操作的场景,相关介绍在文章中。

2024-04-08 16:30:41 1208

原创 2024-04-08 NO.5 Quest3 手势追踪进行 UI 交互

​ 在开始操作前,我们导入先前配置好的预制体 MyOVRCameraRig,相关介绍在文章中。

2024-04-08 14:44:41 849

原创 2024-04-03 NO.4 Quest3 手势追踪抓取物体

(1)取消 Cube 的 Box Collider 的 Trigger 选项,并勾选 Rigidbody 的 Use Gravity。并对 RightHand 进行同样的操作。​ 在运行程序时,如果当前 HandGrabInteractable 物体上没有挂载 “Move Towards Target Provider” 脚本,“Hand Grab lnteractable” 脚本会自动添加 “Move Towards Target Provider” 脚本,用于控制物体被抓取时朝向手部的移动。

2024-04-03 21:07:53 1021

原创 2024-04-01 NO.3 Quest3 手势追踪与玩家角色配置

到此,配置大致完成。​ 以安全区地面(打开 VR 设备一般会先设置地面高度,然后划安全区)作为参考系,运行程序后头部高度以地面作为参考点,高度相当于摆放在场景中的玩家物体的高度加上现实中玩家头显到安全区地面的距离。​ 以头显设备本身作为参考系,头部高度相当于摆放在场景中的玩家物体的高度加上头显相对于设备自身坐标系的高度(每次设备定位成功后会建立设备自身的坐标系),不会额外加上现实中头显到地面的高度。此时运行项目,只有追踪功能,没有手部模型,也没有交互功能。只有确立坐标系的原点后,才能给出三维坐标的值。

2024-04-01 15:28:21 662

原创 2024-03-29 NO.2 Quest3 开发包基本原理和框架

​ 当 Oculus Integration 获取设备的追踪数据后,就知道虚拟世界中的手或者手柄的位置和旋转角度,此时手部或者手柄物体上的 Interactor 就会寻找对应的 Interactable。​ 现实世界中,头显和手柄的追踪数据会被传输给虚拟世界中的头部和手部,之后虚拟世界中的头和手就会同步现实中的位置和旋转。记录身体的姿态数据,在 v57 版本中可以模拟上半身的一个运动姿态,SDK 中有提供相关的示例场景。​ 对追踪数据进行处理和包装后,才能适配 SDK 中的一些组件。记录头显的相关数据。

2024-03-29 14:11:20 560

原创 2024-03-28 NO.1 Quest3 开发环境配置教程

(2)进入“Window --> Package Manager”,点击左上角的“+”按钮,选择“Add package from tarball…(8)返回 Project 窗口中的 Asset 文件夹下,进入“Asset --> Oculus --> Oculus Project Config”,勾选“Quest3”,并设置下列参数。(3)所有开发包导入完成后,进入“Editor --> Project Settings”,选择“Meta XR”,修复 PC 端的所有选项,并应用所有建议。

2024-03-28 20:57:25 1269

原创 《深入解析 C#》—— C# 3 部分

委托的作用是提供可运行的代码,而表达式树的作用是提供可查看的代码(这有点类似于反射机制)。代码中方法调用的顺序和实际执行的顺序刚好相反:Where 方法是第一个被调用的,却放在了末尾。​ 在这段代码中,每次声明 text 时,该变量就完成一次实例化,因此每个 lambda 表达式捕获的都是不同的变量实例,于是 5 个完全独立的 text 变量被分别捕获。例如对于没有捕获变量的 lambda 表达式,编译器可能会创建一个包含一个实例方法的嵌套类,而不是创建一个静态方法。编译器负责生成适用于执行期的表达式树。

2024-03-21 11:18:46 588

原创 《深入解析 C#》—— C# 2 部分

​ 例如在处理很多带 DateTime 参数的方法,向当前命名空间引入另外一个名为 DateTime 类型的时候,这些函数声明就无法正常工作了。​ C#3 引入了局部类的一个扩展特性:局部方法默认是私有方法,返回值必须是 void 且不能使用 out 参数(可以使用 ref 参数)。编写局部方法,可以在一个类型的局部声明中声明一个不包含方法体的方法,而在一个局部声明中定义该方法的实现(可选)。​ 假设有不同的程序集,它们提供了相同的命名空间,而命名空间中左有相同的类型名,这要怎么处理呢?

2024-03-14 21:28:49 780

原创 LeetCode 389. 找不同

输入:s = “abcd”, t = “abcde”随机重排,然后在随机位置添加一个字母。输入:s = “”, t = “y”最后留下来的结果即为添加的字符。解释:‘e’ 是那个被添加的字母。,它们只包含小写字母。

2024-03-14 20:22:51 258 1

原创 LeetCode 1768. 交替合并字符串

开始,通过交替添加字母来合并字符串。如果一个字符串比另一个字符串长,就将多出来的字母追加到合并后字符串的末尾。注意,word2 比 word1 长,“rs” 需要追加到合并后字符串的末尾。注意,word1 比 word2 长,“cd” 需要追加到合并后字符串的末尾。比较简单的题目,思路很清晰,直接放上代码了。合并后: a p b q r s。合并后: a p b q c d。合并后: a p b q c r。返回 合并后的字符串。

2024-03-11 20:19:21 398 1

原创 2024-02-25 Unity 编辑器开发之编辑器拓展7 —— Inspector 窗口拓展

单独为某一个脚本实现一个自定义脚本,并且脚本需要继承 Editor。一般该脚本命名为:自定义脚本名 + Editor。在该脚本前加上特性。命名空间:UnityEditor特性名:CustomEditor(想要自定义脚本类名的 Type)// 通过该特性,可以为 Lesson22 脚本自定义 Inspector 窗口中的显示typeofLesson22...声明对应 SerializedProperty 序列化属性对象,主要通过它和自定义脚本中的成员进行关联。

2024-02-25 18:02:30 1008

原创 2024-02-25 Unity 编辑器开发之编辑器拓展6 —— Event

​ Event 提供许多属性和方法,允许检查和处理用户输入,主要用于 Unity 编辑器拓展开发。​ Input 相关内容需要在运行时才能监听输入,而 Event 专门提供给编辑模式下使用,可以帮助检测鼠标键盘输入等事件相关操作,在 OnGUI 和 OnSceneView 中都能使用。

2024-02-25 14:29:07 755

原创 2024-02-25 Unity 编辑器开发之编辑器拓展5 —— Selection

​ Selection 主要用来获取当前 Unity 编辑器中选择的对象,只能用于编辑器开发中。

2024-02-25 14:13:19 316

原创 2024-02-13 Unity 编辑器开发之编辑器拓展4 —— EditorGUIUtility

​ Utility 意思为“实用”,EditorGUIUtility 是 EditorGUI 中的一个实用工具类,提供 EditorGUI 相关的其他辅助 API,下面仅介绍其中相对常用的内容。​ 官方文档:https://docs.unity3d.com/ScriptReference/EditorGUIUtility.html。

2024-02-13 13:16:24 1628

原创 2024-02-12 Unity 编辑器开发之编辑器拓展3 —— EditorGUI

​ EditorGUI 类似 GUI,是用于绘制编辑器拓展 UI 的工具类,提供 GUI 中没有的 API(主要是编辑器功能中会用到的一些特殊控件)。​ EditorGUILayout 类似于 GUILayout,是带有自动布局功能的 EditorGUI 绘制工具类。通常,会将 EditorGUI 和 GUI 混合使用来制作编辑器拓展功能。但由于用到自动布局功能,因此接下来着重介绍 EditorGUILayout 中的功能。EditorGUI 和它的区别仅仅是需要自己设置位置而已。

2024-02-12 14:58:57 1987

原创 2024-02-11 Unity 编辑器开发之编辑器拓展2 —— 自定义窗口

​ 当想为 Unity 拓展一个自定义窗口时,只需实现继承 EditorWindow 的类即可,并在该类的 OnGUI 函数中编写面板控件相关的逻辑。当窗口被销毁时调用,通常在关闭编辑器或切换场景时触发。在该方法中可以执行与所选对象相关的操作,以确保编辑器窗口的内容与当前选择保持同步。可以在这个方法中执行需要在检视器面板刷新时进行的逻辑,比如更新显示的信息。通常在这里执行需要在每帧进行的逻辑。通常在该方法中执行在窗口失去焦点时需要进行的清理工作。在该方法中可以执行在窗口获得焦点时需要进行的操作。

2024-02-11 14:58:24 1741

原创 2024-02-08 Unity 编辑器开发之编辑器拓展1 —— 自定义菜单栏

命名空间:UnityEditor特性:MenuItem用法:在静态函数前加上[MenuItem("页签/一级选项/二级选项/....")]作用:当在菜单栏点击该页签时,将执行静态函数中逻辑。注意:不用在意继承对象。斜杠必须是。[MenuItem"Unity编辑器拓展/Lesson1/TestFun"命名空间:UnityEditor特性:MenuItem用法:在静态函数前加上,并且页签命名放入 GameObject 路径。

2024-02-08 23:10:34 1764

原创 2024-02-01 Unity Shader 开发入门4 —— ShaderLab 语法

​ ShaderLab 是 Unity 自定义的语法规则,是专门用于在 Untiy 中编写和管理着色器的语言。​ 它提供一种结构化的方式来描述 Unity 着色器的各个部分,从而更轻松地创建和管理着色器。​ Unity 通过 ShaderLab 语言对 Shader 进行包装和组织。

2024-02-01 03:19:01 808

原创 C# 图解教程 第5版 —— 第25章 反射和特性

​ 特性是一种允许向程序集添加元数据的语言结构,用于保存程序结构信息的特殊类型。将应用了特性的程序结构称为目标。设计用来获取和使用元数据的程序称为特性的消费者。.NET 预定义了许多特性,也可以自己声明自定义特性。图25.2 创建和使用特性的相关组件在源代码中将特性应用于程序结构。编译器获取源代码并从特性产生元数据,之后将元数据放到程序集中。消费者程序可以获取特性的元数据以及程序中其他组件的元数据。即,编译器同时生产和消费特性。

2024-01-14 15:12:55 1011

原创 C# 图解教程 第5版 —— 第24章 预处理指令

​ C# 中没有实际的预处理程序,“预处理”指令由编译器处理,但这个术语被保留了下来。

2024-01-13 14:49:48 1197 2

原创 C# 图解教程 第5版 —— 第23章 异常

​ 异常是程序中的运行时错误,它违反了系统约束或应用程序约束,或是正常操作时不会发生的状况。如果程序没有提供处理异常的代码,系统会挂起这个程序。例如,下面的代码在试图用 0 除一个数时抛出一个异常:​ 在没有异常处理程序的情况下,应用程序将停止(或者崩溃),并向用户显示非常不友好的错误消息。在有限的几种情况下采取纠正措施,让应用程序继续运行。记录有关异常的信息,以便开发团队可以解决该问题。清理任何外部资源,例如可能保持打开的数据库连接。向用户显示友好的信息。

2024-01-13 14:02:41 1163 2

原创 2024-01-12 Unity Shader 开发入门3 —— 坐标空间变换

​ 在渲染管线中,需要将坐标数据在这些空间中进行变换计算。​ 在设计模型时,使用模型空间。模型导入 Unity 后,最终显示在屏幕上,依次经历了如下空间的坐标变换:​ 模型空间->世界空间->观察空间->裁剪空间->屏幕空间。

2024-01-12 20:37:55 1204

原创 C# 图解教程 第5版 —— 第22章 命名空间和程序集

mscorlib 包含 C# 类型及大部分 .NET 语言基本类型的定义,在编译时,它必须被引用,因此不显示放在引用目录中。​ 若想扩展上述类的能力,使用名为 CircleWidget 的类,并将其定义在 UltraLib 的程序集中。​ 在许多项目中,会使用其他程序集的类或类型,而不仅仅是自己声明的。​ 由于两个库都含有名为 SquareWidget 的类,编译时会产生错误信息,因为编译器不知道使用 SquareWidget 类的哪个版本。“引用”,选择下方的“添加自”按钮,找到对应的程序集即可。

2024-01-12 19:51:44 1220 2

原创 C# 图解教程 第5版 —— 第21章 异步编程

​ 启动程序时,系统会在内存中创建一个新的进程。在进程内部,系统创建了一个称为线程的内核对象,代表真正执行的程序(线程是“执行线程”的简称)。一旦进程建立,系统会在 Main 方法的第一行语句处开始线程的执行。进程是构成运行程序的资源集合,包括虚地址空间、文件句柄和运行程序所需的其他东西。默认情况下,一个进程只包含一个线程,从程序的开始一直执行到结束。线程可以派生其他线程,因此任意时刻,一个进程都可能包含不同状态的多个线程,执行程序的不同部分。同一个进程的多个线程共享进程的资源。

2024-01-12 10:40:05 523

原创 C# 图解教程 第5版 —— 第19章 枚举器和迭代器

​ 编译器得到有关枚举项的描述后,会构建包含所有需要的方法(MoveNext)和属性(Current)实现的枚举器类,产生的类被嵌套包含在声明迭代器的类中。​ 可枚举类是指实现了 IEnumerable 接口的类,该接口只有一个成员——GetEnumerator,返回对象的枚举器。​ 对于有枚举器的类型而言,我们使用 GetEnumerator 方法来获取其拥有的枚举器,实现该方法的类型称为。​ 迭代器块描述了希望编译器为我们创建的枚举器类的行为,其中的代码描述了如何枚举元素。或不实现,来让类不可枚举。

2023-12-18 16:16:50 1147

原创 C# 图解教程 第5版 —— 第18章 泛型

​ 泛型可以将重构代码并且额外添加一个抽象层,是专门为多段代码在不同的数据类型上执行相同指令而设计的。

2023-12-11 16:32:38 357 2

原创 LeetCode 面试题 17.04. 消失的数字

的所有整数,但其中缺了一个。请编写代码找出那个缺失的整数。你有办法在O(n)时间内完成吗?求 1 ~ n 的和后,减去数组的和即可。输入:[9,6,4,2,3,5,7,0,1]注意:本题相对书上原题稍作改动。输入:[3,0,1]

2023-12-09 13:57:48 197

原创 C# 图解教程 第5版 —— 第17章 转换

转换是接受一个类型的值并将它用作另一个类型的等价值的过程。转换后的值应和原值一样,但其类型为目标类型。​ 可以为类和结构定义隐式和显式转换。需要 public 和 static 修饰符。implicit 和 explicit 分别表示隐式和显式转换。只可以为类和结构定义。不能重定义标准隐式或显式转换。对于源类型 S 和目标类型 T:S 和 T 类型不能相同。S 和 T 不能有继承关系。S 和 T 不能同时为接口或 object。

2023-12-07 13:55:30 230

原创 C# 图解教程 第5版 —— 第16章 接口

​ 接口是声明一组函数成员而不进行实现的引用类型,只能用类和结构来实现接口。使用 IComparable 接口的示例​ Array 类的 Sort 方法依赖于 IComparable 接口,其声明在 BCL 中,只包含唯一的 CompareTo 方法。图 16.1 中灰色表示该方法目前未实现。图16.1 IComparable 接口负数:当前对象 < 参数对象。正数:当前对象 > 参数对象。0:两个对象相等。

2023-12-06 21:14:51 1139

原创 LeetCode 面试题 17.01. 不用加号的加法

将 a、b 进行二进制加法,ai、bi 表示 a、b 第 i 位的值(0或1),ci 表示第 i 位的进位(0或1)。使用 ans 表示计算结果,初始情况 ans 各位均为 0。设计一个函数把两个数字相加。或者其他算术运算符。

2023-12-06 19:15:12 201

原创 LeetCode 面试题 16.26. 计算器

给定一个包含正整数、加(+)、减(-)、乘(*)、除(/)的算数表达式(括号除外),计算其结果。整数除法仅保留整数部分。表达式仅包含非负整数,

2023-11-20 13:08:58 359

原创 LeetCode 面试题 16.25. LRU 缓存

设计和构建一个“最近最少使用”缓存,该缓存会删除最近最少使用的项目。缓存应该从键映射到值(允许你插入和检索特定键对应的值),并在初始化时指定最大容量。当缓存容量达到上限时,它应该在写入新数据之前删除最近最少使用的数据值,从而为新的数据值留出空间。LRUCache cache = new LRUCache( 2 /* 缓存容量 */ );- 如果密钥 (key) 存在于缓存中,则获取密钥的值(总是正数),否则返回 -1。// 返回 -1 (未找到)cache.get(1);// 返回 -1 (未找到)

2023-11-17 19:51:56 1140

原创 C# 图解教程 第5版 —— 第15章 事件

​ 以下示例展示发布者 Incrementer 和订阅者 Dozens 的使用,在 DoCount 方法中,每增加 12 个计数就触发 CountedADozen 事件。​ 发布者 / 订阅者模式:发布者定义了一系列事件,订阅者可以通过向发布者提供一个方法来“注册”以获取通知。​ 和委托类似,如果一个处理程序在事件内注册了多次,移除时只移除列表最后一个。图15.8 包含发布者和订阅者的完整程序,展示了使用事件所必须的 5 个部分。​ 当事件发生时,发布者“触发事件”,然后执行订阅者提交的所有方法。

2023-11-16 23:35:51 369

原创 LeetCode 面试题 16.24. 数对和

直接遍历数组,使用 map 记录出现过的数字和次数,每次查找是否有匹配的 another。设计一个算法,找出数组中两数之和为指定值的所有整数对。一个数只能属于一个数对。使用双指针双向检测,注意要先排序。

2023-11-16 14:17:26 163

原创 LeetCode 面试题 16.22. 兰顿蚂蚁

一只蚂蚁坐在由白色和黑色方格构成的无限网格上。开始时,网格全白,蚂蚁面向右侧。(2) 如果在黑色方格上,则翻转方格的颜色,向左(逆时针方向)转 90 度,并向前移动一个单位。(1) 如果在白色方格上,则翻转方格的颜色,向右(顺时针)转 90 度,并向前移动一个单位。表示,分别表示蚂蚁 左、上、右、下 的朝向。只需要返回能够包含蚂蚁走过的所有方格的最小矩形。网格由数组表示,每个元素是一个字符串,代表网格中的一行,黑色方格由。编写程序来模拟蚂蚁执行的前 K 个动作,并返回最终的网格。表示,蚂蚁所在的位置由。

2023-11-15 13:01:21 224

原创 LeetCode 面试题 16.21. 交换和

返回一个数组,第一个元素是第一个数组中要交换的元素,第二个元素是第二个数组中要交换的元素。若有多个答案,返回任意一个均可。若无满足条件的数值,返回空数组。给定两个整数数组,请交换一对数值(每个数组中取一个数值),使得两个数组所有元素的和相等。

2023-11-13 23:35:24 416

原创 LeetCode 面试题 16.20. T9键盘

在老式手机上,用户通过数字键盘输入,手机将提供与这些数字相匹配的单词列表。每个数字映射到0至4个字母。给定一个数字序列,实现一个算法来返回匹配单词的列表。你会得到一张含有有效单词的列表。题目还好,一个一个匹配就是了。用队列存储中间满足匹配的单词,同时使用 Match 函数判断匹配,而不是建立 Map 判断映射关系,这样会快一点。

2023-11-11 15:00:37 577

原创 LeetCode 面试题 16.19. 水域大小

该矩阵中每个点的值代表对应地点的海拔高度。若值为0则表示水域。由垂直、水平或对角连接的水域为池塘。池塘的大小是指相连接的水域的个数。编写一个方法来计算矩阵中所有池塘的大小,返回值需要从小到大排序。遍历所有点,若为池塘,则进行泛洪“污染”(深度优先遍历),将与其连接的池塘全设置为 -1,以免后续重复计算。本算法使用 DIR 表示当前相对泛洪中心的位置,以确定泛洪的下次污染区域,减少些许重复“污染”时间。你有一个用于表示一片土地的整数矩阵。输出: [1,2,4]

2023-11-10 23:23:49 474

原创 LeetCode 面试题 16.18. 模式匹配

不能同时表示相同的字符串。编写一个方法判断value字符串是否匹配pattern字符串。,顺序取 pattern 中的每个字符,判断 value 对应位置是否匹配。“a”=“dogdog”,b=“”,反之也符合规则。组成,用于描述字符串中的模式。代码中用 lens 存储所有的有序对。),该字符串也匹配像。判断长度是否满足要求。

2023-11-06 15:59:12 245

原创 LeetCode 面试题 16.17. 连续数列

使用分治可以实现 O(logn) 的复杂度。将数组 nums 一分为二,记为 left 和 right。给定一个整数数组,找出总和最大的连续数列,并返回总和。连续子数组 [4,-1,2,1] 的和最大,为 6。使用动态规划可以实现。,因此可以边计算边更新。

2023-11-05 22:50:25 330

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除