protected override void ClientSetupSkeletonAnimation( bool isActive, IItem item, ICharacter character, IComponentSkeleton skeletonRenderer, List <IClientComponent> skeletonComponents) { base.ClientSetupSkeletonAnimation(isActive, item, character, skeletonRenderer, skeletonComponents); if (!isActive) { return; } // create fire sprite renderer var sceneObject = skeletonRenderer.SceneObject; var fireRenderer = Client.Rendering.CreateSpriteRenderer( sceneObject, TextureResource.NoTexture, // draw origin is calculated so that the center // of the flame sprite will always stay on the end of the torch item spritePivotPoint: (0.5, 0.277), // please note: the torch X axis ("Weapon" slot) is oriented up because torch is held this way! positionOffset: (0.35, 0), scale: 0.9); var fireAnimator = sceneObject.AddComponent <ClientComponentSpriteSheetAnimator>(); fireAnimator.Setup( fireRenderer, ClientComponentSpriteSheetAnimator.CreateAnimationFrames(TextureAtlasFire), isLooped: true, frameDurationSeconds: 1 / 15.0, randomizeInitialFrame: true); var slotNameClone = "Weapon_Torch"; skeletonRenderer.CloneSlot("Weapon", slotNameClone); skeletonRenderer.SetAttachmentRenderer(slotNameClone, "WeaponMelee", fireRenderer, applyBoneRotation: false); skeletonRenderer.SetAttachment(slotNameClone, "WeaponMelee"); skeletonComponents.Add(fireRenderer); skeletonComponents.Add(fireAnimator); }