- Home /
a box expands and shrinks after key pressed with a sound?
Hey fellows, just started with Unity and not finished all the manuals yet, sooo...
I'd like to create a simple scene, where a box gradually expands from nothing to a scale about 2, then shrinks in the same way to 1 and a bleep-bloop sound plays ones. It all happens after you press spacebar, for example.
I also need sound to be attached to this box, so I use audio source.
Tried create a function with "transform.localScale = Vector3.Lerp" and "audio.play" inside it, but if i call it just from Update function I get endless bleep-bloop-bleep... and if I call it from "if (Input.GetButton)" then Lerp does not works.
It seems like there is a need for a boolean which would be true after the key is pressed, so I can call sound only once and transform the scale in the update function and so on, but I believe there is much easier way and I can not find it due to lack in script commands knowledge.
excuse me for my english
#pragma strict
var height: float = 1.0;
var speed: float = 0.20;
var size: float = 1.2;
var speed2: float = 2.0;
function Start () {
transform.localScale = Vector3.zero;
}
function Update () {
if (Input.GetButtonDown("Jump")) {
ExpandMe ();
//ContractMe ();
}
}
function ExpandMe () {
yield WaitForSeconds(transform.position.y/speed2 + Random.value);
audio.Play();
transform.localScale = Vector3.Lerp (transform.localScale, Vector3.one * size, speed * Time.deltaTime);
}
function ContractMe () {
transform.localScale = Vector3.Lerp (transform.localScale, Vector3.one, speed * Time.deltaTime);
}
It would be easiest to give accurate advice if you post the code you have so far.
no problem
I just thought it would be easier to write a clear code, when you don't laugh on my senseless attempts =)
you could always make a simple scale animation in unity's animator.
because of the way that Unity takes in key commands work* calling a coroutine successively by triggering it through GetButtonDown() is dangerous. I would suggest that you start by changing to GetButtonUp() http://docs.unity3d.com/Documentation/ScriptReference/Input.GetButtonUp.html
*remember that input is taken at the beginning of the frame, and that coroutines happen interspersed throughout the frame.
Answer by robertbu · Mar 28, 2013 at 11:07 PM
Here is a rewrite of your code that expands and contracts the cube. There are other ways to approach this problem, but I tried to work within the code you've already written. Note they way you are using Lerp() results in easing of the sizing at both end. I don't know if it is what you want or not.
#pragma strict
var height: float = 1.0;
var speed: float = 0.20;
var size: float = 1.2;
var speed2: float = 2.0;
var isSizing = false;
var isExpanding = true;
var threshold = 0.1;
var v3Max = Vector3(size, size, size);
function Start () {
transform.localScale = Vector3.zero;
}
function Update () {
if (Input.GetButtonDown("Jump")) {
isSizing = true;
isExpanding = true;
}
if (isSizing) {
if (isExpanding) {
transform.localScale = Vector3.Lerp (transform.localScale, v3Max, speed * Time.deltaTime);
if (Vector3.Distance(transform.localScale, v3Max) < threshold) {
isExpanding = false;
audio.Play();
}
}
else {
transform.localScale = Vector3.Lerp (transform.localScale, Vector3.zero, speed * Time.deltaTime);
if (Vector3.Distance(transform.localScale, Vector3.zero) < threshold)
isSizing = false;
}
}
}
It seems that it would play the sound every frame while the box expands. You may say "put the audio.play into GetButton event", but I'm using yield command for a delay, depending on the Y coordinate of the box (the higher the box - the longer the delay), and want the sound to be played when the box appears. (There would be multiple boxes, triggering by one button action). - This is another reason, I'm not using animation for this, I thought it would be easier to place number of boxes in the scene with different materials and then just apply a script, than instantiate animated object and then change materials... While reading my comment again... am I kinda stupid?
Also You mentioned Lerp, I was watching again and again and it doesn't looks like it is really linear, as scripting reference says.
I edited the answer to fix the audio...missing pair of {}. No, the movement is not linear, which is why is said in my original answer "way you are using Lerp() results in easing." There are a couple of ways of changing it to be more linear. One way is to change the Vector3.Lerp() calls to Vector3.$$anonymous$$oveTo() calls. Note the Lerp() usage you have here is often used, but it is a "misuse" of Lerp() compared to how it is intended to be used.
Answer by gardian06 · Mar 29, 2013 at 03:02 PM
the only problem that I am seeing with the code you have posted is that you are using Input.GetButtonDown("Jump")
which means that the following code will not only take place when the button is pressed, but for as long as the button is held as well.
essentially based on the speed of everything that could be happening in a frame even if you just tap the key this will fire maybe 5-20 times: meaning that your coroutine will be fired 5-20 times in succession hence resulting in direct competition of priority.
If your goal is to just have the box grow to just your new size every time the button is pressed then the best option is to just switch GetButtonUp("Jump") instead of GetButtonDown("Jump") though I think you might have a different issue if your intention is to call the ExpandMe() followed by the ContractMe() this issue which I am seeing will be because of the way that coroutines are fired.
// if I was to right 2 IEnumerators (coroutines) and then call them in succession
IEnumerator Func1(){
yield return new WaitForSeconds(.01f);
Debug.Log("write this in Func1");
}
IEnumerator Func2(){
Debug.Log("write this in Func2");
yield return null;
}
void Update(){
if(input.GetButtonUp("Jump")){
StartCoroutine(Func1());
StartCoroutine(Func2());
}
}
you would notice that the output would actually be "write this in Func2" and then "write this in Func1"
so my suggestion at that point would be to move your call to ContractMe() to either the end of ExpandMe() maybe even moving the code into that function, or have ContractMe() called when a different command/action is performed.
Edit: translated to .js version as question originally posted in .js format
function Func1(){
yield WaitForSeconds(.01f);
Debug.Log("write this in Func1");
}
function Func2(){
Debug.Log("write this in Func2");
yield null;
}
function Update(){
if(input.GetButtonUp("Jump")){
Func1();
Func2();
}
}
Your answer
Follow this Question
Related Questions
Complete beginner. Where to start? 0 Answers
transform.position returning wrong value (UNITY 2D) 0 Answers
Audio clip change via script,changing audio clip in audio source via script 1 Answer
scripting problem? 1 Answer
TimeScale with AudioSource 1 Answer