jeffreylanters / unity-tweens

An extremely light weight, extendable and customisable tweening engine made for strictly typed script-based animations for user-interfaces and world-space objects optimised for all platforms.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Tween/Driver script added even after Stop game in Editor during async method (actually Unity's limitation)

hsandt opened this issue · comments

Describe the bug
If adding Tween as part of an async method, and stopping the game while it's still running, the async method will keep running, possibly running tweens and adding dirty Tween Driver components on game objects in the scene, that will stay and be saved in the scene.

Sometimes, you'll also see error messages about runtime script on that game object, it's related to the Driver leftover, as removing it removes the error messages.

GameObject (named 'Team Logo Text (TMP)') references runtime script in scene file. Fixing!

Unfortunately, this is due to a limitation of Unity that will keep running all async methods after Stop in Editor, as they are not really controlled, and the user may want to use this behaviour for Tool functionality in the Editor.

See: https://forum.unity.com/threads/non-stopping-async-method-after-in-editor-game-is-stopped.558283/

Since there is not much to do to stop this behaviour without adding code on the project itself (see the 2 workarounds in the thread above), I'm only suggestion to, at least, check for if (Application.isPlaying) before adding a component to the game object, the only effect that really bothers me after stopping the game. Obviously, I put more complex stuff in my async method, that will run too and I may have troubles anyway, but at least I'll be able to avoid the unwanted runtime components sticking to my game objects and being saved in my scene.

To avoid extra code in Builds, you may surround the isPlaying check with #if UNITY_EDITOR

Tested with Graphic Alpha Tween only.

To Reproduce
Steps to reproduce the behavior:

  1. Create a new project with package "git+https://github.com/jeffreylanters/unity-tweens"
  2. Create script SplashScreenManager with multiple tweens chained:
using System.Threading.Tasks;
using UnityEngine;

using ElRaccoone.Tweens;

/// Splash Screen Manager
public class SplashScreenManager : MonoBehaviour
{
    [Header("Scene references")]
    
    [Tooltip("Team logo")]
    public GameObject teamLogo;


    private async void Start()
    {
        await PlaySplashScreenSequence();
    }

    private async Task PlaySplashScreenSequence()
    {
        // fade-in
        await teamLogo.TweenGraphicAlpha(1f, 1f).SetFrom(0f).Await();
        await Task.Delay(Mathf.RoundToInt(1000 * 1f));
        // fade-out
        await teamLogo.TweenGraphicAlpha(0f, 1f).Await();
    }
}
  1. Add it to some SplashScreenManager game object
  2. Create Image (it will automatically be added on a Canvas) "TeamLogo" and set a dummy sprite like "Background" on it, just so it's visible.
  3. Run the game, and try to stop the game at different moments. If you stop if right after fade-in is over (after 1s), it should pop a Driver (meant for the following fade-out) on TeamLogo, that sticks in the scene.

Expected behavior
No Driver should be added outside Play

(or they should be removed automatically by some editor script; they probably are on game quit actually, it's just that another one is re-added afterwards)

Screenshots

image

and if you repeat the operation:

image

Desktop (please complete the following information):

  • OS: Linux Ubuntu
  • Unity: 2021.1.14f1
  • Tween code version: v1.11.1

Additional context
I'm testing my splash screen as you may have guessed, after seeing many errors on runtime scripts I spot the issue.

Workaround
Use coroutines instead of async methods...

Hi! Thank you so much for your detailed contribution.

I've tried implementing your suggestion, but this sadly does not solve the problem. It however dus solve the problem where the Tween kept executing, but now the error moves up a level (MyTestSequence in this case). The quickest solution to resolve this problem is wrapping it within a try/catch as below.

private async void MyTestSequence () {
  try {
    await this.gameObject.TweenPosition (Vector3.zero, 2).Await ();
    await this.gameObject.TweenPosition (Vector3.one, 2).Await ();
    await this.gameObject.TweenPosition (Vector3.zero, 2).Await ();
    await this.gameObject.TweenPosition (Vector3.one, 2).Await ();
  } catch (System.Exception e) { }
}

Could you try this solution using the latest commit?

This issue is stale because it has been open for 30 days with no activity.

OK, I'll try this.

In the meantime I was using one of the workarounds on the Unity forums, so I didn't stumble on the issue further.

Application Quit doesn't seem to be caught in the try-catch, so this didn't work (I never enter the catch case, even if I add a Debug.Log for instance).

I'll stick to my workaround for now, it doesn't need extra local code on async methods so it's convenient enough.

This issue is stale because it has been open for 30 days with no activity.

This issue was closed because it has been inactive for 14 days since being marked as stale.