计算所有现有公民的更好方法?

时间:2018-09-30 11:56:07

标签: c# unity3d

本着宙斯/波塞冬的精神,我已经开始制作一个简单的城市建造者游戏,但是要简单得多。我已经准备好网格系统,并且能够添加房屋和道路。昨天,我开始以一种简单的方式添加市民,即每当创建房屋时,就会创建5个人,并直接从地图的某个边缘移动到该特定房屋。一旦他们到达那所特定的房子,我就认为他们已经成为公民,并将他们添加到房子的居民列表中,也添加到城市居民的列表中。

为此,每个房屋实例都有一个“人类名单”,而我包含游戏所有信息的Game类也有一个“人类名单”。

为简化起见,如下所示:

Game.cs

public class Game {
    private static Game instance; // this is a singleton
    private int currentAmount; //this is the value I'm using to display the number of citizens on screen
    private List<Human> humen;
    public List<Human> Humen
    {
        get { return humen; }
        set
        {
            humen = value;
            currentAmount = humen != null ? humen.Count : 0;
        }
    }
    public void AddHuman(Human human)
    {
        humen.Add(human);
        currentAmount = humen.Count;
    }
    /// <summary>
    /// Private constructor to ensure it's only called when we want it
    /// </summary>
    private Game()
    {
        humen = new List<Human>();
    }


    public static void setGame(Game game)
    {
        instance = game;
    }

    /// <summary>
    /// Returns the instance, creates it first if it does not exist
    /// </summary>
    /// <returns></returns>
    public static Game getInstance() {
        if (instance == null)
            instance = new Game();
        return instance;
    }
}

House.cs

public class House : Building {
    public static int CAPACITY = 5;
    private List<Human> habitants;

    public List<Human> Habitants
    {
        get { return habitants; }
        set { habitants = value; }
    }
    public House() {
        habitants = new List<Human>();
    }
}

HumanEntity.cs

public class HumanEntity : MonoBehaviour {
    private Human human;
    private float speed;

    public Human Human
    {
        get { return human; }
        set { human = value; }
    }


    // Use this for initialization
    void Start () {
        speed = Random.Range(5.0f, 10.0f);

    }

    // Update is called once per frame
    void Update () {
        if (human != null)
        {
            Vector3 targetPosition = human.Target.GameObject.transform.position;
            if (transform.position.Equals(targetPosition)) {
                if (!human.HasAHouse)
                {
                    human.HasAHouse = true;
                    Game.getInstance().AddHuman(human); // here I'm adding the human to the list of citizens
                    ((House)human.Target).Habitants.Add(human); // here I'm adding it to the house list of habitants
                }
            }
            else {
                float step = speed * Time.deltaTime;
                transform.position = Vector3.MoveTowards(transform.position, targetPosition, step);
            }
        }
    }
}

这正在按预期进行,但是我想知道在游戏类中除了一个全局列表之外,还有一个单独的人员列表是否过大,并且是否有一种更优雅的方法来实现这取决于Game类,如果我这么说的话,也许更像是“ Unity friendly”,因为我对Unity的功能并不了解很多。您对做什么有任何建议,可以保持这种方式吗?还是有一种更优雅的方式?

2 个答案:

答案 0 :(得分:1)

了解在HumanEntity类上具有静态计数器的快速而适当的方法:

public class HumanEntity : MonoBehaviour 
{
     public static int HousedHuman { get; private set; }
     public static int HumanCount { get; private set; }

     void Awake() {  HumanCount++;  }
     void OnDestroy()
     { 
         HumanCount--; 
         if(human.HasAHouse == true){ HousedHuman--; }
     }
     public static void ResetCounter() {  HouseHuman = HumanCount = 0; }

     void Update () {
        if (human != null)
        {
            Vector3 targetPosition = human.Target.GameObject.transform.position;
            if (transform.position.Equals(targetPosition)) {
                if (!human.HasAHouse)
                {
                    HouseHuman++;    // Added
                    human.HasAHouse = true;
                    // Rest of code
                }
            }
            // Rest of code
        }
    }
}

添加新实例后,计数器增加;销毁实例时,计数器减少。

您可以通过HumanEntity.HumanCount访问。除了在HumanEntity类中,您将无法在其他地方进行设置。

在开始/离开场景时,请务必重置计数器。

编辑:基于评论,我为HousedHuman添加了第二个静态计数器。当实体到达房屋时,这会增加。如果放置了实体,则销毁该实体时,它会减少。必要时,它也会与整个计数器一起重置。

答案 1 :(得分:1)

基于Everts的想法...

游戏:

public class Game {
    private static Game instance; // this is a singleton
    public static int currentAmount { get; set; }

    //rest of class
}

房子:

public class House : Building {
    public static int CAPACITY = 5;
    private List<Human> habitants;

    public List<Human> Habitants
    {
        get { return habitants; }
        set { habitants = value; }
    }
    public House() {
        habitants = new List<Human>();
    }
    public void AddHuman(Human human)
    {
        human.HasAHouse = true;
        habitants.Add(human);
        Game.currentAmount++;
    }
}

UpdateLoop:

// Update is called once per frame
void Update () {
    if (human != null)
    {
        Vector3 targetPosition = human.Target.GameObject.transform.position;
        if (transform.position.Equals(targetPosition)) {
            if (!human.HasAHouse)
                ((House)human.Target).AddHuman(human);
        }
        else {
            float step = speed * Time.deltaTime;
            transform.position = Vector3.MoveTowards(transform.position, targetPosition, step);
        }
    }
}

如果需要检查房屋的容纳量,则可以将AddHuman方法更改为bool返回类型,在内部进行容量检查并返回是否已成功添加。

您还可以添加一个RemoveHuman方法,该方法将通过Game.currentAmount-;

至于Game中的列表,它实际上取决于上下文。如果需要此行为,则“游戏”类中的“列表”可能有助于区分流浪的人和被安置的人。 (在“游戏”列表中徘徊的人类,在该列表中被容纳)