Forum rules - please read before posting.

SUC frame flip stopped working

Hi there,

I have been using the SUC Frame flip script to mirror my Player's animation. All has been working well until recently when I tried to implement some NPC characters that are using this script as well. It all worked well at first, but when I turned on the Editor today, the Player was not flipping.

I removed the NPCs altogether, removed the Script from the Player prefab as well, and restarted the Editor. I then added the script back to the Player prefab, but it is still not working. The script just stopped working altogether. I had to revert to the last working version of my game. I built everything up again, and the exact same thing happened. What is puzzling is that I know it worked the last time, but now, after I turned it on, it is not working again.

What am I doing wrong?

Comments

  • The script will only affect objects you assign in its Inspector. Unless the component refers to a character different to the one it's attached to, it will have no bearing on the behaviour of another character.

    It's too open-ended an issue to understand what the cause is. I'd suggest placeing Debug.Log statements in the component that output what character is being affected, and how.

  • So i consulted with ChatGPT, and came to this conclusion:

    The original script ran in Update() — but Unity’s Animator also runs every frame and often modifies transform properties like localScale after Update() but before rendering.

    So what happened was:

    • the script ran in Update(), flipped the scale.
    • Animator kicked in afterward, reset localScale.x to what it thinks it should be.
    • Result: no visible flip — even though your logic was correct, it got silently undone!

    I updated the script to this, and it seems to be working just fine! :-)

    using UnityEngine;
    using AC;
    
    public class SUC_FrameFlip : MonoBehaviour
    {
        [SerializeField] private AC.Char character;
        [SerializeField] private Transform transformToFlip;
        [SerializeField] private AC_2DFrameFlipping frameFlipping;
        [SerializeField] private float topAngleFreedom = 0f;
    
        private void LateUpdate()
        {
            if (frameFlipping == AC_2DFrameFlipping.None || character == null || transformToFlip == null)
            {
                return;
            }
    
            float spriteAngle = character.GetSpriteAngle() % 360f;
            if (spriteAngle < 0f) spriteAngle += 360f;
    
            bool doFlip = false;
    
            switch (frameFlipping)
            {
                case AC_2DFrameFlipping.LeftMirrorsRight:
                    doFlip = (spriteAngle >= 0f && spriteAngle < 180f);
                    break;
                case AC_2DFrameFlipping.RightMirrorsLeft:
                    doFlip = (spriteAngle > 180f && spriteAngle <= 360f);
                    break;
                default:
                    return;
            }
    
            // Don't flip if angle is within top or bottom freedom zones
            if (spriteAngle < topAngleFreedom ||
                spriteAngle > (360f - topAngleFreedom) ||
                (spriteAngle > (180f - topAngleFreedom) && spriteAngle < (180f + topAngleFreedom)))
            {
                return;
            }
    
            ApplyFlip(doFlip);
        }
    
        private void ApplyFlip(bool flip)
        {
            float currentX = transformToFlip.localScale.x;
            float targetX = Mathf.Abs(currentX) * (flip ? -1f : 1f);
    
            if (!Mathf.Approximately(currentX, targetX))
            {
                transformToFlip.localScale = new Vector3(
                    targetX,
                    transformToFlip.localScale.y,
                    transformToFlip.localScale.z
                );
    
                Debug.Log($"[SUC_FrameFlip] Flipping applied. Angle: {character.GetSpriteAngle()}, Flip: {flip}, New X: {targetX}");
            }
        }
    }
    
  • Sounds right. While the localScale isn't typically animated in a 2D character's animation set - if it was, there would be competition that can be resolved by using LateUpdate instead of Update.

    I've amended the wiki script to reflect this.

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Welcome to the official forum for Adventure Creator.