c# - 遍历 List 以检查 ScriptableObject 中的 bool 是否为真
问题描述
我有一个字符 Scriptable Object 'Character',它有一个 bool IsMale。我还有一个“团队”脚本对象,它有一个字符脚本对象类中的字符列表。现在,我想在 Team Class 中创建一个自定义方法,用于循环遍历此列表并检查有多少角色是男性,有多少不是。
字符.cs
using UnityEngine;
// Personal Attributes
public string firstName;
public string middleName;
public string lastName;
public string fullName;
public bool isMale;
团队.cs
using UnityEngine;
public List<Character> characters;
// For adding ten players.
public void AddPlayer(Character p1, p2, p3, p4, p5, p6, p7, p8, p9, p10)
{
characters.Add(p1);
characters.Add(p2);
characters.Add(p3);
characters.Add(p4);
characters.Add(p5);
characters.Add(p6);
characters.Add(p7);
characters.Add(p8);
characters.Add(p9);
characters.Add(p10);
}
// I want to loop through these ten characters in the list and tell how many are males and how many are not
同样,我想在 Team Class 中创建一个自定义方法,用于循环遍历此列表并检查有多少角色是男性,有多少不是。
对于@derHugo Character.cs 评论中的问题
using UnityEngine;
using System;
[CreateAssetMenu()]
public class Character : ScriptableObject
{
// Personal Attributes
public string firstName;
public string middleName;
public string lastName;
public string fullName;
public bool isMale;
private int age;
public int personalMoney;
public Sprite image;
// Game Attributes
public int totalRuns;
public int salary;
public enum characterTypes { PlayerCharacter, Manager, Player, Staff };
public characterTypes characterType;
public enum battingHands { LeftHanded, RightHanded };
public battingHands battingHand;
public enum bowlingHands { LeftHanded, RightHanded };
public bowlingHands bowlingHand;
public enum battingMentalities { Aggressive, Balanced, Defensive };
public battingMentalities battingMentality;
public enum bowlingMentalities { Aggressive, Balanced, Defensive };
public bowlingMentalities bowlingMentality;
// Skills
// Technical Skills
public int technical; // Overall Technical
public int judgement; // Batting
public int agility; // Running, Low means if player accidentaly falls down, the time he will take to get back up
public int cardioFitness; // Injury
public int muscleFitness; // Injury and Hitting Power
public int runSpeed; // Running
public int strength; // Hitting Power
// Methods
// Personal Attributes Methods
public void CalculateAge(DateTime dateOfBirth)
{
age = 0;
age = DateTime.Now.Year - dateOfBirth.Year;
if (DateTime.Now.DayOfYear < dateOfBirth.DayOfYear)
age = age - 1;
}
// Starting Game Methods Required
public void SetCharacterType(characterTypes cT)
{
Debug.Log("Setting Character Type for " + fullName);
cT = characterType;
if (cT == characterTypes.PlayerCharacter)
{
Debug.Log(fullName + " is a Player Character");
}
else if (cT == characterTypes.Manager)
{
Debug.Log(fullName + " is a Manager");
}
else if (cT == characterTypes.Player)
{
Debug.Log(fullName + " is a Player");
}
else if (cT == characterTypes.Staff)
{
Debug.Log(fullName + " is a Staff");
}
else
{
Debug.Log("No Character Type");
}
}
public void TechnicalAverage()
{
technical = (judgement + agility + cardioFitness + muscleFitness + runSpeed + strength / 600) * 100;
}
}
解决方案
例如,您可以为此使用Linq Count(我宁愿在这里使用属性,但您也可以使用方法来做同样的事情。):
using System.Linq;
public int Males
{
get
{
return characters != null ? characters.Count(c => c.isMale) : 0;
}
}
public int Females
{
get
{
return characters != null ? characters.Count(c => !c.isMale) : 0;
}
}
您只需使用该值,例如
Debug.LogFormat(this, "Males: {0}, Females: {1}", Males, Females);
提示:即使 Unity Inspector 自动初始化List
和数组字段,您也应该始终将其与定义一起执行,例如
public List<Character> characters = new List<Character>(10);
只是为了确保它null
在调用时永远不会发生Add
,并确保将默认容量设置为您期望 List 稍后作为 Count 具有的容量。
或者你也可以使用
Character[] characters = new Character[10];
因为无论如何您都不希望大小是动态的。(但请注意,Unity 中的 Inspector 始终会覆盖这些定义)
这样做更好的原因:List
无论如何,在后台将它的值存储在一个数组中。通过每次使用它添加元素来Add
检查数组是否仍然足够大,如果没有则将其扩展为双倍大小(参见此处)
public void AddPlayer(Character p1, p2, p3, p4, p5, p6, p7, p8, p9, p10)
{
characters.Add(p1); // characters has now capacity 4
characters.Add(p2);
characters.Add(p3);
characters.Add(p4);
characters.Add(p5); // characters reallocated and has now capacity 8
characters.Add(p6);
characters.Add(p7);
characters.Add(p8);
characters.Add(p9); // characters reallocated and has now capacity 16
characters.Add(p10);
}
所以你看到使用Add
10 或 11 次总是分配比实际需要更多的内存。
我会做
// hide because if you do it via the method you probably don't
// want to add items via Inspector which would get overwritten later anyway
[HideInInspector] public Character[] characters = new Character[10];
public void AddPlayer(Character p1, p2, p3, p4, p5, p6, p7, p8, p9, p10)
{
characters[0] = p1;
characters[1] = p2;
characters[2] = p3;
characters[3] = p4;
characters[4] = p5;
characters[5] = p6;
characters[6] = p7;
characters[7] = p8;
characters[8] = p9;
characters[9] = p10;
}
除此之外,您访问或更改数组或列表中的值的方式没有太大区别。
要为每个字符设置所需的所有值,您可以/应该使用适当的构造函数(不过我会更改命名):
[Serializable]
public class Character
{
// Personal Attributes
public string firstName;
public string middleName;
public string lastName;
public string fullName;
public bool isMale;
public Character(string _firstName, string _middleName, string _lastName, bool _isMale)
{
firstName = _firstName;
middleName = _middleName;
lastName = _lastName;
fullName = string.Format("{0} {1} {2}", firstName, middleName, lastName);
isMale = _isMale;
}
}
推荐阅读
- java - 使用 Java lambda 或流将 POJO 列表转换为其 ID 列表
- bash - 重命名从 PDF 文件的 csv 列表创建的目录
- python - TensorFlow 的 map_fn 只在 CPU 上运行
- web-applications - 如何在 splitwise 中获取 ACCESS_TOKEN
- mysql - SQL 插入不起作用
- node.js - 如何使用单个代码库为桌面、Web 和移动设备创建 node.js 应用程序?
- c# - 使用 Xamarin 进行 FireBase 身份验证
- android - 使用 android volley(POST 方法)时出现此错误:java.net.ConnectException:无法连接到 /192.168.0.2:4000
- eclipse - Git:如何在 git log --pretty=format... 中包含工作树状态?
- java - ScenicView Javafx java.lang.UnsatisfiedLinkError