#c# #visual-studio #unity3d
#c# #visual-studio #unity3d
Вопрос:
У меня есть объект character Scriptable ‘Character’, и у него есть bool isMale. У меня также есть объект ‘Team’ с возможностью создания сценариев, и в нем есть список символов из класса объектов Character Scriptable. Теперь я хочу создать пользовательский метод в классе Team для циклического просмотра этого списка и проверить, сколько персонажей мужского пола, а сколько нет.
Персонаж.cs
using UnityEngine;
// Personal Attributes
public string firstName;
public string middleName;
public string lastName;
public string fullName;
public bool isMale;
Team.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 для выполнения цикла по этому списку и проверить, сколько символов мужского пола, а сколько нет.
По вопросам в комментариях @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;
}
}
Комментарии:
1. На вашем месте я бы изменил
AddPlayer(Character p1, p2, p3, p4, p5, p6, p7, p8, p9, p10)
наAddPlayer(Character p)
. Затем добавьте их по-разному, а также сохраните счетчик для мужчин / женщин и проверяйте каждый раз, когда я добавляю символ и увеличиваю счетчик для мужского или женского пола. Тогда вам не нужно выполнять цикл по списку каждый раз, когда вам нужна эта информация.2. @AliKanat может быть, он хочет быть уверенным, что он всегда вызывается ровно из 10 символов
3. @derHugo Да, на самом деле это имеет смысл. Спасибо, что указали на это.
4. Я делаю игру в крикет. Вот почему я добавил 10 игроков (я знаю, что там 11 игроков, но это только для целей тестирования). Я хочу убедиться, что игроки добавлены. Обязательно. Мне тоже 15 лет, и я тоже новичок в Unity. Это также может быть причиной такого дилетантства.
5. в качестве альтернативы вы могли бы использовать
Character[] characters = new Character[10];
, так как вы не хотите, чтобы размер был динамическим
Ответ №1:
Для этого вы можете, например, использовать 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 автоматически инициализирует List
поля и массив, вы всегда должны делать это вместе с определением типа
public List<Character> characters = new List<Character>(10);
просто чтобы убедиться, что это никогда не происходит null
при вызове Add
, и убедитесь, что вы установили емкость по умолчанию на то, что вы ожидаете, что список будет учитываться позже.
Или, в качестве альтернативы, вы могли бы использовать
Character[] characters = new Character[10];
поскольку вы все равно не хотите, чтобы размер был динамическим. (Обратите внимание, однако, что инспектор в Unity всегда переопределяет эти определения)
Причина, по которой это лучше: 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;
}
}
Комментарии:
1. Спасибо за
public List<Character> characters = new List<Character>();
код. Теперь я могу легко использовать инспектор, чтобы добавить всех игроков в список. Делает жизнь намного проще ;).2. но имейте в виду, что инспектор не привязан к ограничениям размера массива или списка;) И это будет работать, только если
Character
указано как[Serializable]
3. Ухх. Unity никогда не устаревает.
4. В любом случае. Я не думаю, что в какой-либо команде по крикету в истории было 1 00 000 игроков. Итак, я определенно могу преодолеть ограничения по размеру ;).
5. @SwastikBhattacharyya да, это просто крошечные детали 😉 вот почему я поместил это только как
Hint
.