一、准备工作
Spine插件及基本知识可查看这篇文章:Unity | Spine动画记录-CSDN博客
二、Spine资源动态加载
1.官方说明
官方文档指出不建议这种操作。但spine-unity API允许在运行时从SkeletonDataAsset或甚至直接从三个导出的资产实例化SkeletonAnimation和SkeletonGraphic GameObjects。
2.注意事项
注意:动态加载的三个文件需要命名,并且不能出错。因为源代码中需要用名称来匹配。如下方的代码中要求pageName与贴图name一致,不能有后缀。
public static SpineAtlasAsset CreateRuntimeInstance (TextAsset atlasText, Texture2D[] textures, Material materialPropertySource, bool initialize) {// Get atlas page names.string atlasString = atlasText.text;atlasString = atlasString.Replace("\r", "");string[] atlasLines = atlasString.Split('\n');var pages = new List<string>();for (int i = 0; i < atlasLines.Length - 1; i++) {if (atlasLines[i].Trim().Length == 0)pages.Add(atlasLines[i + 1].Trim().Replace(".png", ""));}// Populate Materials[] by matching texture names with page names.var materials = new Material[pages.Count];for (int i = 0, n = pages.Count; i < n; i++) {Material mat = null;// Search for a match.string pageName = pages[i];for (int j = 0, m = textures.Length; j < m; j++) {if (string.Equals(pageName, textures[j].name, System.StringComparison.OrdinalIgnoreCase)) {// Match found.mat = new Material(materialPropertySource);mat.mainTexture = textures[j];break;}}if (mat != null)materials[i] = mat;elsethrow new ArgumentException("Could not find matching atlas page in the texture array.");}// Create AtlasAsset normallyreturn CreateRuntimeInstance(atlasText, materials, initialize);
}
3.代码实现
using Spine.Unity;
using System.Collections;
using UnityEngine;
using UnityEngine.Networking;public class DownloadSpine : MonoBehaviour
{public Shader shader;//选择Spine/Skeleton shaderprivate TextAsset skeletonJson;//json或者二进制文件private TextAsset atlasText;private Texture2D[] textures;private float delay = 0;private string skinName="base";private string animationName = "gun toss";private SpineAtlasAsset runtimeAtlasAsset;private SkeletonDataAsset runtimeSkeletonDataAsset;private SkeletonAnimation runtimeSkeletonAnimation;void Start(){StartCoroutine(DownloadFile("https://static0.***.com/ziliao/spineboy-unity/", "spineboy.atlas", "spineboy", "spineboy-unity"));}private IEnumerator DownloadFile(string dir, string atlasTextName, string imageName, string skeletonJsonName){//下载atlasTextUnityWebRequest request = UnityWebRequest.Get(dir + atlasTextName + ".txt");yield return request.SendWebRequest();if (request.result == UnityWebRequest.Result.Success){atlasText = new TextAsset(request.downloadHandler.text);atlasText.name = atlasTextName;}else{Debug.LogError("Error downloading atlasText asset: " + request.error);}//下载texturesrequest = UnityWebRequestTexture.GetTexture(dir + imageName + ".png");yield return request.SendWebRequest();if (request.result == UnityWebRequest.Result.Success){textures = new Texture2D[1];textures[0] = DownloadHandlerTexture.GetContent(request);textures[0].name = imageName;}else{Debug.LogError("Error downloading image asset: " + request.error);}//下载skeletonFilerequest = UnityWebRequest.Get(dir + skeletonJsonName + ".json");yield return request.SendWebRequest();if (request.result == UnityWebRequest.Result.Success){skeletonJson = new TextAsset(request.downloadHandler.text);skeletonJson.name = skeletonJsonName;}else{Debug.LogError("Error downloading json asset: " + request.error);}StartCoroutine(PlayAnim());}void CreateRuntimeAssetsAndGameObject(){Material material = new Material(shader);runtimeAtlasAsset = SpineAtlasAsset.CreateRuntimeInstance(atlasText, textures, material, true);runtimeSkeletonDataAsset = SkeletonDataAsset.CreateRuntimeInstance(skeletonJson, runtimeAtlasAsset, true);}IEnumerator PlayAnim(){CreateRuntimeAssetsAndGameObject();if (delay > 0){runtimeSkeletonDataAsset.GetSkeletonData(false);yield return new WaitForSeconds(delay);}runtimeSkeletonAnimation = SkeletonAnimation.NewSkeletonAnimationGameObject(runtimeSkeletonDataAsset);runtimeSkeletonAnimation.transform.position = new Vector3(0, -3, 0);// additional initializationruntimeSkeletonAnimation.Initialize(false);if (skinName != ""){runtimeSkeletonAnimation.Skeleton.SetSkin(skinName);}runtimeSkeletonAnimation.Skeleton.SetSlotsToSetupPose();if (animationName != ""){runtimeSkeletonAnimation.AnimationState.SetAnimation(0, animationName, true);}}
}