游戏框架笔记

游戏的数据有哪些类型

无非是只读数据(各种道具配表里的数据)和可读可写数据(玩家属性、拥有的物品)。

游戏框架需要哪些管理器

用户数据管理器

负责找到数据持久化文件,从中读取指定用户的数据,包括玩家的设置数据(音量等)、拥有的物品(金币、人物、道具)。

不需要依附游戏对象,一般是不继承MonoBehavior的单例。

资源配置管理器

负责找到配表文件,根据外界要求的资源种类、ID返回资源的详细信息(游戏内名字、图标、预制体,其他信息如价格)。

资源加载管理器

负责封装加载资源的方法(Resources和AB包),以便快速切换。主要用于资源配置信息管理器加载配表文件,和加载UI面板预制体。

和资源配置信息管理器可以合成一个吗?不合适,因为还要加载UI预制体。

这个管理器就是提供加载资源的方法,并能方便在Resources和AB包加载之间切换。

场景管理器

提供异步加载场景的方法。显示加载界面、更新进度条的代码可以放在里面。

因为要用协程,且全局存在,应该是DontDestroyOnLoad的继承MonoBehavior的类。

UI管理器

提供加载面板的方法,包括从Resources和AB包加载,包括全屏面板和部分面板。为此需要面板预制体的路径和资源名,需要一个方法知道当前哪些面板在显示,可以是查看一个面板类的单例是否存在,也可以用一个字典存储显示的面板。

声音管理器

使玩家可在任意场景的设置面板改变音乐和音效音量。游戏所有播放声音都要使用它封装的函数。它无需储存用户设置的音量,因为那属于用户数据,由用户数据管理器存储。

看想不想用拖赋值,想就用DontDestroyOnLoad的继承MonoBehavior的类。

关卡场景管理模块

以上是游戏全局需要的管理器,在关卡场景有一些所有关卡都相同的管理模块:输入模块、相机模块、UI模块(HUD、对话面板、交互选项面板、任务面板)、关卡管理器、缓存池。

这些模块一般打成一个预制体,新建关卡时直接拖入。(虚幻项目直接就有一套这些)

缓存池

在射击游戏里一般用来存弹壳、弹头、击中效果。只在关卡场景需要,所以用继承MonoBehavior的单例,可以和游戏管理器、输入模块等打进同一个预制体。

public enum BufferType{impact,bullet, rifleShell,handgunShell,impactBlood}
public class BufferPoolBase : MonoSingleton<BufferPoolBase>
{public const float impactLifeTime=1;Dictionary<BufferType,Transform> bufferDict=new Dictionary<BufferType,Transform>();//可能的情况包括没缓冲池、有缓冲池没物体(一般不会有,但理论上可能)、有缓冲池有物体public GameObject Depool(GameObject prefab,BufferType bufferType,Vector3 position){GameObject instance;if(bufferDict.ContainsKey(bufferType)){//缓冲池已建立if(bufferDict[bufferType].childCount>0){//缓冲池里有物体instance=bufferDict[bufferType].GetChild(0).gameObject;//取出instance.transform.SetParent(null);//解绑instance.transform.position = position;instance.SetActive(true);//激活}else{//有缓冲池没物体(曾经放入过物体,又拿出了)instance=Instantiate(prefab,position,Quaternion.identity);}}else{//没有缓冲池Transform bufferTransform=new GameObject(bufferType.ToString()).transform;bufferTransform.parent=transform;bufferDict.Add(bufferType, bufferTransform);instance=Instantiate(prefab,position,Quaternion.identity);}return instance;}public void Enpool(GameObject instance,BufferType bufferType){if(!bufferDict.ContainsKey(bufferType)){Transform bufferTransform=new GameObject(bufferType.ToString()).transform;bufferDict.Add(bufferType, bufferTransform);}instance.transform.SetParent(bufferDict[bufferType]);instance.SetActive(false);}public IEnumerator EnpoolLater(GameObject instance,BufferType bufferType,float delay){yield return new WaitForSeconds(delay);Enpool(instance,bufferType);}

事件中心

我们知道事件中心是用于一个事件引发很多操作的,它比直接调用避免了蜘蛛网一样的耦合,但是又比直接调用麻烦一点。那么问题是,任何一个类操作引起另一个类的操作都要用事件中心吗?那样很明显事件中心会有大量事件。应该设置一个操作引起其他类操作个数的阈值,达到阈值的使用事件中心。

输入模块、玩家人物和人物

玩家人物和NPC人物有一些共性,玩家人物还有一些个性:更新UI、接受输入控制。通常会把玩家人物作为人物的子类,重写一些方法。问题是任何一个类操作引起另一个类操作都要用事件中吗?

是否只有一个操作引起的操作达到一个数量时才值得用事件中心?

输入模块和玩家人物要写在一个脚本吗?

如果用了新的Input System,我们知道给几十个按键配回调很麻烦,会想把PlayerInput和处理回调的脚本放在一个预制体里,如果把PlayerInput和玩家人物打进预制体,那么不同关卡用不同人物时又要换人物的骨架和模型,人物身上绑的物品挂载点、约束也要重新绑。会想到写一个输入回调处理脚本MyInputHandler和PlayerInput放在一起,MyInputHandler指向玩家人物。也就是输入模块和玩家人物分离。

输入脚本和人物脚本的代码分布

人物的各种行为会封装成方法Move()、Turn()、Run()、Jump()。这些方法是在

  1. 人物脚本Update()
  2. 输入脚本Update()
  3. 输入脚本处理输入的方法

执行?

放在输入脚本Update()就等于输入回调先写入输入脚本字段,再传给人物脚本行为方法的输入参数。

放在人物脚本Update就等于先写入人物脚本字段再让行为方法读取。

放在输入脚本的输入回调方法就是把输入变量传给人物方法的输入参数,只在输入变量改变时执行。

为了减少字段,可以尽量用3,但有一些方法必须每帧执行,比如跑步可能被各种情况打断(射击、换弹、坠落)。跑步要执行,除了按下跑步,还要满足几个条件,这些条件有的靠状态机的互斥就可以(跳跃、坠落),有的要另外判断(主要是上半身层的)。执行跑步前把这些条件全部&&。

管理器分类

根据管理器的生命周期,可以分为整个游戏内存在的和场景内存在的。根据是否必须继承MonoBehavior,可以分为继承和不继承。这两个问题组合,其中不继承MonoBehavior的一定整个游戏存在。这样就把管理器分为3类:

  1. 不继承MonoBehavior;
  2. 继承MonoBehavior;
  3. 继承MonoBehavior且DontDestroyOnLoad;

不继承MonoBehavior

用户数据管理器、资源配置管理器;

继承MonoBehavior

各场景内的管理器。对于关卡场景,有输入、相机、秩序管理、缓存池。

继承MonoBehavior且DontDestroyOnLoad

通常是游戏全局存在且需要协程的管理器:场景管理器、AB包管理器。

还有必须和组件关联的管理器,比如声音管理器,必须记录音乐声源和UI音效声源。

这些管理器可以打成一个预制体。

登录注册系统

多用户数据系统

如果一个游戏要做登录注册界面,那么它就是一个多用户游戏,意味着它有一个记录用户名和密码的文件,而其他大部分数据(玩家拥有的人物、武器、物品、音量)都因用户而异,需要在每个用户注册时建一个文件夹,把这些用户数据文件都放在里面。

这样UserDataManager在构建的时候就不能加载所有的数据,因为还没登录,不知道用户名,也就不知道这些数据文件的路径。所以需要一个UserManager,开始运行时构建,负责获取上次登录用户、注册新用户、判断登录是否成功。加载登入用户数据的DataManager在登录成功后构建,它读取数据的路径依赖登入的用户名。

场景管理

需要有一个《场景转换图》列出所有的场景和哪些场景。一般需要登录场景、主界面场景、若干游戏场景。登录场景和主界面场景应该分开,因为主界面场景可能从登录场景或游戏场景进入。

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

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

相关文章

【C语言进阶】指针面试题详解(2)

上一期内容&#xff0c;大多数的解题思路写在代码中&#xff0c;没有写在正文中&#xff0c;这就导致系统判断文章质量不高&#xff0c;没有什么数据&#xff0c;这一期将思路写在正文中。注意&#xff1a;运行环境是x86 1.题目1思路&#xff1a;&a是取到了整个数组的地址&…

一文读懂现代卷积神经网络—稠密连接网络(DenseNet)

目录 什么是 DenseNet&#xff1f; 稠密块&#xff08;Dense Block&#xff09;详解 一、稠密块的核心思想 二、稠密块的结构组成 1. 卷积单元&#xff08;的结构&#xff09; 2. 密集连接的具体方式 3. 关键参数&#xff1a;增长率&#xff08;Growth Rate, k&#xff0…

关于僵尸进程

深入理解僵尸进程&#xff1a;成因、危害与解决方案 进程终止的条件 我们先了解一下进程销毁的条件&#xff1a; 调用了exit函数在main函数中执行了return语句 无论采用哪种方式&#xff0c;都会有一个返回值&#xff0c;这个返回值由操作系统传递给该进程的父进程。操作系统不…

深入解析进程、线程与协程:现代并发编程的三大支柱

深入解析进程、线程与协程&#xff1a;现代并发编程的三大支柱在计算资源日益丰富的时代&#xff0c;理解并发执行机制已成为每位开发者的必修课。本文将带你深入探索操作系统中的三大并发模型&#xff1a;进程、线程与协程&#xff0c;揭开它们的神秘面纱。引言&#xff1a;并…

奇安信下一代防火墙SecGate3600

一、实验拓扑&#xff1a;二、实验目的&#xff08;1&#xff09;让内网可以访问外网。&#xff08;2&#xff09;让外网能够访问dmz区域的web服务器。&#xff08;3&#xff09;测试防火墙的防毒功能&#xff0c;并进行检测。三、实验步骤&#xff08;1&#xff09;防火墙配置…

基于STM32的智能抽水灌溉系统设计(蓝牙版)

✌️✌️大家好&#xff0c;这里是5132单片机毕设设计项目分享&#xff0c;今天给大家分享的是基于《基于STM32的智能抽水灌溉系统设计》。 目录 1、系统功能 2.1、硬件清单 2.2、功能介绍 2.3、控制模式 2、演示视频和实物 3、系统设计框图 4、软件设计流程图 5、原理…

CISSP知识点汇总- 通信与网络安全

CISSP知识点汇总 域1---安全与风险管理域2---资产安全域3---安全工程域4---通信与网络安全域5---访问控制域6---安全评估与测试域7---安全运营域8---应用安全开发一、安全网络架构和保护网络组件 1、OSI 7层协议模型 应用层:SMTP、HTTP、SNMP 、TELNET、 FTP、SFTP、POP3、IM…

C++怎么将可变参数传递给第三方可变参数接口

文章目录&#x1f527; 1. 使用 va_list 转发&#xff08;兼容C/C的传统方案&#xff09;⚙️ 2. 模板参数包转发&#xff08;C11 类型安全方案&#xff09;&#x1f9e9; 3. 替代方案&#xff1a;参数封装与适配**方案A&#xff1a;使用 std::initializer_list (同类型参数)**…

服务端实现阿里云OSS直传

介绍 阿里云上传 OSS 有两种方式&#xff0c;一种是普通上传&#xff0c;一种是客户端直传。 普通上传&#xff0c;就是需要先将文件上传到服务端&#xff0c;然后调用接口将文件上传到阿里云。 当然这种方案经常出现不合理的使用方式&#xff0c;即客户端充当服务端的角色&…

on-policy和offpolicy算法

一句话总结On-policy&#xff08;同策略&#xff09;&#xff1a;边学边用&#xff0c;用当前策略生成的数据更新当前策略。例子&#xff1a;演员自己演完一场戏后&#xff0c;根据观众反馈改进演技。Off-policy&#xff08;异策略&#xff09;&#xff1a;学用分离&#xff0c…

CA-IS3082W 隔离485 收发器芯片可能存在硬件BUG

RT&#xff0c;这个RS485 隔离收发器芯片基本上不可用。本来要买CA-IS3082WX&#xff0c;不小心在某宝买到了没有X 的CA-IS3082W。立创上说没有X 的版本已经停产&#xff0c;连对应的数据手册都找不到&#xff0c;全换成WX 了。 这类半双工485 收发器芯片电路一般都直接把DE 和…

dockerfile 笔记

# 设置JAVA版本 FROM openjdk:20-ea-17-jdk MAINTAINER aaa # 指定存储卷, 任何向/tmp写入的信息都不会记录到容器存储层 VOLUME /tmp # 拷贝运行JAR包 ARG JAR_FILE COPY app.jar /app.jar RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime RUN echo "Asia/…

高德开放平台携手阿里云,面向开发者推出地图服务产品MCP Server

高德开放平台携手阿里云&#xff0c;面向开发者推出地图服务产品MCP Server&#xff0c;通过技术能力与生态资源的深度协同&#xff0c;助力开发者高效构建标准化地图服务&#xff0c;加速智能化场景落地。 高德开放平台携手阿里云&#xff0c;面向开发者推出MCP Server技术融合…

【论文阅读】AdaptThink: Reasoning Models Can Learn When to Think

AdaptThink: Reasoning Models Can Learn When to Think3 Motivation3.1 理论基础3.2 NoThinking在简单问题中的优势3.3 动机总结4. AdaptThink4.1 约束优化目标数学建模基本定义原始优化问题惩罚项转换归一化处理策略梯度实现优势函数定义PPO风格损失函数4.2 重要性采样策略问…

Redis高可用集群一主从复制概述

一、环境概述在分布式集群系统中为了解决服务单点故障问题&#xff0c;通常会把数据复制出多个副本部署到不同的机器中&#xff0c;满足故障恢复和负载均衡等需求。Redis也是如此&#xff0c;它为我们提供了复制功能&#xff0c;实现了相同数据的多个Redis副本。复制功能是高可…

Java 树形结构、层级结构数据构建

目录前言一、树状结构数据库存储二、工具类三、测试四、自定义树节点返回类型&#xff08;只保留部分字段&#xff09;1. 新增 TreeNodeDTO 类2.修改TreeUtil 类3.测试4.输出前言 有时候&#xff0c;开发过程中我们会遇到一些树状层级结构。 比如&#xff0c;公司部门组织架构…

求解线性规划模型最优解

归纳编程学习的感悟&#xff0c; 记录奋斗路上的点滴&#xff0c; 希望能帮到一样刻苦的你&#xff01; 如有不足欢迎指正&#xff01; 共同学习交流&#xff01; &#x1f30e;欢迎各位→点赞 &#x1f44d; 收藏⭐ 留言​&#x1f4dd; 既然选择了远方&#xff0c;当不负青春…

达梦国产数据库安装

打开ISO 、文件点击运行接受选择安装路径数据初始化 新数据库要创建数据库实例 选择一般用途数据库位置 选择所以系统用户&#xff0c;设置初始密码创建示例库可以选可以不选查找最近添加文件登录

互斥锁与同步锁

1. 锁的本质&#xff1a;解决并发问题的基石在多线程/多进程环境中&#xff0c;临界区&#xff08;Critical Section&#xff09; 是访问共享资源的代码段。锁的核心目标是确保互斥访问——任意时刻仅有一个执行单元能进入临界区。// 典型临界区示例 pthread_mutex_lock(&m…

高密度PCB板生产厂商深度解析

在电子制造领域&#xff0c;高密度PCB&#xff08;印制电路板&#xff09;作为核心基础元件&#xff0c;其技术精度与生产稳定性直接影响终端产品性能。本文精选五家具备核心技术优势的国内厂商&#xff0c;通过实地调研与行业数据验证&#xff0c;为读者呈现真实可信的供应商选…