• RuntimesUnity
  • Instantiation At Runtime and Fit In Parent

Hey - I'm attempting to integrate spine animations that can be downloaded at runtime into a unity project.

Everything is working great except that I cannot work out how to make Fit In Parent work after I've instantiated the spine animation at runtime.

Is there a best practice around this?

Related Discussions
...

@hey-ben You may want to call skeletonGraphic.MatchRectTransformWithBounds() after loading your skeleton is complete (and after setting your desired animation so that the mesh bounds are fit to the respective animation's first frame).

@hey-ben Oh, sorry, I just noticed that the other relevant code blocks and methods that reset referenceSize and referenceScale are located in #if UNITY_EDITOR sections, so unavailable or skipped at runtime. We will provide a way to reset the reference rect to the RectTransform accordingly.

@hey-ben We've just fixed MatchRectTransformWithBounds so that it updates the referenceSize property accordingly. So you can setup your SkeletonGraphic object similar to the following code:

skeletonGraphic = SkeletonGraphic.AddSkeletonGraphicComponent(gameObject, skeletonDataAsset, material);
skeletonGraphic.MatchRectTransformWithBounds();
skeletonGraphic.layoutScaleMode = SkeletonGraphic.LayoutMode.FitInParent;

// set the RectTransform to same size as parent. left, right, top, bottom = 0, 0, 0, 0 in Inspector.
skeletonGraphic.rectTransform.anchoredPosition = Vector2.zero;
skeletonGraphic.rectTransform.sizeDelta = Vector2.zero;

Please let us know if this resolves your issue as well.

New spine-unity 4.1 and 4.2-beta unitypackages have just been released, they are available for download here as usual:
https://esotericsoftware.com/spine-unity-download

This issue has been tracked under the following ticket:
EsotericSoftware/spine-runtimes2408

Oh wow that worked perfectly thanks!
I do have to wait for 2 frames to be able to set the sizeDelta and it work. Is there a more reliable callback or anything I can listen for here instead?

    SpineAtlasAsset runtimeAtlasAsset = SpineAtlasAsset.CreateRuntimeInstance(spriteAtlasData, new [] { spriteAtlas }, spineMaterial, true);
    SkeletonDataAsset runtimeSkeletonDataAsset = SkeletonDataAsset.CreateRuntimeInstance(spineJson, runtimeAtlasAsset, false);
    
    skeletonGraphic.skeletonDataAsset = runtimeSkeletonDataAsset;
    skeletonGraphic.Initialize(false);
    skeletonGraphic.Skeleton.SetSkin(streamableSpineData.SkinName);
    skeletonGraphic.Skeleton.SetSlotsToSetupPose();
    skeletonGraphic.AnimationState.SetAnimation(0, streamableSpineData.AnimationName, true);
    
    skeletonGraphic.MatchRectTransformWithBounds();
    skeletonGraphic.layoutScaleMode = SkeletonGraphic.LayoutMode.FitInParent;

    yield return new WaitForEndOfFrame();
    yield return new WaitForEndOfFrame();

    // set the RectTransform to same size as parent. left, right, top, bottom = 0, 0, 0, 0 in Inspector.
    skeletonGraphic.rectTransform.anchoredPosition = Vector2.zero;
    skeletonGraphic.rectTransform.sizeDelta = Vector2.zero;

    hey-ben Harald will be unavailable until November 12th as he is on vacation. I'm sure he'll give you some advice when he gets back, so I hope you'll wait until then.

    10 أيام لاحقا

    @hey-ben Sorry for the long delay.

    hey-ben I do have to wait for 2 frames to be able to set the sizeDelta and it work. Is there a more reliable callback or anything I can listen for here instead?

    From where are you calling the code you posted? Is it called from Update, or from somewhere else?

    See the life-cycle here:
    https://esotericsoftware.com/spine-unity#Life-cycle
    You could use the OnMeshAndMaterialsUpdated callback as shown in the section above, but you could also force an update in the same frame.

    In general, directly after modifying the animation state like by calling AnimationState.SetAnimation(), the AnimationState is not yet applied to the Skeleton, and the mesh is not updated to the Skeleton state. Animations will be applied in the next SkeletonGraphic.Update() call, while the mesh will be updated in the next SkeletonRenderer.LateUpdate() call. So in order to update both immediately, you can call skeletonGraphic.Update(0) to apply the animation to the skeleton, and then skeletonGraphic.UpdateMesh() to update the mesh to the skeleton state. Thereafter you should get the proper mesh bounds for your desired animation.