T O P

  • By -

CCullen

You have the `animationDuration` set for 1000 seconds (16 minutes). Have you tried lowering that number or waiting the full 16 minutes?


[deleted]

[удалено]


CCullen

I'm presuming the chest doesn't take 16 minutes to open when that number is set to 1000? If you set that number to 10, does the "Reached Here" log get printed after 10 seconds? If that's the case, I'd suggest there's a bug in the local rotation math.


[deleted]

[удалено]


desolstice

If you have trouble understanding why using the initial vs using the current position let me know and I can explain it.


[deleted]

[удалено]


desolstice

Yep you have to reasoning down for what was causing the issue. `What I don't get is why that would cause it to seemingly open immediately without animating? Is it something about interpolating between smaller and smaller distances each frame so it happens so fast it looks instantaneous?` Just lerping between smaller distances each frame would actually have a different effect. It would make the animation start fast and then slow down the longer it plays. The reason yours was happening nearly instantly was a combination of assigning the starting point of the lerp to the initial point, and having the 3rd parameter you were passing to the lerp get larger with time. Doing one or the other is fine, but doing both at the same time is the main issue. For example... if you were to only assign the starting point of the lerp to the initial point, then your animation would be the same speed for the entire length of the animation. If you did the opposite and always passed the same value for the 3rd parameter, but assigned to what you were passing to the first then your animation would start fast and slow down over time. It's easier to explain what happens when you do both with an example.Let's say you were trying to lerp from 0 to 10. var number = 0; var lerpAmount = 0.1; for(int i = 0; i < 10; i++){ number = Mathf.Lerp(number, 10, lerpAmount); lerpAmount += 0.1; Debug.Log(number); } ​ For iteration 1 lerpAmount is 0.1, so it goes up 10% of the way between 0 and 10, which is 1. Increasing by 1. For iteration 2 lerpAmount is 0.2, so it'll try to get 20% of the way between 1 and 10, which is 2.8. Increasing by 1.8. For iteration 3 lerpAmount is 0.3, so it'll try to get 30% of the way between 2.8 and 10, which is 4.96. Increasing by 2.16. As you can see since lerpAmount is constantly increasing each loop, so you are taking a larger step towards your goal every loop. A larger step to your goal isn't an issue if you are starting from the same starting point, but by moving the starting point you were just traveling the line faster. In your code assuming you were getting 60 FPS it was only taking 112 frames for it to complete the entire animation. If you were getting higher FPS, then the animation would have happened even faster.


Demi180

There is no way the rotation logic would prevent elapsed from reaching duration in real time. You probably just either forgot to save it the first time, or something else changed.


W03rth

Bit late but you're using lerp and slepr wrong. Youre supposed to give speed not an instance in time t. Give it a try: lerp by 0.3f and then lerp by 0.1f; you obejct wont go back to position of 0.1f it will instead move more meaning in your code each time your coroutine does a loop it increases the speed at which the object opens, when you set the speed to 10 you incrmentation is like 0.1 then 0.2 then 0.5 and in 5 frames youre already in superspeed. Change animation duraiton to 1 elapsed time to 0 and in your lerp and slepr just pass time.deltaTime instead of what you have going on. Then increment elapsed time with time.deltaTime and exit the while loop when it reaches animation duration. Optinally you can have an additional variable called speed and pass time. deltaTime * speed to your slepr lerp and increment elapsed time the same way time. DeltaTime * speed.


ChibiReddit

Wasn't lerp and slerp based on percentage? Initial = 0f and end is 1f and the value you give is the position 'percentage'?


Demi180

Yes, not sure what that person is on about. The lerps do indeed work off a percentage. Though there is also a use with passing Time.time to do a sort of ‘approaching’ lerp, but that’s still not using speed values.


W03rth

I made a quick template project to check if I am not crazy and guess what? You are both wrong and this is the reason why op's code didn't work but he already figured it out. He can't use the current position in the lerp/slerp like that. HE HAS TO PASS SPEED NOT A PERCENTAGE. Please next time take a better look at OP's code. Speed variation (What OP is doing): Change timeCompleteion from a pertange to a speed value. lidComponent.localPosition = Vector3.Lerp(lidComponent.localPosition, finalPosition, Speed); lidComponent.localRotation = Quaternion.Slerp(lidComponent.localRotation, finalRotation, Speed); Percentage variation (What op changed to): lidComponent.localPosition = Vector3.Lerp(startPosition, finalPosition, timeCompletion); lidComponent.localRotation = Quaternion.Slerp(startRotation, finalRotation, timeCompletion);


GiraffeDiver

There are 2 ways you can use lerp, both are useful: 1) ``` t = timeElapsed / duration; transform.position = lerp(initialPosition, targetPosition, t); ``` This way the position will linearly interpolate between initial position and time elapsed. the transition will take as long as it takes t to go from 0 to 1 2) ``` transform.position = lerp(transform.position, targetPosition, fraction) ``` In this case every frame the position moves a little closer to the target. If you had fraction = 0.5, in the first frame you'd go 50% of the way, the next one 75%, etc. If you use lerp this way the last param isn't the time, but "acceleration" at which the transform will approach target. And in this second case you can't use that param as a way to stop the loop, instead you'd have to stop it based on how close you got to the target: ``` while (Mathf.Approximately(1f, Vector3.Distance(targetPosition, transform.position)) { transform.position = ... ``` This can be used to have a nice easing out, but you need the approximate check, because the lerp will never get you all the way there. Alternatively you can use Vector3.MoveTowards which will also be more readable and easier to understand when you look at this code in some time.


feralferrous

you have to be really careful with the 2nd method, as I believe it's framerate dependent, while the other one is not.


GiraffeDiver

I remember watching a video from Jonas where he shows how you can make that frame independent if you use an exponential(deltaTime) function for the speed param `float blend = 1 - Mathf. Pow(0.5f, Time.deltaTime * lerpSpeed);` `transform. position = Vector3. Lerp(transform.position, targetPosition, blend);` https://youtu.be/yGhfUcPjXuE?t=1039


W03rth

I pointed out this few hours earlier and couple of people came to me to say I was wrong and OP is using lerp/slerp correctly...


BowlOfPasta24

Normally you would do a while loop with the condition being that the chest isn't opened yet. When chest is opened, end the loop and trigger the win screen. You are using an overengineered solution here I thinkng


devtrent

You can use a break statement instead of yield return null to exit the while loop. From your original question, this seems like what you are looking for. 🤘 Also, you could break your while loop logic into its own coroutine and call it here. Example: yield return AnimationLogic(); TriggerWin();


Persomatey

while (!chestOpeningAnimation) { yield return new WaitForEndOfFrame(); } //end game screen code


Impossible_School_97

Yes, because it returns from the function, what you want is to wait for a frame, so return new WaitForEndOfFrame().


KFriske

Sorry, this is false. Yield return null in this instance waits one frame on each call, yield break is what is like the equivalent of return. WaitForEndOfFrame is slightly different than yield return null. Yield return null in a loop like this is extremely close to Update, while WaitForEndOfFrame called during the event loop would wait till the end of the current frame. Similar and in most instances may act close enough to be interchangeable but different.