- Home /
How to scale an object to a certain size over a certain period of time(in seconds lets say)
So i've been trying to figure out what equation i need to use to be able to achieve what is mentioned in the post title. first i tried something like:
gameObject.transform.localScale += (new Vector3(0.1f, 0f, 0.1f) * (-gameObject.transform.localScale.x * Time.deltaTime))/10;
which didnt work. I then tried:
gameObject.transform.localScale = Vector3.Lerp (transform.localScale, new Vector3(5f,5f,5f), 10f * Time.deltaTime);
which also didnt quite work :( can anyone tell me what im missing?
Answer by Eno-Khaon · Sep 18, 2021 at 04:00 AM
Using Time.deltaTime as part of the "time" (namely, "t") argument in Linear Interpolation is almost always a terrible idea, and I never understand why it's done so frequently. Essentially, it removes the "Linear" element and makes it state/luck-dependent on exactly how it plays out without being able to reach its goal.
If you want an "animated" Lerp() function to play out, well, linearly, you'll want a fixed start and end point, with a "t" value that ranges from 0-1 over a given length of time.
// This example is based around multiplication for more efficient math
private float fScaleTime;
public float scaleTime
{
get
{
if(fScaleTime == 0f)
{
return 0f;
}
else
{
return 1.0f / fScaleTime;
}
}
set
{
if(value == 0f)
{
fScaleTime = 0f;
}
else
{
fScaleTime = 1.0f / value;
}
}
}
// An editor-facing initial value, since the property would be hidden in the Inspector
[SerializeField]
private float initialScaleTime = 5.0f;
public Vector3 startingScale = Vector3.one * 0.1f;
public Vector3 endingScale = Vector3.one * 5.0f;
private float lerpT = 0f;
void Start()
{
// Set the property to the Inspector value
scaleTime = initialScaleTime;
// Redundant in Start() in this case, but included for general context
lerpT = 0f;
}
void Update()
{
// Simple example, no conditions involved for this
transform.localScale = Vector3.Lerp(startingScale, endingScale, lerpT * fScaleTime);
lerpT += Time.deltaTime;
}
Edit: Fixed an obvious typo
I haven't used get/set in a long time in C# and i happen to get some errors im a little confused about. my full code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Zone : MonoBehaviour
{
ZoneStuff zoneStuff;
bool canReplace = true;
// An editor-facing initial value, since the property would be hidden in the Inspector
[SerializeField]
private float initialScaleTime = 5.0f;
public Vector3 startingScale = Vector3.one * 0.1f;
public Vector3 endingScale = Vector3.one * 5.0f;
private float lerpT = 0f;
private float fScaleTime;
public float scaleTime
{
get
{
if(fScaleTime == 0f)
{
return 0f;
}
else
{
return 1.0f / fScaleTime;
{
}
set
{
if(value == 0f)
{
fScaleTime = 0f;
}
else
{
fScaleTime = 1.0f / value;
}
}
}
void Awake()
{
zoneStuff = GameObject.Find("GameManager").GetComponent<ZoneStuff>();
}
// Start is called before the first frame update
void Start()
{
// Set the property to the Inspector value
scaleTime = initialScaleTime;
// Redundant in Start() in this case, but included for general context
lerpT = 0f;
}
// Update is called once per frame
void Update()
{
// Simple example, no conditions involved for this
transform.localScale = Vector3.Lerp(startingScale, endingScale, lerpT * fScaleTime);
lerpT += Time.deltaTime;
}
void OnTriggerEnter(Collider other)
{
if(other.gameObject.tag == "Zone")
{
if(canReplace)
{
canReplace = false;
zoneStuff.ReplaceZone(this.gameObject);
}
}
}
}
errors: line 32, CS1002: ; expected line 45, CS1513: } expected
Whoops, I made a typo, and put a second starting brace ({) where there should have been an ending brace (}).
This is a pretty good reason to not blindly copy/paste code.
Your answer
