制作Da○Saba○bar(第一期)
“Weekly Make Da○Saba○Bar”上线!
我突然开始以 Di*goth*ini 的风格来做这件事。
已经有一段时间了。
我是系统开发部的松山先生。
当我在智能手机上查看 Facebook 或漫画应用程序时,
经常会看到“Da○saba○bar”的广告。
我并不讨厌那种混乱感的游戏,所以
我决定尝试制作一款游戏,看看它是如何制作出来的。
顺便说一句,我从来没有玩过试玩版以外的任何东西,所以
如果有一些与原作有很大不同的部分,请多多包涵。
粗略要求
像往常一样,我们将澄清要求。
① 有一个 2D 场(网格类型)
② 通过触摸屏幕可以控制你的角色(玩家)上下左右
③ 有多种武器和关卡
④ 敌人会自然出现并向玩家移动
⑤ 有一个每个玩家、敌人和武器的命中检测
⑥ 当你击败敌人时,会显示经验值,通过收集它们可以升级新的武器和武器。
现在就这样了。
我在创建每个部分时都会考虑它们的细节。
让我们将时间测量和 SE 等详细的性能元素留作未来的问题(同时营造一种我们可能不会这样做的氛围)。
创建项目
好久没接触Unity了,安装最新版本吧。
2022.3.18f1 似乎是最新的 LTS,所以我会安装它。
Unity Hub 很有用。
将项目命名为“BeBeSurvivor”并将其创建为 2D 应用程序。
资源
在资源商店中查看创建它所需的资源(精灵)。
当我寻找免费的 2D 时,我发现了一个看起来与它一模一样的资源。
◾️亡灵生存资源包
包含玩家、敌人、武器等必要材料。
一切正常,所以我准备好用它来完成一切,但
我会感谢精灵。
◾️Lowpoly 纹理包
这是一个可以遍布整个场地的图像包。
它也包含在亡灵幸存者资源包中,但我们也尝试使用它。
使用包管理器导入这两个。
填写字段
Lowpoly纹理包中有很多材质,所以我选择我认为有用的材质。
尺寸有点大,所以我会尝试调整比例。
是这样的。
将其制作为预制件并使用脚本将其分布在适当的区域。
像这样的图像。
脚本看起来像这样。
// 生成从 (-50, -50, 0.5) 到 (50, 50, 0.5) (5 x 5 网格)的字段 Vector2 pos = new Vector2(-50, 50); float size = 5f; ; for(int x = 0; x <= cnt; x++) { for(int y = 0; y <= cnt; y++) { // 当 x, y 为 0 且 cnt 时,生成filed[1],否则生成filed[ 0] int idx = (x == 0 || x == cnt || y == 0 || y == cnt) ? 1 : 0; // 中心的 1 个正方形生成字段[2] if(x = = cnt / 2 && y == cnt / 2) { idx = 2; } // 生成游戏对象 obj = Instantiate(field[idx], new Vector3(pos.x + ( x * size), pos.y - (y * 大小), 0.5f), 四元数.identity); obj.transform.parent =parent.transform;
让我们仅在外围和中心放置不同的图像。
这次我要尝试一下有限域,但我觉得无限滚动实际上更好。
(但是,在我看来,这是一个相当合适的代码......)
玩家
幸存者资源包包含一些不错的材料,所以我会使用它们。
还有动画模式,因此创建等待、移动和死亡的动画,并
在 Animator 中设置它们。
这就是你移动它时的样子(待机动作)
移动(输入系统)
移动玩家角色。
该图像是以屏幕中心为原点,使角色向您点击的方向移动。
在我离开Unity一段时间的时候发布了
输入系统的我们还可以从包管理器导入它。
我尝试轻轻触摸它,但无法从输入操作中正确获取信息。
现在,我们将跳过Action并继续使用老式脚本控制来实现。
(当我有时间时,我会再次尝试使用输入操作)
var mouse = Mouse.current; if(mouse.press.ReadValue() == 1) // 按下状态 { if(holdTime > 0.0f) // wait {holdTime -= Time.deltaTime; holdTime = 0.0f; } else // 移动 { Vector2 pos = mouse.position.ReadValue() } } else // 释放状态 {holdTime = HoldTime;
操作信息可以从Mouse.current获取。
点击状态可以使用 mouse.press.ReadValue() 获得,如果触摸打开则返回 1,如果触摸释放则返回 0。
触摸状态经过一定时间后,使用mouse.position.ReadValue()获取触摸坐标并
计算移动方向(向量)。像这样的图像。
由于两点的坐标已知,因此可以通过简单的减法计算出向量。
由于长度并不重要,因此使用标准化对其进行标准化。
Vector2 vec = (pos - center).归一化;
如果将其设置为玩家的坐标(localPosition),角色就会移动。
是这样的。 (等待↔︎移动)
同时,仅提取移动方向上的X分量并切换角色的方向。 (沿y轴旋转180°)
摄像机跟踪
在这种状态下,角色将走出摄像机,因此摄像机将始终跟随角色,使其位于屏幕中央。
您所要做的就是将 MainCamera 的 Transform 的 localPosition 与角色坐标相匹配。
代码如下所示。请注意,z 坐标固定于相机。
// 让相机跟随 Vector3 pos = playerController.GetPosition(); pos.z = -1.0f; mainCamera.gameObject.transform.localPosition = pos;
实施后会是这个样子。
敌人
稻草人现在还好,所以适当地放置敌人。
这也包含在幸存者资源包中,所以我将使用它。 (谢谢你)
还有动画模式,因此创建移动/死亡动画并
在 Animator 中设置它们。
现在,我就这样吧。
碰撞判断
做出命中判断。
使用Unity标准提供的Collider2D。
首先,准备。
为每个玩家和敌人添加 Circle Collider 2D。
检查是否触发。
我们还将向播放器添加 Rigidbody 2D。 (敌人不需要)
这一次,我们不需要物理计算,所以将Body Type设置为Kinematic。
用脚本获取命中判断。
将以下函数添加到玩家和敌人代码中。 (触发类型)
private void OnTriggerEnter2D(Collider2D Collision) { // 在碰撞器击中时调用 // 如果击中敌人则造成伤害 if (collision.tag == "Enemy") { Debug.Log("Player Hit : " + Collision.name ); } } private void OnTriggerStay2D(Collider2D碰撞) { //碰撞体撞击时持续调用 } private void OnTriggerExit2D(Collider2D碰撞) { //碰撞体离开时调用 }
我们将使用标签来确定命中目标是什么。
默认情况下会注册 Player 标签,因此请添加 Enemy 标签和 Weapon 标签。
设置每个对象的标签。
如果运行它以便在接触时输出日志,它将如下所示。
这就是本月的全部内容
现在就这些了。
我认为基本机制已经基本落实。
Unity拥有一套完整的功能,因此相对容易实现。
在下一期中
我想实现武器(3种x 3级)
Unity项目稍后会上传到GitHub。
请稍等。
文章上传后我会更新。
我已将Unity项目上传到GitHub。
我希望这会对您有所帮助。
贝贝幸存者
好了,现在就这些了。
*虽然一开始写的是“每周”,但下一期预定在三月上传。