本着宙斯/波塞冬的精神,我已经开始制作一个简单的城市建造者游戏,但是要简单得多。我已经准备好网格系统,并且能够添加房屋和道路。昨天,我开始以一种简单的方式添加市民,即每当创建房屋时,就会创建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的功能并不了解很多。您对做什么有任何建议,可以保持这种方式吗?还是有一种更优雅的方式?
答案 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中的列表,它实际上取决于上下文。如果需要此行为,则“游戏”类中的“列表”可能有助于区分流浪的人和被安置的人。 (在“游戏”列表中徘徊的人类,在该列表中被容纳)