#c# #unity3d
Вопрос:
Вот как я собираюсь это сделать:
if(transform.localScale.x > 7)
{
for(int i = 7; i > 1; i--)
{
transform.localScale -= new Vector3(1, 1, 1) * Time.deltaTime;
}
}
else
{
transform.localScale = new Vector3(1, 1, 1) * Time.deltaTime;
}
Оператор else выполняется для увеличения масштаба, и когда он достигает 7, оператор if должен уменьшить его обратно до 1 благодаря циклу for, который должен выполняться в течение 6 итераций и уменьшать масштаб в 6 раз. Но только часть else работает должным образом, когда масштаб достигает 7, он просто уменьшается до 6, а затем возвращается к 7 через секунду. Он не доходит до 1.
Ответ №1:
Вы знаете, что весь ваш for
цикл будет выполняться немедленно в пределах одного кадра? и вы умножаете это на Time.deltaTime
то, что при условии, что 60 кадров в секунду будет значением около 0.0166666666...
.
Итак, то, что вы делаете в цикле, в основном просто равносильно выполнению
transform.localScale -= Vector3.one * 6 * 0.017f;
Прямо в следующем кадре вы можете снова оказаться ниже, чем 7
=> вы попадаете в else
дело и снова увеличиваете масштаб.
Поэтому в следующем кадре он уже снова уменьшит его и т. Д
Насколько я понимаю, вам скорее нужен эффект пин-понга между двумя масштабами.
Я бы предпочел использовать что-то вроде
// adjust via the Inspector
public float speed = 1;
public float amplitude = 7f;
private Vector3 originalScale;
private float timePassed;
private void Start()
{
originalScale = transform.localScale;
}
private void Update()
{
timePassed = Time.deltaTime * speed;
// see https://docs.unity3d.com/ScriptReference/Mathf.PingPong.html
transform.localScale = originalScale * (1 Mathf.PingPong(timePassed, amplitude - 1));
// or with ease-in and ease-out
//transform.localScale = originalScale * (1 (amplitude - 1) * Mathf.SmoothStep(0, 1, Mathf.PingPong(timePassed, 1)));
}
Где Mathf.PingPong
возвращает значение, которое будет увеличиваться и уменьшаться между значением 0 и длиной.
Или, если вам действительно нужно другое увеличение и уменьшение продолжительности, я бы предпочел предложить сопрограмму типа
// adjust via the Inspector
public float increaseDuration = 1f;
public float decreaseDuration = 7f;
public float amplitude = 7f;
private IEnuemerator Start()
{
var originalScale = transform.localScale;
var maxScale = originalScale * amplitude;
while(true)
{
for(var timePassed = 0f; timePassed < increaseDuration; timePassed = Time.deltaTime)
{
var factor = timePassed / increaseDuration;
// optinal add ease-in and ease-out
//factor = Mathf.SmoothStep(0, 1, factor);
transform.localScale = Vector3.Lerp(originalScale, maxScale, factor);
yield return null;
}
for(var timePassed = 0f; timePassed < decreaseDuration; timePassed = Time.deltaTime)
{
var factor = timePassed / decreaseDuration;
// optinal add ease-in and ease-out
//factor = Mathf.SmoothStep(0, 1, factor);
transform.localScale = Vector3.Lerp(maxScale, originalScale, factor);
yield return null;
}
}
}
Ответ №2:
Вы можете создать другую переменную, например:
public bool isDecreasing=false;
if(!isDecreasing amp;amp; transform.localScale.x > 7)
{
isDecreasing=true
}else if(isDecreasingamp;amp;transform.localScale.x==1)
{
isDecreasing=false
}
if(isDecreasing)
{
transform.localScale -= new Vector3(1, 1, 1) * Time.deltaTime;
}else
{
transform.localScale = new Vector3(1, 1, 1) * Time.deltaTime;
}
Комментарии:
1. Это все равно будет выполнять весь цикл в одном кадре, хотя, скорее всего, kin of в конечном итоге приведет к тому же поведению