why

I used Live2D to display dynamic characters in Unity, and encountered that when the game went on for a period of time, the character’s eyeballs randomly disappeared without showing. Looking at the eyeball node, you can see that it uses a MaskGuess it should be mask function failure, find the official manualDocs.live2d.com/cubism-sdk-… Masks are shared, and when the upper limit is reached, the Mask function behind them is disabled.

To solve

There are not so many Live2D characters on the screen at the same time, and the code to check is CubismMaskController only removes the Mask when OnDestroy is used, which makes it not enough. Change the CubismMaskController file’s code functions Start and OnDestroy to OnEnable and OnDisable, and place them in the Mask only when activated.

        /// <summary>
        /// Initializes instance.
        /// </summary>
        private void OnEnable()
        {
            // Fail silently.
            if (MaskTexture == null)
            {
                return;
            }


            MaskTexture.AddSource(this);

            // Get cubism update controller._hasUpdateController = (GetComponent<CubismUpdateController>() ! =null);
        }

        /// <summary>
        /// Finalizes instance.
        /// </summary>
        private void OnDisable()
        {
            if (MaskTexture == null)
            {
                return;
            }


            MaskTexture.RemoveSource(this);
        }
Copy the code

In addition, the CubismMaskTexture does not need to release the texture when the Live2D character is not displayed. In the RemoveSource function, comment out ReleaseRenderTexture();

        /// <summary>
        /// Remove source of masks
        /// </summary>
        public void RemoveSource(ICubismMaskTextureCommandSource source)
        {
            // Return early if empty.
            if(! ContainsSources) {return;
            }


            var itemIndex = Sources.FindIndex(i => i.Source == source);


            // Return if source is invalid.
            if (itemIndex == - 1)
            {
                return;
            }


            // Return tiles and deregister source.
            TilePool.ReturnTiles(Sources[itemIndex].Tiles);
            Sources.RemoveAt(itemIndex);

            // releaseRT
            if (Sources.Count == 0)
            {
                //ReleaseRenderTexture();}}Copy the code

The CubismMaskTexture GlobalMaskTexture variable exists globally and is not released when cutting the scene.