public void NotifyGrabbed(Notamari notamari) { if (notamari.GetDebrisCount() >= m_DebrisTotal) { EndPhase(notamari); } }
IEnumerator EndGameCutscene(Notamari notamari) { // This is all pretty hacked-together, I just don't want to try putting it in a state machine // IN RETROSPECT this is terrible and I did a better job on the next function Camera camera = Camera.main; ColorCorrectionCurves colorCurves = camera.GetComponent<ColorCorrectionCurves>(); float preDelayTime = 1f; float saturationTime = 3f; float saturationDelayTime = 1.2f; float successTime = 2f; float successDelayTime = 1.2f; float continueTime = 2f; ShatterWorld(true, notamari.transform.position); yield return new WaitForSeconds(preDelayTime); float startTime = Time.time; while (Time.time < startTime + saturationTime) { // yield goes first to guarantee we max out the animation yield return 0; // parenthesis are important to avoid floating-point inaccuracy! float progress = Mathf.Clamp((saturationTime - (Time.time - startTime)) / saturationTime, 0, 1); // strongly recommended that you consult with google calculator or wolfram alpha or similar in order to graph these // math pulled pretty much out of nowhere, I guess it looked good // in retrospect I probably should have used curves, but using curves to create curves seemed . . . complicated // even though it really wouldn't have been // welp // TODO: use curves float progressMunged = (Intensify(progress * 2 - 1, 2) + 1) / 2; float darkness = progressMunged; float lightness = Mathf.Sqrt(progressMunged); AnimationCurve curve = AnimationCurve.Linear(0, -darkness * (1 - darkness), lightness * lightness, 1); colorCurves.redChannel = curve; colorCurves.greenChannel = curve; colorCurves.blueChannel = curve; colorCurves.UpdateParameters(); } m_AllowRestart = true; yield return new WaitForSeconds(saturationDelayTime); startTime = Time.time; while (Time.time < startTime + successTime) { // this is copypastier than I like :/ // yield goes first to guarantee we max out the animation yield return 0; // parenthesis are important to avoid floating-point inaccuracy! float progress = Mathf.Clamp((successTime - (Time.time - startTime)) / successTime, 0, 1); Assert.IsNotNull(m_SuccessText); if (m_SuccessText) { m_SuccessText.color = new Color(0, 0, 0, 1 - progress); } } yield return new WaitForSeconds(successDelayTime); startTime = Time.time; while (Time.time < startTime + continueTime) { // this is copypastier than I like :/ // yield goes first to guarantee we max out the animation yield return 0; // parenthesis are important to avoid floating-point inaccuracy! float progress = Mathf.Clamp((continueTime - (Time.time - startTime)) / continueTime, 0, 1); Assert.IsNotNull(m_ContinueText); if (m_ContinueText) { m_ContinueText.color = new Color(0, 0, 0, 1 - progress); } } }
IEnumerator PhaseChangeCutscene(Notamari notamari) { // The phase change cutscene is (1) meant to be pretty, and (2) meant to disguise the framerate hitch caused by spawning a ton of physics items // If I couldn't disguise the hitch like this I would probably have to generate physics items in stasis over a period of time, or generate them at level load, or something // But I can! // So I do. // We're using animation curves here because the EndGameCutscene is way too ugly for me to be happy with. float flashDuration = 0.2f; // FUN FACT: smaller flash durations felt like a framerate hitch, even though half the purpose was to disguise framerate hitches. welp ColorCorrectionCurves colorCurves = Camera.main.GetComponent<ColorCorrectionCurves>(); float startTime = Time.time; while ((Time.time - startTime) < m_PCCutsceneLow[m_PCCutsceneLow.length - 1].time) { // yield goes first to guarantee we max out the animation yield return 0; AnimationCurve curve = AnimationCurve.Linear(0, m_PCCutsceneLow.Evaluate(Time.time - startTime), m_PCCutsceneHigh.Evaluate(Time.time - startTime), 1); colorCurves.redChannel = curve; colorCurves.greenChannel = curve; colorCurves.blueChannel = curve; colorCurves.UpdateParameters(); } yield return new WaitForSeconds(flashDuration); // Destroy all colliders that are involved in this phase ShatterWorld(false, notamari.transform.position); // Clear the notamari notamari.Empty(); // Begin the next segment m_Chain.BeginPhase(); // Reset colors AnimationCurve origCurve = AnimationCurve.Linear(0, 0, 1, 1); colorCurves.redChannel = origCurve; colorCurves.greenChannel = origCurve; colorCurves.blueChannel = origCurve; colorCurves.UpdateParameters(); }
void EndPhase(Notamari notamari) { if (m_Chain) { StartCoroutine(PhaseChangeCutscene(notamari)); } else { StartCoroutine(EndGameCutscene(notamari)); } }