当前位置: 首页 > news >正文

cocos 3D自由世界游戏 - 开发

cocos 3D自由世界游戏 - 开发

  • 概述
  • 第一步 创建环境,XForge 框架
  • 基础3D创建思路
    • 场景
      • 地形
      • 树木等环境
    • 人物角色
      • 角色实现
        • 实现代码篇
        • 空间管理篇
        • 动画逻辑篇
        • 按钮实现篇
          • 虚拟摇杆
          • 多功能按钮
        • 移动和目标篇
        • AI实现
        • 角色属性以及身份牌篇
        • 装备篇
  • 结尾

在同时浅入了unity 和 cocos以来,得到了以下个人观点
------------------------------
unity:
:优点:方便 好用,插件能帮你做80%,剩下的就是完善自己的逻辑,资源(免费)多,容易获取—我觉得这些已经够自己用了。
:缺点:由于个人游戏的环境来说,app也好、win也好,都不好传播,没有自然流量,只能通过各小游戏平台实现(或者H5),所以我选择了微信小游戏,unity有直接打包成微信小游戏的工具,打包以后,主包很小,分包10M+,也差不多,但是需要放服务器去加载,可能研究不足的原因,打包的过程以及结果,暂无法控制。 在运行的过程中,发热比较重,(跟者官方的教程走,优化不足,插件重导致运算高),控制也有插件(按钮控制,屏幕触控),但不能做到分手指进行使用,(在缩放或者移动时候,会和其他手指同时作用),想来还是得自己做轮子才能更合适自己用。
:总结:写的时候是很开心的,用的时候是比较糟心的(还有各糟心的理由就是团结要收费。。)而且发热比较重
------------------------------
cocos
:优点:界面操作简洁,编辑器加载快,(不知道怎么,确实编辑器面板看着比unity 会更舒心点),对于开发过程来说,流程是一条走的(ts 单线程的原因吧,无论是组件、脚本、单例也好,总会觉得就是顺序从上到下来的,这个对前端来说比较亲切),动画图对应unity的动画状态,效果也是很像很好的,暂时就想到这么多子。
:缺点:!!!啥都要自己做(大部分),社区环境也是可以的,但共享的、实用的东西大部分是没有的,也可能现在还是unity 等其他开发为主,池子就这么大,大佬也只有这么些。
:总结:基本上在开发和流程来说,是非常棒的 ,不过开发起来比较累,都要自己实现,有些确实不兼容微信小游戏,比如基于babylon的Navigation 寻路,在打包后就有问题,因为没有window,后面没研究, 就直接用胶囊角色控制器代替了。总之 很多要自己写。

概述

大概大家都想做一个和魔兽一样的开放世界游戏,而且要轻 随时能玩 (特别是自己的游戏可以给自己开挂~),所以历经一年多的空闲时间(当然不是所有…)进行想法实现,最后发现,要素材没素材,要逻辑太过庞大的,到真正完成,估计还需要···时间!大量时间!(一个人开发太难了。)。所以 我想记录下现在的开发进度,以及开发遇到的事情吧,
以上文字较多,各位可选择后面基本代码实现来看,其他的可以省略掉,没关系

守护域界-基础尝鲜版-3D自由开放世界逻辑基础


源代码-cocos商店

第一步 创建环境,XForge 框架

我用 的是XForge框架,第一 他是免费的,第二 他好用,第三 作者 是 这个 (๑•̀ㅂ•́)و✧棒 。
这个框架理顺了你在开发时候的2d和3d的关系, 只做纯2d也完美, 他的资源复用、分包、Manager控制、数据控制,封装的很让人舒心, 开发的时候你只要用就好了,我用下来没有发现问题,发现的都是方便、好用 推荐(XForge)
怎样搭建可以去看他的文档、也可以加qq,这里就不多说了 可以自行去看。

基础3D创建思路

一个平台 、几棵树、一个自己、几个敌人,构成我所想的游戏环境,在cocos分包中,资源的分配管理是决定大小的最重要的东西,如果把要的素材全部在scene中放置的话, 所有用到的资源其实会打包两遍–资源管理分包-使用的战斗分包,所以一切的加载都要在初始化好基本环境以后,使用预加载、分包加载 去进行资源的管理加载、 最后 一个scene 只需要几百k 就可以显示几M,甚至十几M的内容。如: 总大小有16M
总大小有16M左右, 天空、角色、敌人、环境树木、Terrain等 占用比较大,不过没关系 微信小游戏可以30M以内,所以要控制每个分包要在4M以内,做好分包管理是最重要的事情,在我的想法中,就是角色、敌人、环境等, 都可以有多个分包,通过一个管理分包路径的目录来统一进行加载。在这里插入图片描述
通过每次都访问这个文件进行加载对应的一类预制体以及分包。

做到这里,就差不多整个架构已经搭建好了,可以加上素材了

场景

地形

场景的话使用的是Terrain,Terrain资源很大,一个差不多100*100的都要1M 而且是在颜色贴图只有两个简单的几K的颜色块和塑型没有的情况下,所以 用动态方式进行加载

  // 创建地形节点const terrainNode = new Node(option.name);// 先加入场景再添加物理组件this.PlaneNode.addChild(terrainNode);// 添加地形组件const terrainComp = terrainNode.addComponent(Terrain);terrainComp._asset = terrain;// 添加碰撞体组件(此时节点已在场景中)const collider = terrainNode.addComponent(TerrainCollider);collider.setGroup(PhysicsGroupMap.Terrain);collider.terrain = terrain; // ✅ 此时onLoad已执行terrainNode.position.set(option.position);load && load();

这种方式加载所以这1M的Terrain 不会在fight分包里面在这里插入图片描述
效果正常
在这里插入图片描述

树木等环境

也是同样的道理,通过预加载和分包加载的方式来进行,
通过下面代码来实现同样的预制体有不同的呈现方式 角度 位置的偏差

 /**加载node - 通过不同形式进行坐标的生成后调用 */loadNatureNode(opt: EnvironmentConfig) {// 随机选择资源路径const nodePool = NatureLoadManager.instance.createNatrueNode(opt.paths? opt.paths[Math.floor(Math.random() * opt.paths.length)]: opt.path);if (!nodePool) {console.error("节点创建失败,路径:", opt.path);return;}//缩放if (opt.offscale) {let scale =opt.offscale[0] + Math.random() * (opt.offscale[1] - opt.offscale[0]);nodePool[0].scale.set(scale, scale, scale);} else if (opt.scale) {nodePool[0].scale.set(opt.scale, opt.scale, opt.scale);}// 添加随机旋转(修复1:正确使用计算后的旋转值)if (opt.offRotation) {let randomRotation =opt.offRotation[0] +Math.random() * (opt.offRotation[1] - opt.offRotation[0]);this.randomRot_tmp.set(0, 0, randomRotation);nodePool[0].setRotationFromEuler(this.randomRot_tmp); // 使用临时变量而非原始数组}// 坐标计算(修复2:确保使用正确的坐标索引)if (opt.offSize) {opt.position[0] += Math.random() * opt.offSize[0];opt.position[2] += Math.random() * opt.offSize[1];}// 设置节点属性nodePool[0].position.set(opt.position[0], opt.position[1], opt.position[2]);this.PlaneNode.addChild(nodePool[0]);}

在资源配置上也用了分包管理的思想, 给每个关卡可以单独配置
在这里插入图片描述
包括圆形、范围、直线随机生成树木或其他
在这里插入图片描述
这样的方式 我只需要管理关卡的map数据 以及这个预制体的加入就好了,是不是很方便
最终效果
在这里插入图片描述
树是直线的 地面上的蘑菇草之类的是范围的, 后期也可以加上在放置的位置去获取Terrain这个位置的高度来确定位置(我的只是平面没考虑,有api是可以获取高度的)
环境已经搭建好了

人物角色

在多次从头开始的情况下,我始终觉得应该拆分角色(控制器,实际模型)。在初始化时候,只有这个控制器才代表当前的玩家,里面的模型或者技能之类的都是附加的,是通过这个控制器来进行整个使用过程的控制,所以这个控制器就应该是一个预制体,每个模型也应该是额外的预制体, 并且每个比如角色类型, 是一套适配控制器的(模型,动画,数据,属性)在这里插入图片描述
暂只考虑只有一个角色。其中我每个敌人也是公共用这个配置的控制器, 和角色同理
在这里插入图片描述
其实所有角色都是通过以上两个预制体实例出来的。
期间我使用了两种方法,一个是用内存池的方式来加载,但是每次加都或多或少有上次的属性残留,很麻烦, 所以后面我直接实例预制体了,就不通过内存池, 这样就方便多了,因为每个是新的,性能问题,哎暂时不考虑把

在这里插入图片描述在这里插入图片描述
我给角色和敌人配置了不同的分包,避免后期滥用分包的问题,超过4M再进行加分包

角色实现

实现代码篇

这步,我一开始是完全敌人和角色是一体的,但是发现,从0到1 的过程 变数太多,重构太多,毕竟不是专业而且不知道哪个公用哪个不同, 在这个版本中, 我使用两套(大部分代码还是相同的)的方式来做
这里说一句 ,整个js我都放在主包里,不进行分包,一方面做个2M以上的代码也比较多了,没必要,另一方面 ,运行时候不用太考虑js分包,是很爽的, 一开始我把js都放分包,有的地方主包又要用,代码会重复部分,后期代码成熟后再考虑
在这里插入图片描述
在这里插入图片描述
基本上一个文件夹就一个功能的ts,文件名之所以都加上角色和敌人的区分,是为了编程时候不搞错,名字相同不好找而且容易混掉。

在总控实现加载各部分,reroop

export class Actor extends Component {/**挂载组件 *//**移动组件 */_moveControl: ActorMoveControl;/**动画组件 */_animControl: ActorAnimActiveControl;/**武器组件 */_weaponControl: ActorWeapon;/**攻击组件 */_attackControl: ActorAttackControl;/**属性组件 */_attribute: ActorAttribute;/**AI大脑实例 */_aiBrain: ActorAiBrain;/**事件控制器 */_eventControl: ActorEventControl;// 初始化AIthis._aiBrain = new ActorAiBrain(this, opt

相关文章:

  • GitHub实用手册
  • Java项目之基于ssm的学校小卖部收银系统(源码+文档)
  • 获取 arm-none-eabi-ld 默认使用的链接脚本
  • 【2-10】E1与T1
  • CentOS 下 Zookeeper 常用命令与完整命令列表
  • element-ui colorPicker 组件源码分享
  • 音视频小白系统入门笔记-0
  • 多光谱相机与高光谱相机的区别
  • AI搜索引擎的局限性
  • 代码随想录算法训练营Day30 | 01背包问题(卡码网46. 携带研究材料)、Leetcode416.分割等和子集
  • 车载软件架构 --- Autosar OS MCU多核启动
  • Python(16)Python文件操作终极指南:安全读写与高效处理实践
  • TikTok账号养号难题解决方案:利用TK矩阵系统助力账号快速成长
  • 爱普生SG3225EEN低抖动差分晶振在网络通信的应用
  • JAVA如何操作文件?(超级详细)
  • Kimi-VL:开源多模态视觉语言模型的崭新突破
  • 爬虫框架 - Coocan
  • 2.2 函数返回值
  • 今日行情明日机会——20250415
  • 聊聊Spring AI Alibaba的DocumentParser
  • 国务院食安办:加强五一假期食品生产、销售、餐饮服务环节监管
  • 赵乐际主持十四届全国人大常委会第十五次会议闭幕会并作讲话
  • 孙磊已任中国常驻联合国副代表、特命全权大使
  • 融创服务全面退出彰泰服务集团:约8.26亿元出售广西彰泰融创智慧80%股权
  • “女乘客遭顺风车深夜丢高速服务区”续:滴滴永久封禁两名涉事司机账号
  • 民营经济促进法出台,自今年5月20日起施行