Topic: Custom Left and Right Facing 2D Sprites

Most of my characters are asymmetrical, so the automatic mirroring of the original sprites don't work for my project. How do I implement specific Left and Right facing sprites? I've already made sprites for both sides, but only know how to implement one side before it ultimately gets mirrored by the engine. Here's an example of the left and right facing sprites, and then what I currently have in engine.

https://i.imgur.com/9Opgdjw.png
https://i.imgur.com/BFes504.png
https://i.imgur.com/Hxv4WKk.png

Share

Thumbs up Thumbs down

Re: Custom Left and Right Facing 2D Sprites

The system isn't designed with it in mind, no. Sorry.

However, off the top of my head.... you'd create a custom script to the character's prefab that knows where the sprite renderer is being played. If the character is being mirrored in UFE (forgive me because at the moment I forget the exact check but it's something like the character's active controlsScript.mirror. 1 is I believe Player 1 side and -1 is Player 2 side. Assuming that's the case, you could do a check that if the player is being mirrored, then alter the frame in the sprite renderer to the alt. I'd imagine you'd some how make the sprite names formulaic to easily tell when a sprite name is being used, then tell it to switch to the alt. or you can create an array in the same custom script of all the possible adjusted sprites and what to switch them to?

Anyways, that's the best i was able to come up with off the top of my head.

Share

Thumbs up +2 Thumbs down

3 (edited by GriffinSTatum 2021-05-09 16:04:16)

Re: Custom Left and Right Facing 2D Sprites

MrPonton wrote:

The system isn't designed with it in mind, no. Sorry.

However, off the top of my head.... you'd create a custom script to the character's prefab that knows where the sprite renderer is being played. If the character is being mirrored in UFE (forgive me because at the moment I forget the exact check but it's something like the character's active controlsScript.mirror. 1 is I believe Player 1 side and -1 is Player 2 side. Assuming that's the case, you could do a check that if the player is being mirrored, then alter the frame in the sprite renderer to the alt. I'd imagine you'd some how make the sprite names formulaic to easily tell when a sprite name is being used, then tell it to switch to the alt. or you can create an array in the same custom script of all the possible adjusted sprites and what to switch them to?

Anyways, that's the best i was able to come up with off the top of my head.

Thanks for the reply!

I've gotten far enough into development where I wished I fixed this earlier rather than later. I definitely agree with the methodology in terms of taking the Mirror data from the ControlsScript. I was thinking it may be easier to load a Stance (Stance 2) with the P2 sprites, have a custom script read whether the character is on P1 side (1) or P2 side (-1) and then switch between the stance 1 and 2 accordingly. This would be the easiest solution in my mind(at least theoretically), however I'm having trouble finding how to code this.

This code is probably not right, but here's an example of what I'm thinking of.



public void CharacterOrientation
{
if (controlsScript.mirror == 1 && moveSetScript.currentCombatStance == CombatStances.Stance1)
    {
        controlsScript.stanceChange.casted = false;
    }

else if (controlsScript.mirror == 1 && moveSetScript.curentCombatStance == CombatStances.Stance2)
    {
        myMoveSetScript.ChangeMoveStances(stanceChange.Stance1);
        controlsScript.stanceChange.casted = true;
    }

else if (controlsScript.mirror == -1 && moveSetScript.curentCombatStance == CombatStances.Stance1)
    {
        myMoveSetScript.ChangeMoveStances(stanceChange.Stance2);
        controlsScript.stanceChange.casted = true;
    }
else
    {
        controlsScript.stanceChange.casted = false;
    }
    return;
}



Alternatively this may not even need a custom script, as it could (theoretically) be directly implemented into the MoveSetScript, making it a singular instance code where it just picks up on the character's stance and side of the stage, rather than having to go tell a custom script to look for specific sprites for each character.

Here's my example, although I'm not necessarily sure that void Awake is the correct place to put it. Right now it's only loading Stance1 for P1 and Stance2 for P2, not switching as I move one character to the other side. 

void Awake()
    {
        controlsScript = transform.parent.gameObject.GetComponent<ControlsScript>();
        hitBoxesScript = GetComponent<HitBoxesScript>();
        spriteRenderer = GetComponent<SpriteRenderer>();

        List<MoveSetData> loadedMoveSets = new List<MoveSetData>();
            foreach (MoveSetData moveSetData in controlsScript.myInfo.moves)
        {
            loadedMoveSets.Add(moveSetData);
        }
        foreach (string path in controlsScript.myInfo.stanceResourcePath)
        {
            loadedMoveSets.Add(Resources.Load<StanceInfo>(path).ConvertData());
        }
        controlsScript.loadedMoves = loadedMoveSets.ToArray();

        controlsScript.currentCombatStance = CombatStances.Stance10;
        ChangeMoveStances(CombatStances.Stance1);

        if (controlsScript.playerNum == 1)
        {
            if (controlsScript.mirror < 0)
                ChangeMoveStances(CombatStances.Stance2);
            else
                ChangeMoveStances(CombatStances.Stance1);
        }

        else
        {
            if (controlsScript.mirror > 0)
                ChangeMoveStances(CombatStances.Stance1);
            else
                ChangeMoveStances(CombatStances.Stance2);
        }

    }

Share

Thumbs up Thumbs down

Re: Custom Left and Right Facing 2D Sprites

You're touching on areas of the code I've been afraid of messing around with for 3D style play. Where it would switch to "back-turned" stance should the opponent be facing the +/- 45 degrees from character's back, hopefully seemlessly...

I'm too afraid to be mucking around in Stance code so I'm unsure of your changes here as I haven't messed with that part of UFE well enough. I'll try taking a look at your stuff here later when I find the time though to see if it makes sense to me, or if I can give any further suggestions/tips.

Share

Thumbs up Thumbs down

5 (edited by GriffinSTatum 2021-05-12 13:41:00)

Re: Custom Left and Right Facing 2D Sprites

MrPonton wrote:

You're touching on areas of the code I've been afraid of messing around with for 3D style play. Where it would switch to "back-turned" stance should the opponent be facing the +/- 45 degrees from character's back, hopefully seemlessly...

I'm too afraid to be mucking around in Stance code so I'm unsure of your changes here as I haven't messed with that part of UFE well enough. I'll try taking a look at your stuff here later when I find the time though to see if it makes sense to me, or if I can give any further suggestions/tips.

I actually got it to work! I had to adjust the ControlsScript.cs file, here's the original piece of code:

private void testCharacterRotation(Fix64 rotationSpeed, bool forceMirror = false)
    {
        Fix64 myX = worldTransform.position.x;
        Fix64 opX = opControlsScript.worldTransform.position.x;

#if !UFE_LITE && !UFE_BASIC
        if (UFE.config.gameplayType == GameplayType._3DFighter && IsSideSwitchEnabled())
        {
            myX = Camera.main.transform.InverseTransformDirection(worldTransform.position.ToVector() - Camera.main.transform.position).x;
            opX = Camera.main.transform.InverseTransformDirection(opControlsScript.worldTransform.position.ToVector() - Camera.main.transform.position).x;
        }
        else if (UFE.config.gameplayType != GameplayType._2DFighter) 
        {
            return;
        }
#endif

        if ((mirror == -1 || forceMirror) && myX > opX) {
            potentialBlock = false;
            InvertRotation(1);
            if (UFE.config.characterRotationOptions.autoMirror) ForceMirror(true);
            myHitBoxesScript.inverted = true;
            UFE.FireSideSwitch(mirror, this);

        } else if ((mirror == 1 || forceMirror) && myX < opX) {
            potentialBlock = false;
            InvertRotation(-1);
            if (UFE.config.characterRotationOptions.autoMirror) ForceMirror(false);
            myHitBoxesScript.inverted = false;
            UFE.FireSideSwitch(mirror, this);

        }

Here is it working with the two additional line of code that I added:

private void testCharacterRotation(Fix64 rotationSpeed, bool forceMirror = false)
    {
        Fix64 myX = worldTransform.position.x;
        Fix64 opX = opControlsScript.worldTransform.position.x;

#if !UFE_LITE && !UFE_BASIC
        if (UFE.config.gameplayType == GameplayType._3DFighter && IsSideSwitchEnabled())
        {
            myX = Camera.main.transform.InverseTransformDirection(worldTransform.position.ToVector() - Camera.main.transform.position).x;
            opX = Camera.main.transform.InverseTransformDirection(opControlsScript.worldTransform.position.ToVector() - Camera.main.transform.position).x;
        }
        else if (UFE.config.gameplayType != GameplayType._2DFighter) 
        {
            return;
        }
#endif

        if ((mirror == -1 || forceMirror) && myX > opX) {
            potentialBlock = false;
            InvertRotation(1);
            if (UFE.config.characterRotationOptions.autoMirror) ForceMirror(true);
            myHitBoxesScript.inverted = true;
            UFE.FireSideSwitch(mirror, this);
            myMoveSetScript.ChangeMoveStances(CombatStances.Stance2);

        } else if ((mirror == 1 || forceMirror) && myX < opX) {
            potentialBlock = false;
            InvertRotation(-1);
            if (UFE.config.characterRotationOptions.autoMirror) ForceMirror(false);
            myHitBoxesScript.inverted = false;
            UFE.FireSideSwitch(mirror, this);
            myMoveSetScript.ChangeMoveStances(CombatStances.Stance1);

        }

A very minor change but got the exact result I was looking for! This does affect every character, so if someone was looking to only do this for a specific character(or exclude specific characters) there would probably have to be extra lines of code added to adjust.

Share

Thumbs up +2 Thumbs down