【问题标题】:Unity: Enemy Spawn / Health SystemUnity: Enemy Spawn / 健康系统
【发布时间】:2015-07-28 12:50:53
【问题描述】:

我正在研究一个敌人生成系统。这是我的代码:

using UnityEngine;
using System.Collections;
using System.Collections.Generic;


public class EnemyManager : MonoBehaviour
{
 public GameObject shark;                // prefab von Shark
 public GameObject instanceShark;        // globale Instanzvariable von Shark
 public Transform[] spawnPoints;         // An array of the spawn points this enemy can spawn from.
 public float spawnTime = 3f;            // How long between each spawn.
 public int maximumSharks = 2;
 private int currentSharks;
 public int healthShark; // current Health von Shark
 public int startinghealthShark = 200;
 public float sinkSpeed = 2.5f;
 bool isDead;

 void Start ()
 {
     healthShark = startinghealthShark;
     currentSharks = 0;
 }


     void Update ()
 {
     if (currentSharks <= maximumSharks) {
         InvokeRepeating ("Spawn", spawnTime, spawnTime);
     }
     Debug.Log (currentSharks);    
 }


 void Spawn ()
 {    
     // Find a random index between zero and one less than the number of spawn points.
     int spawnPointIndex = Random.Range (0, spawnPoints.Length);

     // Create an instance of the enemy prefab at the randomly selected spawn point's position and rotation.
     instanceShark = Instantiate (shark, spawnPoints[spawnPointIndex].position, spawnPoints[spawnPointIndex].rotation) as GameObject;

     currentSharks++;
     if (currentSharks >= maximumSharks) {
         CancelInvoke("Spawn");
     }
 }

 public void AddDamageToShark (int neuDamageWert) // Addiere zu damage. Public function, können andre scripts auch aufrufen
 {
     // If the enemy is dead...
     if(isDead)
         // ... no need to take damage so exit the function.
         return;

     healthShark -= neuDamageWert;

     if (healthShark <= 0) {  //tot
         Death ();
     }
     Debug.Log (healthShark);
 }

 void Death ()
 {

     // The enemy is dead.
     isDead = true;
     currentSharks--;
     Destroy (instanceShark);
     Debug.Log ("dead?");    
     return;
 }

我想要的:只要没有达到最大数量就产生敌人(这部分到目前为止有效)并摧毁被射击的敌人并重生另一个(不起作用)。

此代码目前会创建 2 条鲨鱼作为敌人。问题是当我损坏一个时,即使我向第一条鲨鱼开枪,也只有最后一个创建的实例被破坏。另一个实例和新生成实例的运行状况也完全不受影响。

我很感激任何建议,我在这段代码上花了很长时间,似乎我需要一些关于实例的帮助 - 健康逻辑。

非常感谢

【问题讨论】:

    标签: c# unity3d unityscript


    【解决方案1】:

    拆分您的生成管理器行为和您的敌人行为,并使用interfaces 以更可靠的方式组织您的代码。让您的对象只负责一个范围(现在您的 SpawnManager 目前负责敌人的行为/责任)

    SpawnManager 应该是一个 singleton 对象,只有一个职责是“管理敌人的生成”,一个 maximunEnemyCount 和一个 currentEnemyCount。当您的currentEnemyCount &lt; maximunEnemyCount 时,您始终可以生成。

    OnTakeDamage()OnDeath() 应该是你的敌人行为的接口(在与 SpawnManager 分开的脚本中,假设 EnemyBehaviour 脚本)并且你的销毁应该只针对它自己的实例 Destroy(this.gameObject)

    记得在敌人死亡时通知 SpawnManager 使用 OnDeath 方法调整enemyCurrentCount。

    我认为这是一种更优雅的方式来完成这项任务,并且不太容易受到管理敌人实例的错误的影响。

    已编辑: 我之前忘记的链接单例引用

    你需要一个独特的游戏对象作为管理者,它应该知道有多少敌人可以存活以及有多少人活着,而不是关于敌人的更多信息(在这种情况下,敌人的健康是敌人对象的责任)。

    每个敌人都需要知道他/她何时死亡,因此通知经理减少其计数器。

    【讨论】:

    • 抱歉,我试图为 SOLID 找到一个好的参考,但找不到一个好的参考,因此如果您不了解此模式,请自行研究。
    • 我同意@Frohilch。你必须分开逻辑。它将使事情变得更高效,更易于管理和维护。作为程序员,以逻辑方式组织代码非常重要。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-21
    • 2023-01-15
    • 1970-01-01
    • 1970-01-01
    • 2017-03-14
    相关资源
    最近更新 更多