- Home /
Scale Object Using Lerp?
Hi,
So I've written a simple code (based on a Unity tutorial) that uses raycasting, and when you hit an object with a ray (with the tag "Pick Up") it grows. When you look away, it shrinks. However, I want to make the growing/shrinking a smooth transition, not instant. Should I use lerp? The object I'm scaling has an original size of (.5, .5, .5). (I'm a beginner, sorry if this is straightforward)
Thanks for the help!
Here is the code:
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class Raycast : MonoBehaviour {
public Text NameText;
void Start ()
{
}
void Update () {
Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);
Debug.DrawRay (ray.origin, ray.direction * 10, Color.green);
RaycastHit hit;
if (Physics.Raycast (ray, out hit) == true)
{
Debug.DrawRay (ray.origin, ray.direction * hit.distance, Color.red);
NameText.text = ("Ray hit: " + hit.transform.gameObject.name);
if (hit.collider.gameObject.CompareTag("Pick Up"))
{
Debug.DrawRay (ray.origin, ray.direction * hit.distance, Color.cyan);
//here is where I wan't to add the growing/shrinking
hit.transform.localScale = new Vector3(1F, 1F, 1F);
}
}
}
}
Give it a try. Is it what you want? Try also $$anonymous$$oveTowards.
Answer by bogartrye · Jun 17, 2015 at 10:17 PM
You can achieve this effect through Lerp, but it's not a necessity; there are plenty of ways to do this. This is how I would do it:
// Put this part at the top where you have NameText
float scale = 0.5f;
float minScale = 0.5f;
float maxScale = 1.0f;
float scaleSpeed = 0.5f;
// Put this part inside Update where you want it to grow
// Grow
scale += scaleSpeed * Time.deltaTime;
// Limit the growth
if (scale > maxScale) {
scale = maxScale;
}
// Apply the new scale
hit.transform.localScale = new Vector3(scale, scale, scale);
To do the shrinking, you'd need to subtract from the scale, make sure it doesn't go below minScale, and re-apply it to the object.
wait, when I use this it only works on the first gameObject I attempt to grow. The rest grow/shrink instantly, just like before. Is it because the float value of scale has already been set by then? Thank you so much for the help!
EDIT:
never$$anonymous$$d, I figured it out! I added a section where it says if the ray is not hitting something, then reset SCALE to 0.5f. That way, by the time you reach another object, SCALE is reset!
The updated code works wonderfully! Thank you so much! :)
If you're reusing the scale variable for other object's scales, whenever one grows, the others' scales will grow as well (because you're changing a variable all objects are referring to). It may appear to happen instantly if you only apply the new scale to the object when you're pointing at them. For example, you have 2 cubes and 1 scale variable. When you set cube 1 to grow, scale goes from 0.5 to 1. Then you try and scale cube 2, which is originally is scaled to 0.5 but your scale variable has now been set to 1 as a result of scaling cube 1. So the next frame, cube 2 jumps from 0.5 to 1.
One way to solve this is to have a new scale variable for each object that you want to scale. This is impractical though, especially if you don't know how many objects you need to scale. So ins$$anonymous$$d, i would fetch the current scale of the object just before growing it and get rid of the scale variable at the top of your script. Insert the line: float scale = hit.transform.localScale.x; just above where you increment the scale. Hope this helps.
Answer by Tekksin · Jun 17, 2015 at 11:00 PM
Warning, incoming javascript:
You can use the animator for something like this. This way you can get some interesting squash and stretch with your animation, easily.
Set up your animation (research how to or ask me if you want to know a very lengthy step by step on how to do it), and then in the script just do this:
private var anim : Animator;
function Start(){
//if the script is on the scale object
anim = GetComponent(Animator);
//if the script is not on the scale object
anim = GameObject.Find("theScaleObject").GetComponent(Animator);
}
function Update(){
if(rayCastHit)
Grow(true);
}
function Grow(grow : boolean){
if(grow)
anim.SetBool("Grow", true);
yield;
anim.SetBool("Grow", false);
}
alternatively, I think you can bypass the expensive raycasting by making a script on the object you want to scale, and just doing something like:
private var anim : Animator;
function OnMouseDown(){
anim.SetBool("Grow", true);
yield;
anim.SetBool("Grow", false);
}
disclaimer: I write in java. Replace function with void, and deal with C#'s annoying Coroutines lol, I'm sure you're used to them. I think you have to do something like 'yield return new;' instead of just yield.
But yeah, that's how I'd do scaling of an object. Unity's animator offers a lot of flexibility and you don't have to worry about fps. And it won't look static and boring as it would with simple coding, lerped or not.
Your answer
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
How to Scale an object up and down over time? 5 Answers
C# - Mathf.Lerp: NullReferenceException: Object reference not set 1 Answer
how to use time on lerp 2 Answers