1.webgl打包内存上限:
https://docs.unity.cn/cn/2023.2/Manual/webgl-memory.html
官方文档里面说是2GB,实际测试4GB(也就是4096MB)也是可以的。
如果这里超出了,就会在打包的时候报错。然后这个错误也很难定位。
Building Library\Bee\artifacts\WebGL\build\debug_WebGL_wasm\build.js failed with output:
C:\workspace\#neiwangsvn\U3D\IFCViewer - URP>set MYDIR=C:\Program Files\Unity 2023.2.4f1\Editor\Data\PlaybackEngines\WebGLSupport\BuildTools\Emscripten\emscripten\
C:\workspace\#neiwangsvn\U3D\IFCViewer - URP>goto FOUND_MYDIR
wasm-ld: error: maximum memory too large, cannot be greater than 4294967296
emcc: error: '"C:/Program Files/Unity 2023.2.4f1/Editor/Data/PlaybackEngines/WebGLSupport/BuildTools/Emscripten/llvm\wasm-ld.exe" @C:\Users\hzkek\AppData\Local\Temp\emscripten_1683lb3u.rsp.utf-8' failed (returned 1)
UnityEngine.GUIUtility:ProcessEvent (int,intptr,bool&)
Build completed with a result of 'Failed' in 18 seconds (18133 ms)
Building Library\Bee\artifacts\WebGL\build\debug_WebGL_wasm\build.js failed with output:
C:\workspace\#neiwangsvn\U3D\IFCViewer - URP>set MYDIR=C:\Program Files\Unity 2023.2.4f1\Editor\Data\PlaybackEngines\WebGLSupport\BuildTools\Emscripten\emscripten\
C:\workspace\#neiwangsvn\U3D\IFCViewer - URP>goto FOUND_MYDIR
wasm-ld: error: maximum memory too large, cannot be greater than 4294967296
emcc: error: '"C:/Program Files/Unity 2023.2.4f1/Editor/Data/PlaybackEngines/WebGLSupport/BuildTools/Emscripten/llvm\wasm-ld.exe" @C:\Users\hzkek\AppData\Local\Temp\emscripten_1683lb3u.rsp.utf-8' failed (returned 1)
UnityEngine.GUIUtility:ProcessEvent (int,intptr,bool&)
2.webgl 的jslib报错的调试和修改debug:
jslib报错,有时候打包的时候就会检查出来,一般是语法错误。
比如:
typeof(someFunction) == function
这种直接就会报错,需要改成
typeof(someFunction) == 'function'
还有一种是运行时报错,这就比较烦,需要在浏览器里F12定位。
我用了BestHttp插件,然后这个插件的jslib报错了。
这边是这样定位问题的。
首先是浏览器报错,F12打开调试
在源代码中看到
loader.js中的
function h(e, t, r) { -1 == e.indexOf("fullscreen error") && (b.startupErrorHandler ? b.startupErrorHandler(e, t, r) : b.errorHandler && b.errorHandler(e, t, r) || (console.log("Invoking error handler due to\n" + e), "function" == typeof dump && dump("Invoking error handler due to\n" + e), h.didShowErrorMessage || (-1 != (e = "An error occurred running the Unity content on this page. See your browser JavaScript console for more info. The error was:\n" + e).indexOf("DISABLE_EXCEPTION_CATCHING") ? e = "An exception has occurred, but exception handling has been disabled in this build. If you are the developer of this content, enable exceptions in your project WebGL player settings to be able to catch the exception or see the stack trace." : -1 != e.indexOf("Cannot enlarge memory arrays") ? e = "Out of memory. If you are the developer of this content, try allocating more memory to your WebGL build in the WebGL player settings." : -1 == e.indexOf("Invalid array buffer length") && -1 == e.indexOf("Invalid typed array length") && -1 == e.indexOf("out of memory") && -1 == e.indexOf("could not allocate memory") || (e = "The browser could not allocate enough memory for the WebGL content. If you are the developer of this content, try allocating less memory to your WebGL build in the WebGL player settings."), alert(e), h.didShowErrorMessage = !0))) }
代码段报错
根据错误提示,在整个项目目录中搜索关键字
socket.socketImpl.onopen和dynCall_vi
定位到BestHttp的jslib库
源代码:
socket.socketImpl.onopen = function(e) { console.log(id + ' WS_Create - onOpen'); Module['dynCall_vi'](onOpen, id); };
这里报错提示dynCall_vi —————— is not a function
所以要加个if做检测,代码改成:
socket.socketImpl.onopen = function(e) { console.log(id + ' WS_Create - onOpen'); if(Module['dynCall_vi'] != null && typeof(Module['dynCall_vi']) == 'function') Module['dynCall_vi'](onOpen, id); };
再次打包运行,错误解决
3.优化树木显示
一般显示优化的树木有几种方式:
1)3个互相垂直90度相交的面片
2)update中实时朝向相机的一个面片
3)采用low poly,4面体,8面体,12面体,20面体,球体等
这边都试过,最后选了4面体,直接放一下效果图:
12面体:
4面体:
4面体12面体混合使用:
4.生成式AI回答Lua做脚本语言能够防止反编译吗?
Unity 使用 Lua 作为脚本语言,生成的是 Lua 字节码,而不是 Lua 源代码。如果你想反编译 Lua 字节码以获得源代码,你需要一个 Lua 反编译器。然而,Lua 字节码非常难以反编译,因为它的结构与机器代码类似,不包含源代码级别的信息。
尽管如此,如果你的应用程序中包含 Lua 源代码,这些源代码可能会在打包应用程序中暴露出来。在这种情况下,攻击者可以简单地查看应用程序的资源文件来获取 Lua 源代码。
为了保护你的 Lua 源代码,你可以采取以下措施:
- 将 Lua 源代码编译为字节码:使用 Lua 编译器将 Lua 源代码编译为字节码,这样攻击者就无法直接查看源代码。
- 加密 Lua 源代码:在打包应用程序之前,可以使用一些工具(如 luacrypto)对 Lua 源代码进行加密。这样,即使攻击者获得了 Lua 源代码,他们也无法立即使用它。
- 使用 C# 或其他编程语言编写敏感逻辑:将应用程序中较敏感的部分用 C# 或其他编程语言编写,而不是 Lua。这样,攻击者更难篡改应用程序的核心功能。
5.如何学习java spring的注解
- 理解注解的基本概念:在深入学习 Spring 注解之前,首先要理解 Java 注解的基本概念和作用。了解注解是如何工作的,以及它们在编译时和运行时的不同作用。
- 逐步学习:不要试图一次性学习所有的 Spring 注解。可以按照类别逐步学习,例如先从核心的 @Component、@Service、@Repository 和 @Controller 开始,然后再学习与特定功能相关的注解,如 @RequestMapping、@RestController 等。
- 实践操作:通过实际编写代码来应用这些注解。实践是最好的学习方式,通过创建简单的 Spring 应用程序并使用不同的注解,你可以更直观地理解它们的工作方式和效果。
- 查阅官方文档:Spring 官方文档提供了详尽的注解列表和说明。当你对某个注解有疑问时,查阅官方文档是获取准确信息的最佳途径。
- 参考示例项目:查看和分析一些简单的 Spring 示例项目,了解如何在实际项目中使用注解。GitHub 上有许多优秀的开源项目,你可以通过阅读它们的源代码来学习注解的使用。
- 使用 IDE 辅助:现代 IDE(如 IntelliJ IDEA、Eclipse 等)提供了对 Spring 注解的自动完成和提示功能。这些工具可以帮助你更快地熟悉注解,并避免拼写错误。
- 理解注解背后的原理:了解注解背后的实现机制,例如 Spring 如何通过反射和依赖注入来处理注解。这可以帮助你更深入地理解注解的作用。
- 参与社区讨论:加入 Spring 社区,参与论坛、博客和 Stack Overflow 等平台上的讨论。通过向他人提问或解答问题,你可以加深对注解的理解。
- 编写自己的注解:尝试创建自己的注解,并在项目中使用它们。这可以帮助你更好地理解注解的创建和使用过程。
- 持续学习:Spring 框架不断更新,新的注解和功能会被加入。保持对新技术的关注,并不断更新你的知识库。
为什么使用特定的注解?
- 语义清晰:使用特定的注解可以更清晰地表达类的职责和作用域。例如,@Service 用于标记服务层组件,@Repository 用于数据访问层,而 @Controller 用于控制器层。这种分类有助于开发者快速理解每个组件的用途。
- 自动装配:特定的注解可以启用特定的自动装配规则。例如,@Repository 会启用对持久化相关的 Bean 的自动装配,如 JpaRepository 接口的实现。
- 类型安全:特定的注解可以提供类型安全。例如,@Controller 确保一个类是控制器,并且它的方法可以用于处理 HTTP 请求。
- IDE 支持:特定的注解可以提供更好的 IDE 支持,如代码导航、重构和提示等。
- 扩展和自定义:特定的注解可以更容易地进行扩展和自定义。例如,你可以创建一个继承自 @Repository 的自定义注解,以便添加特定的行为或配置。
各个注解的用途:
- @Service:用于标记服务层组件,这些类通常包含业务逻辑,并且可能会被多个控制器或服务层组件所使用。@Service 注解的类可以被 Spring 容器管理,并且可以利用 Spring 提供的依赖注入、AOP 等特性。
- @Repository:用于标记数据访问层组件,即 DAO(Data Access Object)组件。这些类通常包含与数据库交互的逻辑。@Repository 还启用了 Spring 数据访问相关的异常处理,例如,任何继承自 RuntimeException 的异常都会被转换为持久化异常。
- @Controller:用于标记控制器组件,这些类负责处理用户的 HTTP 请求并返回响应。@Controller 注解的类通常包含方法,这些方法通过 @RequestMapping 或其衍生注解(如 @GetMapping、@PostMapping 等)映射到特定的 URL 路径。
- Spring Boot 应用程序可以独立运行,这意味着你可以将应用程序打包成一个可执行的 JAR 或 WAR 文件,并直接运行它,而不需要将其部署到外部的 Servlet 容器(如 Tomcat、Jetty 等)中。这是通过 Spring Boot 的内嵌容器功能实现的,它允许你在应用程序中直接启动一个 Web 服务器。要使得 Spring Boot 应用程序能够独立运行,你需要遵循以下步骤:创建 Spring Boot 项目:使用 Spring Initializr(https://start.spring.io/)或你的 IDE(如 IntelliJ IDEA、Eclipse 等)来创建一个新的 Spring Boot 项目。添加依赖:在你的 pom.xml(Maven)或 build.gradle(Gradle)文件中,添加你需要的依赖。例如,对于 Web 应用程序,你需要添加 spring-boot-starter-web 依赖。编写代码:编写你的应用程序代码,包括配置类、控制器、服务、实体等。构建应用程序:使用 Maven 或 Gradle 构建你的应用程序。对于 Maven,你可以在项目根目录下运行 mvn package 命令;对于 Gradle,运行 gradle build 命令。这将创建一个可执行的 JAR 或 WAR 文件。运行应用程序:如果你创建的是一个 JAR 文件,可以使用 java -jar 命令来运行它,如:java -jar target/your-app-name.jar。如果你创建的是一个 WAR 文件,并且想要将其部署到外部的 Servlet 容器中,你可以将 WAR 文件复制到 Servlet 容器的 webapps 目录下,然后启动容器。但是,如果你想要独立运行 WAR 文件,你需要将 WAR 文件转换为一个可执行的 JAR 文件,并包含一个内嵌的 Servlet 容器。这可以通过在 pom.xml 中添加 Spring Boot 的 Maven 插件,并配置它以产生一个包含内嵌容器的可执行 JAR 来实现。访问应用程序:默认情况下,Spring Boot 应用程序将在 http://localhost:8080 上运行(除非你配置了不同的端口)。你可以在浏览器中访问这个地址来查看你的应用程序。这就是 Spring Boot 应用程序独立运行的基本过程。Spring Boot 提供了很多其他功能,如健康检查、指标监控、外部化配置等,这些都可以帮助你更好地管理和维护你的应用程序。
移动端微型关系型数据库
移动端微型关系型数据库有SQLite。
SQLite是一个开源的嵌入式关系数据库,实现自包容、零配置、支持事务的SQL数据库引擎。其特点是高度便携、使用方便、结构紧凑、高效、可靠。与其他数据库管理系统不同,SQLite的安装和运行非常简单,在大多数情况下,只要确保SQLite的二进制文件存在即可开始创建、连接和使用数据库。
unity 对 sqlite支持
Unity 对 SQLite 的支持主要通过第三方库实现,因为 Unity 默认不包含对 SQLite 的内置支持。以下是在 Unity 中使用 SQLite 的一些常见方法和步骤:
- 选择 SQLite 库:
- System.Data.SQLite: 这是一个流行的 SQLite 库,它可以在 .NET Framework 和 .NET Core 上运行。尽管 Unity 使用的 .NET 子集可能不完全兼容标准 .NET 库,但 System.Data.SQLite 有时可以在 Unity 中工作,尤其是在较旧的 Unity 版本中。
- Microsoft.Data.Sqlite: 这是另一个 SQLite 库,专为 .NET Core 和 .NET 5+ 设计。它通常不直接在 Unity 中使用,因为 Unity 的 .NET 支持版本较低。
- SQLitePCL.raw: 这是一个轻量级的 SQLite 库,专为跨平台使用而设计,包括 Unity。它提供了对 SQLite 的直接访问,并且通常更容易在 Unity 中集成。
- 将库集成到 Unity 项目中:
- 将所选的 SQLite 库作为 DLL 文件导入到 Unity 项目中。
- 如果库依赖于其他原生插件(如 SQLitePCL.raw),确保这些插件也被正确导入。
- 某些情况下,可能需要在 Unity 项目设置中配置插件的路径或特殊设置,以确保它们被正确加载。
- 编写代码以使用 SQLite:
- 使用 C# 编写代码来创建数据库连接、执行查询和更新、处理结果等。
- 根据所选的 SQLite 库,代码的结构和API调用将有所不同。
- 处理平台差异:
- Unity 支持多个平台(如 Windows、macOS、Linux、iOS、Android 等)。确保所选的 SQLite 库和您的代码能在目标平台上正常工作。
- 某些平台可能需要特定的配置或原生库支持。
- 测试和调试:
- 在不同平台和设备上进行测试,以确保 SQLite 集成正常工作。
- 使用 Unity 的调试工具来诊断任何潜在的问题或错误。
- 考虑性能和内存使用:
- SQLite 是一个轻量级的数据库,但在大量数据或高并发情况下可能会遇到性能问题。
- 确保监控应用程序的性能和内存使用,并根据需要进行优化。
请注意,由于 Unity 的特殊性和跨平台要求,不是所有标准 .NET 库都能在 Unity 中无缝工作。因此,选择专为 Unity 或跨平台设计的库通常是一个更好的选择。此外,随着 Unity 的更新和 .NET 支持的改进,可用的库和最佳实践可能会发生变化。
将 WebSocket 集成到 Spring Boot 游戏服务端的学习路径中,可以让你创建实时的、交互性更强的游戏应用。以下是如何将 WebSocket 学习结合到上述学习路径中的建议:
基础阶段
- 了解 WebSocket 概念:
- 学习 WebSocket 协议的基本原理,包括全双工通信、握手过程和消息格式。
- 了解 WebSocket 如何在浏览器和服务器之间建立持久连接。
- Spring Boot 与 WebSocket:
- 阅读 Spring Boot 官方文档中关于 WebSocket 的部分,了解 Spring 提供的 WebSocket 支持。
- 学习 @EnableWebSocket 注解和 WebSocketController 类,了解如何在 Spring Boot 应用中启用和处理 WebSocket 请求。
进阶阶段
- 实现简单的 WebSocket 服务:
- 在 Spring Boot 应用中创建一个 WebSocket 控制器,使用 @Controller 注解。
- 实现基本的 WebSocket 消息处理逻辑,如连接、断开、发送和接收消息。
- 集成游戏逻辑:
- 将 WebSocket 通信集成到你的游戏逻辑中,例如,用于玩家之间的实时交互。
- 使用 WebSocket API 发送和接收游戏状态更新、事件通知等。
- 测试 WebSocket 功能:
- 使用 WebSocket 测试工具,如 websocket.org 提供的测试页面,验证 WebSocket 连接和消息传递。
- 编写自动化测试,确保 WebSocket 消息正确处理和传递。
实践示例
- 创建 WebSocket 端点:
- 在 Spring Boot 应用中创建一个新的 WebSocketController,配置 WebSocket 端点。
- 配置 WebSocket 路由:
- 在 application.properties 或 application.yml 中配置 WebSocket 路由和消息代理。
- 实现游戏特定的 WebSocket 逻辑:
- 根据游戏需求,实现玩家之间的实时通信和状态同步。
- 处理玩家加入、离开游戏,以及游戏中的各种事件。
- 前端集成:
- 在游戏的前端页面中,使用 JavaScript 的 WebSocket API 与后端建立连接。
- 实现前端的消息发送和接收逻辑,与后端 WebSocket 控制器协同工作。
总结
通过上述步骤,你可以将 WebSocket 学习整合到 Spring Boot 游戏服务端的开发中。从理解 WebSocket 的基本概念开始,逐步学习如何在 Spring Boot 中配置和使用 WebSocket,然后将 WebSocket 集成到游戏逻辑中,实现实时的交互功能。实践是学习的关键,通过创建实际的 WebSocket 端点和前端集成,你将能够更好地理解和掌握这些技术。
复制再试一次分享
####POST和PUT区别:
https://blog.csdn.net/xcc_2269861428/article/details/80433382
1.什么是幂等性
幂等性概念:幂等通俗来说是指不管进行多少次重复操作,都是实现相同的结果。
2.REST请求中哪些是幂等操作
GET,PUT,DELETE都是幂等操作,而POST不是,以下进行分析:
首先GET请求很好理解,对资源做查询多次,此实现的结果都是一样的。
PUT请求的幂等性可以这样理解,将A修改为B,它第一次请求值变为了B,再进行多次此操作,最终的结果还是B,与一次执行的结果是一样的,所以PUT是幂等操作。
同理可以理解DELETE操作,第一次将资源删除后,后面多次进行此删除请求,最终结果是一样的,将资源删除掉了。
POST不是幂等操作,因为一次请求添加一份新资源,二次请求则添加了两份新资源,多次请求会产生不同的结果,因此POST不是幂等操作。
java final 与C# const 的区别:
- 使用场景:
- Java的final关键字可以用于变量、方法和类。它表示一旦给变量赋值后,变量的值就不能改变;对于方法,表示该方法不能被子类重写;对于类,表示该类不能被继承。
- C#的const关键字仅用于变量(字段)。它表示该变量的值在编译时已经确定,并且在程序运行过程中不会改变。
- 值的类型:
- Java的final关键字可以用于基本数据类型(如int、double等)和引用类型(如对象)。对于引用类型,final关键字确保你不能将该引用赋值为其他对象,但你可以修改对象内部的可变成员。
- C#的const关键字只能用于基本数据类型、字符串和枚举。你不能将其用于引用类型。
- 初始化时机:
- Java的final变量可以在声明时初始化,也可以在构造函数中初始化。如果在声明时初始化,必须赋值;如果在构造函数中初始化,可以不赋值,但必须保证在构造函数执行完毕后,final变量已被初始化。
- C#的const变量必须在声明时初始化,并且必须赋值。它不能在构造函数中初始化。
- 变量作用域:
- Java的final变量的作用域取决于它的声明位置。如果在类级别声明,则为全局变量;如果在方法内声明,则为局部变量。
- C#的const变量的作用域是全局的,即在整个程序中都可以访问。
MySQL与Java数据类型对应表
MySQL 数据类型 对应的 Java 类型
TINYINT | byte (使用 Integer 包装类处理无符号) |
SMALLINT | short (使用 Integer 包装类处理无符号) |
MEDIUMINT | int (使用 Integer 包装类处理无符号) |
INT | int (使用 Integer 包装类处理无符号) |
BIGINT | long (使用 BigInteger 处理无符号) |
FLOAT | float |
DOUBLE | double |
DECIMAL | java.math.BigDecimal |
DATE | java.sql.Date |
TIME | java.sql.Time |
DATETIME | java.sql.Timestamp |
TIMESTAMP | java.sql.Timestamp |
CHAR | String (或者 byte[] 如果字符集为 BINARY) |
VARCHAR | String |
TINYBLOB | byte[] |
BLOB | byte[] |
MEDIUMBLOB | byte[] |
LONGBLOB | byte[] |
ENUM | String (需要特殊处理枚举值) |
SET | String (需要特殊处理集合值) |
BIT | byte[] 或 Boolean (取决于上下文) |
MySQL与C#数据类型对应表
MySQL 数据类型 对应的 C# 类型
TINYINT | sbyte 或 byte (使用 int 包装类处理无符号) |
SMALLINT | short 或 int (使用 int 包装类处理无符号) |
MEDIUMINT | int (使用 int 包装类处理无符号) |
INT | int (使用 int 包装类处理无符号) |
BIGINT | long 或 BigInteger (使用 BigInteger 处理无符号) |
FLOAT | float |
DOUBLE | double |
DECIMAL | decimal |
DATE | DateTime |
TIME | TimeSpan |
DATETIME | DateTime |
TIMESTAMP | DateTime |
CHAR | string (或者 byte[] 如果字符集为 BINARY) |
VARCHAR | string |
TINYBLOB | byte[] |
BLOB | byte[] |
MEDIUMBLOB | byte[] |
LONGBLOB | byte[] |
ENUM | string (需要特殊处理枚举值) |
SET | string (需要特殊处理集合值) |
BIT | bool 或 byte[] (取决于上下文) |
暂无关于此日志的评论。