Can't Modify Variable

Ok, I need help to figure out what I’m getting wrong here.

the variable “_loop” won’t let me change it’s value in the code below: if _loop == 1 then _loop = 0 (line 47).

I’ve made it public, I’ve re-jigged the code a few different ways, and it still won’t do as it’s told.

I’m sure it’s just an obvious oversight (it’s 4:30am at the moment, so I’ve probably lost a little reasoning by this point), but can anybody please tell me where I’m going wrong?

Thanks in advance.

using DragonBones;
using UnityEngine;

public class DBAnimHandler: MonoBehaviour
{
    [SerializeField]
    private int _currentAnimation;
    [SerializeField]
    private bool _waitForLoop;
    [SerializeField]
    private int _timeScale;
    public int _loop;
    [SerializeField]
    private int _orderInLayer;
    [SerializeField]
    private UnityArmatureComponent _armatureComp;
    private int? _lastAnimation;
    private int? newAnimation;

    // Update is called once per frame
    void LateUpdate()
    {
        // Sets the animation and then checks whether the animation has changed.
        // Wait For Loop determines whether the animation will run to the end or just change immediately on request.
        string[] animationIndex = this._armatureComp.animation.animationNames.ToArray();
        newAnimation = _currentAnimation;
        bool isPlaying = this._armatureComp.animation.isPlaying;
        this._armatureComp.animation.timeScale = _timeScale;
        this._armatureComp.sortingOrder = _orderInLayer;
        Debug.Log("Loop " + _loop);


        // Out of animation index range.
        if (newAnimation < 0 ^ newAnimation > (animationIndex.Length - 1))
        {
            return;
        }

        // Immediately play new animation, play new animation after previous animation finishes, or loop current animation.
        else if (((newAnimation != _lastAnimation) && (_waitForLoop == false || isPlaying == false)) || (isPlaying == false && newAnimation == _lastAnimation))
        {
            if (_loop == -1 || _loop == 1)
            {
                this._armatureComp.animation.FadeIn(animationIndex[newAnimation ?? 0], 0.1f, 1);
                _lastAnimation = newAnimation;

                if (_loop == 1)
                {
                    _loop = 0;
                }
            }

            else if (_loop == 0)
            {
                this._armatureComp.animation.Stop();
            }

            else return;
        }
    }
}

Can you clarify this- are you getting a compiler error, runtime exception or an apparently unchanging value?

If it’s the latter, what have you done to ensure the value is actually being changed (debug logging, stepped in debugger)?

Also, given that it’s a public variable, what other areas in the code are writing to it- are they instantly resetting it after this code has made the expected change?

Hey, Doug_B.

Sorry, just got myself awake & back together.

The end result is an unchanged value.

You can see the debug.log in the script, and the logs confirms that the field isn’t changing.

I set it to public in exacerbation to see if it would maybe affect access by the code. The only other thing accessing the field is a Unity Animator Component, but it only sets the value once, and doesn’t loop. Besides, the field doesn’t appear to be resetting; it’s not changing at all.

The only other thing I can think of is that this script is a go-between for the Dragonbones animation component and the Animator component, and there appears to be issues with accessing the DB component directly from the animator, hence the need for the script.

That said, I would have thought the end result of that would be that my _loop value changes but has no effect on the animation.

I’m stumped for the moment.

Ok, didn’t figure out how to fix the original query, but I found a work around.

Since I only really need three states – infinite loop, play once, or stop – and the first play through is distinguished by the variables newAnmiation and _lastAnmation not being equal, I just changed my code to only play the animation in the subsequent if statement if the _loop field is set to -1, and then it will loop continuously.

Still didn’t figure out why I couldn’t change the value of _loop via code, but I can worry about that the next time I butt up against that wall.

using DragonBones;
using UnityEngine;

public class DBAnimHandler: MonoBehaviour
{
    [SerializeField]
    private int _currentAnimation;
    [SerializeField]
    private bool _waitForLoop;
    [SerializeField]
    private int _timeScale;
    public int _loop;
    [SerializeField]
    private int _orderInLayer;
    [SerializeField]
    private UnityArmatureComponent _armatureComp;
    private int? _lastAnimation;
    private int? newAnimation;

    // Update is called once per frame
    void LateUpdate()
    {
        // Sets the animation and then checks whether the animation has changed.
        // Wait For Loop determines whether the animation will run to the end or just change immediately on request.
        string[] animationIndex = this._armatureComp.animation.animationNames.ToArray();
        newAnimation = _currentAnimation;
        bool isPlaying = this._armatureComp.animation.isPlaying;
        this._armatureComp.animation.timeScale = _timeScale;
        this._armatureComp.sortingOrder = _orderInLayer;
        Debug.Log("Loop " + _loop);


        // Out of animation index range.
        if (newAnimation < 0 ^ newAnimation > (animationIndex.Length - 1))
        {
            return;
        }

        // Immediately play new animation, play new animation after previous animation finishes, or loop current animation.
        else if (newAnimation != _lastAnimation && (_waitForLoop == false || isPlaying == false))
        {
            if (_loop == -1)
            {
                this._armatureComp.animation.FadeIn(animationIndex[newAnimation ?? 0], 0.1f, 1);
                _lastAnimation = newAnimation;
            }

            if (_loop == 1)
            {
                this._armatureComp.animation.FadeIn(animationIndex[newAnimation ?? 0], 0.1f, 1);
                _lastAnimation = newAnimation;
            }

            else if (_loop == 0)
            {
                this._armatureComp.animation.Stop();
                return;
            }

            else return;
        }

        else if (isPlaying == false && newAnimation == _lastAnimation)
        {
            if (_loop == -1)
            {
                this._armatureComp.animation.Play(animationIndex[newAnimation ?? 0]);
            }

            else return;
        }

        else return;
    }
}

I didn’t notice that log line. However, that line is not reached until the frame following the setting of the value. By which time, of course, it could have been set back by something else.

One thing you could try is adding a debug log line at the end of the method to show that _loop has indeed changed. If it has but has been reset by the next frame (so the current debug log line (at 30) shows its old value), then something else is changing it. What you could do then, is rename the variable and recompile the code. Find out what breaks as that thing may be accessing (writing to) that variable.