创造一个 Da○saba○ber(第 3 号)
![]()
由于内部学习和其他一些事情,我们已经有一段时间没有发布消息了。
感谢大家的辛勤付出。
我是系统开发部的松山先生。
我们很高兴推出“创建 Da○saba○bar”的第三期,该期在上一期中突然开始。
第一期内容在此↓
第二期在此 ↓
在第二版中,我们加入了三种玩家可以使用的武器(最高等级为3级)。
在第三版中,我们将加入僵尸的生态系统(包括生成和移动)以及通过收集经验值升级的机制。
僵尸创造
就游戏系统而言,我认为僵尸会存活一段时间,所以我觉得需要做的就是随着时间推移增加僵尸的出现数量。
因此,我准备了两种生成方式。
① 每隔一段时间出现一个(短时)
② 每隔一段时间出现大量(波浪式)
① 是游戏初期武器等级较低时,更容易逐步获得经验值的画面;
② 是游戏初期遇到大量敌人时,一边逃跑一边提升武器等级的画面,以及武器等级提升并进入屠杀模式时所获得的快感。
这两个事件都应该发生在距离玩家位置一定距离处。
此外,使用协程来处理等待特定时间段的情况。
逐个生成的过程如下:
private IEnumerator spawnBase() { const int MAX_BASE_ENEMYS = 50; const float spawnRadiusMin = 8.0f; const float spawnRadiusMax = 10.0f; const float spawnInterval = 1f; var waitTime = new WaitForSeconds(spawnInterval); while(true) { // 生成敌人,确保敌人数量始终为 MAX if(enemies.Count < MAX_BASE_ENEMYS) { // 玩家位置 Vector2 playerPos = playerController.GetPlayer().Position; // 确定放置半径 float r = UnityEngine.Random.Range(spawnRadiusMin, spawnRadiusMax); // 确定放置角度 float angle = UnityEngine.Random.Range(0, 360); // 生成 spawn(playerPos, r, angle); } yield return waitTime; } else { yield return null; } }
- 每秒生成一次
- 最多生成 50 个
- 距离玩家 8.0 到 10.0
- 与玩家呈 0.0 到 360.0 之间的随机角度 -
使用生成函数实例化 它们
将以这种方式生成。
波(②)的基本实现与①相同。
坐标、角度和生成过程会根据生成的僵尸数量重复进行。
生成的僵尸数量逐渐增加,第二次出现的次数多于第一次出现的次数。
以上仅摘录了这部分内容。
// 确定每波敌人的生成数量(最多 100 个) float spawnNum = Mathf.Min(wave * 10, MaxSpawnNum); // 等距放置 float angleRange = 360 / spawnNum; // 玩家位置 Vector2 playerPos = playerController.GetPlayer().Position; // 生成 for(int i = 0; i < spawnNum; i++) { // 确定放置半径 float r = spawnRadiusMax + UnityEngine.Random.Range(-1.0f, 1.0f); // 确定放置角度 float angle = angleRange * i; // 生成 spawn(playerPos, r, angle); }
它长这样。

僵尸运动
观察原图,我得到如下印象:
・比玩家慢
・向玩家移动
・跟踪能力低
,因此流程应该
1)找到指向玩家的向量
2)朝该方向移动一定时间
3)返回 1
。
private void walk() { // 行走 this.transform.localPosition += new Vector3(walkInfo.course.x * WalkSpeed * Time.deltaTime, walkInfo.course.y * WalkSpeed * Time.deltaTime, 0); // 更新计时器 walkInfo.timer -= Time.deltaTime; // 当计时器低于 0 时重置 if(walkInfo.timer < 0) { walkInfo.timer = walkInfo.interval; // 计时器 walkInfo.course = (walkInfo.player.Position - this.transform.localPosition).normalized; // 行走方向 } }
程序无法停止,所以你只需要每帧运行 Update() 函数即可。
它长这样。

经验值
我不确定“经验值”这个词是否准确,但它们是用来获取武器和升级的。
僵尸被击杀时会获得经验值,玩家靠近时可以收集这些经验值。
当僵尸死亡动画结束时,敌人类会通过经验控制器类生成一个经验值对象。
生成过程
public void OnAnimationEnd() { // 死亡动画结束后销毁 if (status == Status.Dead) { expController.Spawn(this.transform.localPosition); Destroy(this.gameObject); } }
该收集过程通过使用 Vector2.Distance 函数计算到玩家的距离,并将阈值范围内的物体向玩家坐标移动来实现。此过程也在协程中处理。
收集过程
private IEnumerator move() { var elapsedTime = 0f; var startPosition = transform.localPosition; while (elapsedTime < 1f) { var targetPosition = playerController.GetPosition(); elapsedTime += Time.deltaTime * MoveSpeed; transform.localPosition = Vector2.Lerp(startPosition, targetPosition, elapsedTime); yield return null; } Destroy(gameObject); }
它长这样。

武器等级界面
当积累到一定经验值后,就可以获得武器或升级。
我们在第二期中实现了每种武器的等级控制,因此我们将进行相应的调整,以便用户可以通过用户界面进行操作。

・灰色书写板:面板
・武器图标:按钮
・文本和★☆:文本
通过组合这些,您可以创造出看起来相似的东西。
这是成品
将此实现与第一个和第二个问题结合起来,它看起来会像这样。

现在看起来很像了,不是吗?
接下来
我想添加一些内容来完善它,比如玩家生命值管理
、时间限制
和磁铁
和往常一样,整个项目都已上传到 GitHub。
这篇博文包含大量源代码,如果您想查看整个项目,请点击此处。希望对您
有所帮助。BeBe
Survivor
好了,今天就到这里。
第一期内容在这里 ↓
https://beyondjapan.com/blog/2024/02/survivor/
第二期在这里 ↓
https://beyondjapan.com/blog/2024/03/survivor2/
7