#c# #unity3d
Вопрос:
Я чувствую, что мне не хватает какого-то простого решения, но я застрял на этом. Я рассчитываю балл, основанный на том, как далеко игрок проходит, пока не попадет в здание в конце курса. Оценка разрушения отделена от оценки расстояния, и она увеличивается до тех пор, пока все части здания не остановятся.
У меня есть анимация, которую я хочу воспроизвести, чтобы добавить показатель расстояния к общему показателю уничтожения и дать общий балл игрока, но мне нужно, чтобы анимация сработала, как только показатель уничтожения перестанет увеличиваться. Прямо сейчас у каждой части здания есть код, который проверяет, движется ли она, и увеличивает счет, если это правда.
public class SkiLodgeScoreTracker : MonoBehaviour
{
Rigidbody rb;
private GameObject[] score;
private void Start()
{
rb = gameObject.GetComponent<Rigidbody>();
score = GameObject.FindGameObjectsWithTag("Score");
}
private void Update()
{
//check if lodgePiece is moving, while it is, add to Score object
if(rb.velocity.magnitude >= 2f amp;amp; !rb.isKinematic)
{
score[0].GetComponent<SkiScore>().addToSkiScore(2f);
}
}
}
Вот где я хочу, чтобы анимация сработала, как только эта оценка остановится (это была еще одна попытка, которую я предпринял, логика не работает).
public Animator moveScore;
...
if(skiScore > 0)
{
previousScore2 = previousScore1;
previousScore1 = skiScore;
if(previousScore1 == previousScore2 amp;amp; !scoreMoved)
{
moveScore.SetTrigger("EndCourse");
addScoreToSkiScore();
}
}
public void addScoreToSkiScore()
{
scoreMoved = true;
for(float i = score; i>0; i--)
{
skiScore = 1;
}
}
Я хотел получить оценку за один кадр и посмотреть, равна ли она оценке за следующий кадр, и если да, то запустить анимацию, но я чувствую, что это недопустимый вариант.
Есть какие-нибудь идеи?
Комментарии:
1. Возможно, вы предпочли бы использовать события анимации и не проверять, изменилось ли значение, но закончилась ли анимация
Ответ №1:
В SkiScore
, следите за тем, сколько фигур движется, и когда фигура останавливается и количество становится равным 0, делайте свое дело:
public class SkiScore : MonoBehaviour
{
int movingCount;
void Start()
{
ResetMovingCount();
/* ... */
}
public void ResetMovingCount() {movingCount = 0;} // call as needed
public void OnStartedMoving() { movingCount;}
public void OnStoppedMoving()
{
if (--movingCount == 0) OnNoneMoving();
}
void OnNoneMoving() {/* do the thing */}
/* ... */
}
Для каждой фигуры используйте флажок, чтобы запомнить, перемещалась ли она недавно, и если она переместилась, но больше не перемещается, сообщите об этом своему менеджеру по подсчету очков:
public class SkiLodgeScoreTracker : MonoBehaviour
{
Rigidbody rb;
private GameObject[] score;
// flag used to recognize newly stopped movement
bool recentlyMoving;
// cache for GetComponent
SkiScore mySkiScore
private void Start()
{
rb = gameObject.GetComponent<Rigidbody>();
score = GameObject.FindGameObjectsWithTag("Score");
// GetComponent is expensive, try not to call it in Update unless necessary
mySkiScore = score[0].GetComponent<SkiScore>();
}
private void Update()
{
//check if lodgePiece is moving, while it is, add to Score object
if(rb.velocity.magnitude >= 2f amp;amp; !rb.isKinematic)
{
mySkiScore.addToSkiScore(2f);
recentlyMoving = true;
mySkiScore.OnStartedMoving();
}
else if (recentlyMoving)
{
recentlyMoving = false;
mySkiScore.OnStoppedMoving();
}
}
}
Комментарии:
1. Это хорошая идея, но этот сценарий прикреплен к каждой части ложи. Как ты думаешь, я мог бы просто проверить, не является ли каждое недавнее перемещение фрагмента ложным?
2. @getALoadOfThisGuy Я отредактировал ответ, чтобы учесть это. Дайте мне знать, если это не имеет смысла, и я могу попытаться уточнить. Кстати, красивое имя.
3. Это прекрасно! Спасибо вам и спасибо за совет по поводу GetComponent<>(). Я все еще изучаю единство и оптимизацию, и это очень полезно.