c# - Escalar GameObject con el tiempo
unity3d (3)
Hice un juego de prueba en la unidad que hace que cuando haga clic en un botón, genere un cilindro creado a partir de una clase de fábrica. Estoy tratando de hacerlo para que cuando cree el cilindro, su altura se reduzca en los próximos 20 segundos. Algunos métodos que encontré son difíciles de traducir a lo que estoy haciendo. Si pudieras guiarme en la dirección correcta, te lo agradecería mucho.
Aquí está mi código para la clase de cilindro
public class Cylinder : Shape
{
public Cylinder()
{
GameObject cylinder = GameObject.CreatePrimitive(PrimitiveType.Cylinder);
cylinder.transform.position = new Vector3(3, 0, 0);
cylinder.transform.localScale = new Vector3(1.0f, Random.Range(1, 2)-1*Time.deltaTime, 1.0f);
cylinder.GetComponent<MeshRenderer>().material.color = Random.ColorHSV();
Destroy(cylinder, 30.0f);
}
}
Creará un nuevo script monobehaviour y lo agregará a su primitivo. Luego usará el método "Actualizar" de monoconducta (o usará la rutina) para cambiar el objeto con el tiempo.
El monoconducto debe verse así:
public class ShrinkBehaviour : MonoBehaviour
{
bool isNeedToShrink;
Config currentConfig;
float startTime;
float totalDistance;
public void StartShrink(Config config)
{
startTime = Time.time;
currentConfig = config;
totalDistance = Vector3.Distance(currentConfig.startSize, currentConfig.destinationSize);
isNeedToShrink = true;
transform.localScale = config.startSize;
}
private void Update()
{
if (isNeedToShrink)
{
var nextSize = GetNextSize(currentConfig);
if (Vector3.Distance(nextSize, currentConfig.destinationSize) <= 0.05f)
{
isNeedToShrink = false;
return;
}
transform.localScale = nextSize;
}
}
Vector3 GetNextSize(Config config)
{
float timeCovered = (Time.time - startTime) / config.duration;
var result = Vector3.Lerp(config.startSize, config.destinationSize, timeCovered);
return result;
}
public struct Config
{
public float duration;
public Vector3 startSize;
public Vector3 destinationSize;
}
}
Para usar esto, debe hacer lo siguiente:
public Cylinder()
{
GameObject cylinder = GameObject.CreatePrimitive(PrimitiveType.Cylinder);
var shrink = cylinder.AddComponent<ShrinkBehaviour>();
shrink.StartShrink(new ShrinkBehaviour.Config() { startSize = Vector3.one * 10, destinationSize = Vector3.one * 1, duration = 20f });
cylinder.transform.position = new Vector3(3, 0, 0);
cylinder.GetComponent<MeshRenderer>().material.color = Random.ColorHSV();
Destroy(cylinder, 30.0f);
}
Debe recordar que monobehaviour-script debe estar en un archivo separado y debe tener un nombre similar al nombre de monobehaviour-class. Por ejemplo, ShrinkBehaviour.cs;
Echa un vistazo a Lerp . Un ejemplo general de cómo usarlo sería algo como esto:
float t = 0;
Update()
{
t += Time.deltaTime;
cylinder.localScale = new Vector3(1, Mathf.Lerp(2f, 1f, t/3f), 1); // shrink from 2 to 1 over 3 seconds;
}
Esto se puede hacer con
Time.deltaTime
y
Vector3.Lerp
en una función de rutina.
Similar a
Rotar GameObject con el tiempo
y
Mover GameObject con el tiempo
.
Lo modifiqué un poco para hacer esto.
bool isScaling = false;
IEnumerator scaleOverTime(Transform objectToScale, Vector3 toScale, float duration)
{
//Make sure there is only one instance of this function running
if (isScaling)
{
yield break; ///exit if this is still running
}
isScaling = true;
float counter = 0;
//Get the current scale of the object to be moved
Vector3 startScaleSize = objectToScale.localScale;
while (counter < duration)
{
counter += Time.deltaTime;
objectToScale.localScale = Vector3.Lerp(startScaleSize, toScale, counter / duration);
yield return null;
}
isScaling = false;
}
USO
Escalará GameObject en 20 segundos:
StartCoroutine(scaleOverTime(cylinder.transform, new Vector3(0, 0, 90), 20f));