Hi Guys,
I’m stuck for days with an issue on animating my character. In play mode it works perfect, unfortunately whenever I build and start it the results looks like all my characters are trapped in a twister.
I have an object called player with 5 child objects body, hair, eyes, outfit and accessory. The user should be able to change the look, so I have 5 different images rendered in a specific order to ensure the character looks as it should.
Each different visual object such as body, hair or accessory has 48 different sprites, as each animation consists of 6 sprites * 4 for each direction * 2 for standing and walking.
This way I have e.g. 27 hair styles, which additionally have 7 hair colors each.
This issue is happening for each of these objects, so I use the body as the simplest example.
Initially I had created an animation controller and used animations triggered with keyboard inputs to decide if the character is standing or walking, but then I had this issue, so I removed the animations and decided to update the sprites in each FixedUpdate() call instead.
Again working fine in play mode, but not in the built game.
The player looks like each part constantly receives different inputs, resulting in a body looking left, hair from the right looking, equipment from the up looking and so on.
This changes several times per second so it looks the character is in a twister.
The animationIds are ordered and should loop only in a specific way, e.g. 0-5 = looking down, 6-11 looking left and so on.
I have another script called Move which uses keyboard inputs to calculate the offset and loop through the 6 sprites. If I’m e.g. walking right it will set it’s animationId which is referenced in each of the scripts to an integer looping through [42,43,44,45,46,47] every 0.1f seconds.
I have added a Text Mash Pro GUI field to show the current animationId. It’s correct, always resulting in the correct number, in play mode and the built game.
Please take a look at my code, maybe you have an idea
public class Body : UpdateReceiver
{
private int bodyId = 0;
private int animationId = 0;
private Sprite[] spriteList = new Sprite[48];
private int lastBodyId = 0;
private int lastAnimationId = 0;
public bool ui = false;
protected void Start()
{
bodyId = gameObject.GetComponentInParent<Person>().playerLook._bodyId % PersonStatics.bodyList.Length;
AsyncOperationHandle<Sprite[]> spriteHandle = Addressables.LoadAssetAsync<Sprite[]>("Assets/Tilemaps/Character/Body/" + PersonStatics.bodyList[bodyId % PersonStatics.bodyList.Length] + ".png");
spriteHandle.Completed += LoadSpritesWhenReady;
lastBodyId = bodyId;
}
protected void LoadSpritesWhenReady(AsyncOperationHandle<Sprite[]> handleToCheck)
{
if (handleToCheck.Status == AsyncOperationStatus.Succeeded)
{
spriteList = handleToCheck.Result;
if (ui)
{
GetComponent<Image>().sprite = spriteList[animationId];
}
else
{
GetComponent<SpriteRenderer>().sprite = spriteList[animationId];
}
}
}
protected void FixedUpdate()
{
bodyId = gameObject.GetComponentInParent<Person>().playerLook._bodyId % PersonStatics.bodyList.Length;
animationId = gameObject.GetComponentInParent<Move>().animationId % 48;
if (lastBodyId != bodyId)
{
AsyncOperationHandle<Sprite[]> spriteHandle = Addressables.LoadAssetAsync<Sprite[]>("Assets/Tilemaps/Character/Body/" + PersonStatics.bodyList[bodyId % PersonStatics.bodyList.Length] + ".png");
spriteHandle.Completed += LoadSpritesWhenReady;
lastBodyId = bodyId;
}
else if(animationId != lastAnimationId)
{
if (ui)
{
GetComponent<Image>().sprite = spriteList[animationId];
}
else
{
GetComponent<SpriteRenderer>().sprite = spriteList[animationId];
}
}
lastAnimationId = animationId;
}
}
Thanks in advance!
Regards,
Christian