#c# #unity3d
Вопрос:
Я получаю предупреждение о производительности от своей среды разработки о том, что вызов GetComponent() является дорогостоящим, особенно с учетом того, что я вызываю MoveCards() в Update(). Я понимаю, почему это дорого, и обычно знаю, как исправить кэширование в Awake (), но поскольку оно имеет префикс[i], я не уверен, как это сделать.
private void MoveCards()
{
// This loop moves the cards.
for (var i = 0; i < cards.Length; i )
{
cards[i].localPosition = Vector3.Lerp(cards[i].localPosition, cardPositions[i cardArrayOffset],
Time.deltaTime * cardMoveSpeed);
if (!(Mathf.Abs(cards[i].localPosition.x - cardPositions[i cardArrayOffset].x) < 0.01f)) continue;
cards[i].localPosition = cardPositions[i cardArrayOffset];
// This disables interaction with cards that are not on top of the stack.
cards[i].gameObject.GetComponent<CanvasGroup>().interactable = cards[i].localPosition.x == 0;
}
}
Комментарии:
1. Вы можете хранить ссылки в словаре и захватывать группу canvas по объекту. Таким образом, у вас будет <GameObject, CanvasGroup>. Чтобы расширить эту функциональность, просто измените CanvasGroup на класс и сохраните в нем несколько ссылок. Класс будет просто хранить данные и больше ничего не делать. Кроме того, почему вы используете группу canvas для одного объекта? Имеют ли карты больше взаимодействий, чем сама карта?
2. Что это за тип
cards
?3. @Ruzihm Преобразование[]
4.
cards[i].localPosition.x == 0
При сравнении поплавков лучше проводить приблизительное сравнение в случае ошибок округления.Mathf.Approximately(0f, cards[i].localPosition.x);
5. Спасибо @Ruzihm, я ценю вашу помощь.
Ответ №1:
Что бы я сделал, так это сделал так, чтобы у карточного игрового объекта было собственное монообъектное поведение для хранения ссылки на эти компоненты. Затем измените коллекцию карт, чтобы сохранить ссылку на монопод карты.
Ответ №2:
Вы бы хранили cards[]
как a CanvasGroup
вместо a GameObject
.
Вы бы объявили это так в Awake()
:
GameObject[] cardObjects = new GameObject[10];
CanvasGroup[] cards = new CanvasGroup[cardObjects.Length];
for (int i = 0; i < cardObjects.Length; i )
{
cards[i] = cardObjects[i].GetComponent<CanvasGroup>();
}
Мы перебираем все объекты карты и назначаем этот компонент определенному объекту в массиве.
В вашей функции, которую вы показали в вопросе, вы изменили бы ее на эту:
private void MoveCards()
{
for (int i = 0; i < cardObjects.Length; i )
{
cardObjects[i].transform.localPosition = Vector3.Lerp(cardObjects[i].transform.localPosition, cardPositions[i cardArrayOffset], Time.deltaTime * cardMoveSpeed);
if (!(Mathf.Abs(cardObjects[i].transform.localPosition.x - cardPositions[i cardArrayOffset].x) < 0.01f)) continue;
cardObjects[i].localPosition = cardPositions[i cardArrayOffset]
cards[i].interactable = cardObjects[i].transform.localPosition.x == 0;
}
}
Мы меняем все cards
переменные на cardObjects
. На GetComponent<>()
линии мы сохраняем cards
и удаляем .gameObject.GetComponent<CanvasGroup>()
.
Важно: Вы не показали нам, где были созданы некоторые переменные. Нравится cardPositions
. Если это создано с помощью cards
, обязательно используйте cardObjects
переменную.
Комментарии:
1. Я не думаю, что это отличный подход, так как он не очень гибкий, если вам потребуется доступ к большему количеству компонентов в будущем. В конечном итоге вы либо переработаете его, либо сделаете код очень грязным.