/** * The MIT License (MIT) * * Copyright (c) 2012-2017 DragonBones team and other contributors * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ using System.Collections.Generic; using UnityEngine; #if UNITY_EDITOR using UnityEditor; #endif namespace DragonBones { /// internal class ClockHandler : MonoBehaviour { void Update() { UnityFactory.factory._dragonBones.AdvanceTime(Time.deltaTime); } } /// /// The Egret factory. /// /// DragonBones 3.0 /// en_US /// /// /// Egret 工厂。 /// /// DragonBones 3.0 /// zh_CN public class UnityFactory : BaseFactory { /// /// 创建材质时默认使用的 shader。 /// /// DragonBones 4.7 /// zh_CN internal const string defaultShaderName = "Sprites/Default"; /// /// 创建UI材质时默认使用的 shader。 /// /// DragonBones 4.7 /// zh_CN internal const string defaultUIShaderName = "UI/Default"; internal static DragonBones _dragonBonesInstance = null; private static UnityFactory _factory = null; private static GameObject _gameObject = null; // private GameObject _armatureGameObject = null; private bool _isUGUI = false; // private readonly List _cacheUnityDragonBonesData = new List(); /// /// A global factory instance that can be used directly. /// /// DragonBones 4.7 /// en_US /// /// 一个可以直接使用的全局工厂实例。 /// /// DragonBones 4.7 /// zh_CN public static UnityFactory factory { get { if (_factory == null) { _factory = new UnityFactory(); } return _factory; } } /// public UnityFactory(DataParser dataParser = null) : base(dataParser) { Init(); } private void Init() { if (Application.isPlaying) { if (_gameObject == null) { _gameObject = GameObject.Find("DragonBones Object"); if (_gameObject == null) { _gameObject = new GameObject("DragonBones Object", typeof(ClockHandler)); _gameObject.isStatic = true; _gameObject.hideFlags = HideFlags.HideInHierarchy; } } //全局的 GameObject.DontDestroyOnLoad(_gameObject); var clockHandler = _gameObject.GetComponent(); if (clockHandler == null) { _gameObject.AddComponent(); } var eventManager = _gameObject.GetComponent(); if (eventManager == null) { eventManager = _gameObject.AddComponent(); } if (_dragonBonesInstance == null) { _dragonBonesInstance = new DragonBones(eventManager); // DragonBones.yDown = false; } } else { if (_dragonBonesInstance == null) { _dragonBonesInstance = new DragonBones(null); // DragonBones.yDown = false; } } _dragonBones = _dragonBonesInstance; } /// protected override TextureAtlasData _BuildTextureAtlasData(TextureAtlasData textureAtlasData, object textureAtlas) { if (textureAtlasData != null) { if (textureAtlas != null) { //if ((textureAtlas as Material).name.IndexOf("UI_Mat") > -1) //{ // (textureAtlasData as UnityTextureAtlasData).uiTexture = textureAtlas as Material; //} //else //{ // (textureAtlasData as UnityTextureAtlasData).texture = textureAtlas as Material; //} (textureAtlasData as UnityTextureAtlasData).uiTexture = (textureAtlas as UnityDragonBonesData.TextureAtlas).uiMaterial; (textureAtlasData as UnityTextureAtlasData).texture = (textureAtlas as UnityDragonBonesData.TextureAtlas).material; } } else { textureAtlasData = BaseObject.BorrowObject(); } return textureAtlasData; } /// protected override Armature _BuildArmature(BuildArmaturePackage dataPackage) { var armature = BaseObject.BorrowObject(); var armatureDisplay = _armatureGameObject == null ? new GameObject(dataPackage.armature.name) : _armatureGameObject; var armatureComponent = armatureDisplay.GetComponent(); if (armatureComponent == null) { armatureComponent = armatureDisplay.AddComponent(); armatureComponent.isUGUI = _isUGUI; if (armatureComponent.isUGUI) { armatureComponent.transform.localScale = Vector2.one * (1.0f / dataPackage.armature.scale); } } else { //compatible slotRoot var slotRoot = armatureDisplay.transform.Find("Slots"); if (slotRoot != null) { for (int i = slotRoot.transform.childCount; i > 0; i--) { var childSlotDisplay = slotRoot.transform.GetChild(i - 1); childSlotDisplay.transform.SetParent(armatureDisplay.transform, false); } UnityFactoryHelper.DestroyUnityObject(slotRoot.gameObject); } } armatureComponent._armature = armature; armature.Init(dataPackage.armature, armatureComponent, armatureDisplay, this._dragonBones); _armatureGameObject = null; return armature; } protected override Armature _BuildChildArmature(BuildArmaturePackage dataPackage, Slot slot, DisplayData displayData) { var childDisplayName = slot.slotData.name + " (" + displayData.path + ")"; // var proxy = slot.armature.proxy as UnityArmatureComponent; var childTransform = proxy.transform.Find(childDisplayName); Armature childArmature = null; if (childTransform == null) { if (dataPackage != null) { childArmature = BuildArmature(displayData.path, dataPackage.dataName); } else { childArmature = BuildArmature(displayData.path, displayData.parent.parent.parent.name); } } else { if (dataPackage != null) { childArmature = BuildArmatureComponent(displayData.path, dataPackage != null ? dataPackage.dataName : "", null, dataPackage.textureAtlasName, childTransform.gameObject).armature; } else { childArmature = BuildArmatureComponent(displayData.path, null, null, null, childTransform.gameObject).armature; } } if (childArmature == null) { return null; } // var childArmatureDisplay = childArmature.display as GameObject; childArmatureDisplay.GetComponent().isUGUI = proxy.GetComponent().isUGUI; childArmatureDisplay.name = childDisplayName; childArmatureDisplay.transform.SetParent(proxy.transform, false); childArmatureDisplay.gameObject.hideFlags = HideFlags.HideInHierarchy; childArmatureDisplay.SetActive(false); return childArmature; } /// protected override Slot _BuildSlot(BuildArmaturePackage dataPackage, SlotData slotData, Armature armature) { var slot = BaseObject.BorrowObject(); var armatureDisplay = armature.display as GameObject; var transform = armatureDisplay.transform.Find(slotData.name); var gameObject = transform == null ? null : transform.gameObject; var isNeedIngoreCombineMesh = false; if (gameObject == null) { gameObject = new GameObject(slotData.name); } else { if (gameObject.hideFlags == HideFlags.None) { var combineMeshs = (armature.proxy as UnityArmatureComponent).GetComponent(); if (combineMeshs != null) { isNeedIngoreCombineMesh = !combineMeshs.slotNames.Contains(slotData.name); } } } slot.Init(slotData, armature, gameObject, gameObject); if (isNeedIngoreCombineMesh) { slot.DisallowCombineMesh(); } return slot; } /// /// Create a armature from cached DragonBonesData instances and TextureAtlasData instances, then use the {@link #clock} to update it. /// The difference is that the armature created by {@link #buildArmature} is not WorldClock instance update. /// /// The armature data name /// The cached name of the DragonBonesData instance (If not set, all DragonBonesData instances are retrieved, and when multiple DragonBonesData instances contain a the same name armature data, it may not be possible to accurately create a specific armature) /// The skin name, you can set a different ArmatureData name to share it's skin data (If not set, use the default skin data) /// The textureAtlas name /// /// isUGUI default is false /// The armature display container. /// DragonBones 4.5 /// en_US /// /// 通过缓存的 DragonBonesData 实例和 TextureAtlasData 实例创建一个骨架,并用 {@link #clock} 更新该骨架。 /// 区别在于由 {@link #buildArmature} 创建的骨架没有 WorldClock 实例驱动。 /// /// 骨架数据名称。 /// 实例的缓存名称 (如果未设置,将检索所有的 DragonBonesData 实例,当多个 DragonBonesData 实例中包含同名的骨架数据时,可能无法准确的创建出特定的骨架) /// 皮肤名称,可以设置一个其他骨架数据名称来共享其皮肤数据(如果未设置,则使用默认的皮肤数据) /// 贴图集名称 /// 骨甲容器,如果未设置,则自动创建 /// isUGUI 是否是UGUI,默认为false /// 骨架的显示容器。 /// DragonBones 4.5 /// zh_CN public UnityArmatureComponent BuildArmatureComponent(string armatureName, string dragonBonesName = "", string skinName = "", string textureAtlasName = "", GameObject gameObject = null, bool isUGUI = false) { _armatureGameObject = gameObject; _isUGUI = isUGUI; var armature = BuildArmature(armatureName, dragonBonesName, skinName, textureAtlasName); if (armature != null) { _dragonBones.clock.Add(armature); var armatureDisplay = armature.display as GameObject; var armatureComponent = armatureDisplay.GetComponent(); return armatureComponent; } return null; } /** * @language zh_CN * 获取带有指定贴图的显示对象。 * @param textureName 指定的贴图名称。 * @param textureAtlasName 指定的龙骨数据名称,如果未设置,将检索所有的龙骨数据。 * @version DragonBones 3.0 */ public GameObject GetTextureDisplay(string textureName, string textureAtlasName = null) { /*var textureData = _getTextureData(textureAtlasName, textureName) as UnityTextureData; if (textureData != null) { if (textureData.texture == null) { var textureAtlasTexture = (textureData.parent as UnityTextureAtlasData).texture; var rect = new Rect( textureData.region.x, textureAtlasTexture.height - textureData.region.y - textureData.region.height, textureData.region.width, textureData.region.height ); textureData.texture = Sprite.Create(textureAtlasTexture, rect, new Vector2(), 1.0f); } var gameObject = new GameObject(); gameObject.AddComponent().sprite = textureData.texture; return gameObject; }*/ return null; } /// protected void _RefreshTextureAtlas(UnityTextureAtlasData textureAtlasData, bool isUGUI, bool isEditor = false) { Material material = null; if (isUGUI && textureAtlasData.uiTexture == null) { if (isEditor) { #if UNITY_EDITOR if (!Application.isPlaying) { material = AssetDatabase.LoadAssetAtPath(textureAtlasData.imagePath + "_UI_Mat.mat"); } #endif } else { material = Resources.Load(textureAtlasData.imagePath + "_UI_Mat"); } if (material == null) { Texture2D textureAtlas = null; if (isEditor) { #if UNITY_EDITOR if (!Application.isPlaying) { textureAtlas = AssetDatabase.LoadAssetAtPath(textureAtlasData.imagePath + ".png"); } #endif } else { textureAtlas = Resources.Load(textureAtlasData.imagePath); } material = UnityFactoryHelper.GenerateMaterial(defaultUIShaderName, textureAtlas.name + "_UI_Mat", textureAtlas); if (textureAtlasData.width < 2) { textureAtlasData.width = (uint)textureAtlas.width; } if (textureAtlasData.height < 2) { textureAtlasData.height = (uint)textureAtlas.height; } textureAtlasData._disposeEnabled = true; #if UNITY_EDITOR if (!Application.isPlaying) { string path = AssetDatabase.GetAssetPath(textureAtlas); path = path.Substring(0, path.Length - 4); AssetDatabase.CreateAsset(material, path + "_UI_Mat.mat"); AssetDatabase.SaveAssets(); } #endif } // textureAtlasData.uiTexture = material; } else if (!isUGUI && textureAtlasData.texture == null) { if (isEditor) { #if UNITY_EDITOR if (!Application.isPlaying) { material = AssetDatabase.LoadAssetAtPath(textureAtlasData.imagePath + "_Mat.mat"); } #endif } else { material = Resources.Load(textureAtlasData.imagePath + "_Mat"); } if (material == null) { Texture2D textureAtlas = null; if (isEditor) { #if UNITY_EDITOR if (!Application.isPlaying) { textureAtlas = AssetDatabase.LoadAssetAtPath(textureAtlasData.imagePath + ".png"); } #endif } else { textureAtlas = Resources.Load(textureAtlasData.imagePath); } material = UnityFactoryHelper.GenerateMaterial(defaultShaderName, textureAtlas.name + "_Mat", textureAtlas); if (textureAtlasData.width < 2) { textureAtlasData.width = (uint)textureAtlas.width; } if (textureAtlasData.height < 2) { textureAtlasData.height = (uint)textureAtlas.height; } textureAtlasData._disposeEnabled = true; #if UNITY_EDITOR if (!Application.isPlaying) { string path = AssetDatabase.GetAssetPath(textureAtlas); path = path.Substring(0, path.Length - 4); AssetDatabase.CreateAsset(material, path + "_Mat.mat"); AssetDatabase.SaveAssets(); } #endif } textureAtlasData.texture = material; } } /// public override void Clear(bool disposeData = true) { base.Clear(disposeData); _armatureGameObject = null; _isUGUI = false; // _cacheUnityDragonBonesData.Clear(); } /// /// A global sound event manager. /// Sound events can be listened to uniformly from the manager. /// /// DragonBones 4.5 /// zh_CN /// /// 全局声音事件管理器。 /// 声音事件可以从该管理器统一侦听。 /// /// DragonBones 4.5 /// zh_CN public IEventDispatcher soundEventManager { get { return _dragonBonesInstance.eventManager; } } /// /// Parse the UnityDragonBonesData to a DragonBonesData instance and cache it to the factory. /// /// The UnityDragonBonesData data /// is UGUI /// The armature scale /// The texture scale /// /// DragonBones 4.5 /// en_US /// /// 将UnityDragonBonesData数据解析为 DragonBonesData 实例,并缓存到工厂中。 /// /// 龙骨数据 /// 是否是UGUI /// 骨架缩放值 /// 贴图缩放值 /// /// DragonBones 4.5 /// zh_CN public DragonBonesData LoadData(UnityDragonBonesData data, bool isUGUI = false, float armatureScale = 0.01f, float texScale = 1.0f) { DragonBonesData dragonBonesData = null; if (data.dragonBonesJSON != null) { dragonBonesData = LoadDragonBonesData(data.dragonBonesJSON, data.dataName, armatureScale); if (!string.IsNullOrEmpty(data.dataName) && dragonBonesData != null && data.textureAtlas != null) { #if UNITY_EDITOR bool isDirty = false; if (!Application.isPlaying) { for (int i = 0; i < data.textureAtlas.Length; ++i) { if (isUGUI) { if (data.textureAtlas[i].uiMaterial == null) { isDirty = true; break; } } else { if (data.textureAtlas[i].material == null) { isDirty = true; break; } } } } #endif var textureAtlasDatas = this.GetTextureAtlasData(data.dataName); if (textureAtlasDatas != null) { for (int i = 0, l = textureAtlasDatas.Count; i < l; ++i) { if (i < data.textureAtlas.Length) { var textureAtlasData = textureAtlasDatas[i] as UnityTextureAtlasData; var textureAtlas = data.textureAtlas[i]; textureAtlasData.uiTexture = textureAtlas.uiMaterial; textureAtlasData.texture = textureAtlas.material; #if UNITY_EDITOR if (!Application.isPlaying) { textureAtlasData.imagePath = AssetDatabase.GetAssetPath(textureAtlas.texture); textureAtlasData.imagePath = textureAtlasData.imagePath.Substring(0, textureAtlasData.imagePath.Length - 4); _RefreshTextureAtlas(textureAtlasData, isUGUI, true); if (isUGUI) { textureAtlas.uiMaterial = textureAtlasData.uiTexture; } else { textureAtlas.material = textureAtlasData.texture; } } #endif } } } else { for (int i = 0; i < data.textureAtlas.Length; ++i) { LoadTextureAtlasData(data.textureAtlas[i], data.dataName, texScale, isUGUI); } } #if UNITY_EDITOR if (isDirty) { AssetDatabase.Refresh(); EditorUtility.SetDirty(data); AssetDatabase.SaveAssets(); } #endif } } return dragonBonesData; } /// /// Parse the raw data to a DragonBonesData instance and cache it to the factory. /// /// The path of dragonBones data in Resources. (other forms of loading can be extended by themselves) /// Specify a cache name for the instance so that the instance can be obtained through this name. (If not set, use the instance name instead) /// Specify a scaling value for all armatures. (Default does not scale) /// DragonBonesData instance /// DragonBones 4.5 /// en_US /// /// 将原始数据解析为 DragonBonesData 实例,并缓存到工厂中。 /// /// 龙骨数据在 Resources 中的路径。(其他形式的加载可自行扩展) /// 为该实例指定一个缓存名称,以便可以通过此名称获取该实例。 (如果未设置,则使用该实例中的名称) /// 为所有的骨架指定一个缩放值。 (默认不缩放) /// 龙骨数据 /// DragonBones 4.5 /// zh_CN public DragonBonesData LoadDragonBonesData(string dragonBonesJSONPath, string name = "", float scale = 0.01f) { dragonBonesJSONPath = UnityFactoryHelper.CheckResourecdPath(dragonBonesJSONPath); TextAsset dragonBonesJSON = Resources.Load(dragonBonesJSONPath); DragonBonesData dragonBonesData = LoadDragonBonesData(dragonBonesJSON, name); return dragonBonesData; } /// /// Parse the json data to a DragonBonesData instance and cache it to the factory. /// /// The jsonData of dragonBones /// Specify a cache name for the instance so that the instance can be obtained through this name. (If not set, use the instance name instead) /// Specify a scaling value for all armatures. (Default does not scale) /// DragonBonesData instance /// DragonBones 4.5 /// en_US /// /// 将json数据解析为 DragonBonesData 实例,并缓存到工厂中。 /// /// 龙骨的json数据。 /// 为该实例指定一个缓存名称,以便可以通过此名称获取该实例。 (如果未设置,则使用该实例中的名称) /// 为所有的骨架指定一个缩放值。 (默认不缩放) /// 龙骨数据 /// DragonBones 4.5 /// zh_CN public DragonBonesData LoadDragonBonesData(TextAsset dragonBonesJSON, string name = "", float scale = 0.01f) { if (dragonBonesJSON == null) { return null; } if (!string.IsNullOrEmpty(name)) { var existedData = GetDragonBonesData(name); if (existedData != null) { return existedData; } } DragonBonesData data = null; if (dragonBonesJSON.text == "DBDT") { BinaryDataParser.jsonParseDelegate = MiniJSON.Json.Deserialize; data = ParseDragonBonesData(dragonBonesJSON.bytes, name, scale); // Unity default Scale Factor. } else { data = ParseDragonBonesData((Dictionary)MiniJSON.Json.Deserialize(dragonBonesJSON.text), name, scale); // Unity default Scale Factor. } // name = !string.IsNullOrEmpty(name) ? name : data.name; // _dragonBonesDataMap[name] = data; return data; } /// /// Parse the textureAtlas json data to a UnityTextureAtlasData instance and cache it to the factory. /// /// The path of dragonBones data in Resources. (other forms of loading can be extended by themselves. use factory.ParseTextureAtlasData(JSONObject, Material)) /// Specify a cache name for the instance so that the instance can be obtained through this name. (If not set, use the instance name instead) /// Specify a scaling value for textureAtlas. (Default does not scale) /// /// /// DragonBones 4.5 /// en_US /// /// 将贴图集json数据解析为UnityTextureAtlasData,并缓存到工厂中。 /// /// 贴图集数据在 Resources 中的路径。(其他形式的加载可自行扩展,使用 factory.ParseTextureAtlasData(JSONObject, Material)) /// 为数据指定一个名称,以便可以通过这个名称获取数据,如果未设置,则使用数据中的名称。 /// 为贴图集设置一个缩放值。 /// /// 贴图集数据 /// DragonBones 4.5 /// zh_CN public UnityTextureAtlasData LoadTextureAtlasData(string textureAtlasJSONPath, string name = "", float scale = 1.0f, bool isUGUI = false) { textureAtlasJSONPath = UnityFactoryHelper.CheckResourecdPath(textureAtlasJSONPath); TextAsset textureAtlasJSON = Resources.Load(textureAtlasJSONPath); // if (textureAtlasJSON != null) { Dictionary textureJSONData = (Dictionary)MiniJSON.Json.Deserialize(textureAtlasJSON.text); UnityTextureAtlasData textureAtlasData = ParseTextureAtlasData(textureJSONData, null, name, scale) as UnityTextureAtlasData; if (textureAtlasData != null) { textureAtlasData.imagePath = UnityFactoryHelper.GetTextureAtlasImagePath(textureAtlasJSONPath, textureAtlasData.imagePath); _RefreshTextureAtlas(textureAtlasData, isUGUI); } return textureAtlasData; } return null; } /// /// Parse the TextureAtlas to a UnityTextureAtlasData instance and cache it to the factory. /// /// The path of dragonBones data in Resources. (other forms of loading can be extended by themselves. use factory.ParseTextureAtlasData(JSONObject, Material)) /// Specify a cache name for the instance so that the instance can be obtained through this name. (If not set, use the instance name instead) /// Specify a scaling value for textureAtlas. (Default does not scale) /// /// /// DragonBones 4.5 /// en_US /// /// 将TextureAtlas解析为UnityTextureAtlasData,并缓存到工厂中。 /// /// /// 为数据指定一个名称,以便可以通过这个名称获取数据,如果未设置,则使用数据中的名称。 /// 为贴图集设置一个缩放值。 /// /// /// DragonBones 4.5 /// zh_CN public UnityTextureAtlasData LoadTextureAtlasData(UnityDragonBonesData.TextureAtlas textureAtlas, string name, float scale = 1.0f, bool isUGUI = false) { Dictionary textureJSONData = (Dictionary)MiniJSON.Json.Deserialize(textureAtlas.textureAtlasJSON.text); UnityTextureAtlasData textureAtlasData = ParseTextureAtlasData(textureJSONData, null, name, scale) as UnityTextureAtlasData; if (textureJSONData.ContainsKey("width")) { textureAtlasData.width = uint.Parse(textureJSONData["width"].ToString()); } if (textureJSONData.ContainsKey("height")) { textureAtlasData.height = uint.Parse(textureJSONData["height"].ToString()); } if (textureAtlasData != null) { textureAtlasData.uiTexture = textureAtlas.uiMaterial; textureAtlasData.texture = textureAtlas.material; #if UNITY_EDITOR if (!Application.isPlaying) { textureAtlasData.imagePath = AssetDatabase.GetAssetPath(textureAtlas.texture); textureAtlasData.imagePath = textureAtlasData.imagePath.Substring(0, textureAtlasData.imagePath.Length - 4); _RefreshTextureAtlas(textureAtlasData, isUGUI, true); if (isUGUI) { textureAtlas.uiMaterial = textureAtlasData.uiTexture; } else { textureAtlas.material = textureAtlasData.texture; } } #endif } return textureAtlasData; } /// /// Refresh the Armature textureAtlas data. /// /// UnityArmatureComponent /// DragonBones 4.5 /// en_US /// /// 刷新骨架的贴图集数据。 /// /// 骨架 /// DragonBones 4.5 /// zh_CN public void RefreshAllTextureAtlas(UnityArmatureComponent unityArmature) { foreach (var textureAtlasDatas in _textureAtlasDataMap.Values) { foreach (UnityTextureAtlasData textureAtlasData in textureAtlasDatas) { _RefreshTextureAtlas(textureAtlasData, unityArmature.isUGUI); } } } /// public override void ReplaceDisplay(Slot slot, DisplayData displayData, int displayIndex = -1) { //UGUI Display Object and Normal Display Object cannot be replaced with each other if (displayData.type == DisplayType.Image || displayData.type == DisplayType.Mesh) { var dataName = displayData.parent.parent.parent.name; var textureData = this._GetTextureData(dataName, displayData.path); if (textureData != null) { var textureAtlasData = textureData.parent as UnityTextureAtlasData; var oldIsUGUI = (slot._armature.proxy as UnityArmatureComponent).isUGUI; if ((oldIsUGUI && textureAtlasData.uiTexture == null) || (!oldIsUGUI && textureAtlasData.texture == null)) { LogHelper.LogWarning("ugui display object and normal display object cannot be replaced with each other"); return; } } } base.ReplaceDisplay(slot, displayData, displayIndex); } /// /// 用特定的显示对象数据替换特定插槽当前的显示对象数据。 /// /// The DragonBonesData instance cache name /// The armature data name /// The slot data name /// The display data name /// The slot /// The new texture /// The new material /// is ugui。 /// The index of the display data that is replaced. (If it is not set, replaces the current display data) /// DragonBones 4.5 /// zh_CN /// /// 用特定的显示对象数据替换特定插槽当前的显示对象数据。 /// /// 指定的龙骨数据名称。 /// 指定的骨架名称。 /// 指定的插槽名称。 /// 指定的显示对象名称。 /// 指定的插槽实例。 /// 新的贴图。 /// 新的材质。 /// 是否为ugui。 /// 被替换的显示对象数据的索引。 (如果未设置,则替换当前的显示对象数据)。 /// DragonBones 4.5 /// zh_CN public void ReplaceSlotDisplay( string dragonBonesName, string armatureName, string slotName, string displayName, Slot slot, Texture2D texture, Material material = null, bool isUGUI = false, int displayIndex = -1) { var armatureData = this.GetArmatureData(armatureName, dragonBonesName); if (armatureData == null || armatureData.defaultSkin == null) { return; } var displays = armatureData.defaultSkin.GetDisplays(slotName); if (displays == null) { return; } DisplayData prevDispalyData = null; foreach (var displayData in displays) { if (displayData.name == displayName) { prevDispalyData = displayData; break; } } if (prevDispalyData == null || !((prevDispalyData is ImageDisplayData) || (prevDispalyData is MeshDisplayData))) { return; } TextureData prevTextureData = null; if(prevDispalyData is ImageDisplayData) { prevTextureData = (prevDispalyData as ImageDisplayData).texture; } else { prevTextureData = (prevDispalyData as MeshDisplayData).texture; } UnityTextureData newTextureData = new UnityTextureData(); newTextureData.CopyFrom(prevTextureData); newTextureData.rotated = false; newTextureData.region.x = 0.0f; newTextureData.region.y = 0.0f; newTextureData.region.width = texture.width; newTextureData.region.height = texture.height; newTextureData.frame = newTextureData.region; newTextureData.name = prevTextureData.name; newTextureData.parent = new UnityTextureAtlasData(); newTextureData.parent.width = (uint)texture.width; newTextureData.parent.height = (uint)texture.height; newTextureData.parent.scale = prevTextureData.parent.scale; // if (material == null) { if (isUGUI) { material = UnityFactoryHelper.GenerateMaterial(defaultUIShaderName, texture.name + "_UI_Mat", texture); } else { material = UnityFactoryHelper.GenerateMaterial(defaultShaderName, texture.name + "_Mat", texture); } } if (isUGUI) { (newTextureData.parent as UnityTextureAtlasData).uiTexture = material; } else { (newTextureData.parent as UnityTextureAtlasData).texture = material; } material.mainTexture = texture; DisplayData newDisplayData = null; if (prevDispalyData is ImageDisplayData) { newDisplayData = new ImageDisplayData(); newDisplayData.type = prevDispalyData.type; newDisplayData.name = prevDispalyData.name; newDisplayData.path = prevDispalyData.path; newDisplayData.transform.CopyFrom(prevDispalyData.transform); newDisplayData.parent = prevDispalyData.parent; (newDisplayData as ImageDisplayData).pivot.CopyFrom((prevDispalyData as ImageDisplayData).pivot); (newDisplayData as ImageDisplayData).texture = newTextureData; } else if (prevDispalyData is MeshDisplayData) { newDisplayData = new MeshDisplayData(); newDisplayData.type = prevDispalyData.type; newDisplayData.name = prevDispalyData.name; newDisplayData.path = prevDispalyData.path; newDisplayData.transform.CopyFrom(prevDispalyData.transform); newDisplayData.parent = prevDispalyData.parent; (newDisplayData as MeshDisplayData).texture = newTextureData; (newDisplayData as MeshDisplayData).vertices.inheritDeform = (prevDispalyData as MeshDisplayData).vertices.inheritDeform; (newDisplayData as MeshDisplayData).vertices.offset = (prevDispalyData as MeshDisplayData).vertices.offset; (newDisplayData as MeshDisplayData).vertices.data = (prevDispalyData as MeshDisplayData).vertices.data; (newDisplayData as MeshDisplayData).vertices.weight = (prevDispalyData as MeshDisplayData).vertices.weight; } ReplaceDisplay(slot, newDisplayData, displayIndex); } // public UnityDragonBonesData GetCacheUnityDragonBonesData(string draonBonesName) { if (string.IsNullOrEmpty(draonBonesName)) { return null; } for (int i = 0; i < this._cacheUnityDragonBonesData.Count; i++) { if (this._cacheUnityDragonBonesData[i].dataName == draonBonesName) { return this._cacheUnityDragonBonesData[i]; } } return null; } public void AddCacheUnityDragonBonesData(UnityDragonBonesData unityData) { for (int i = 0; i < this._cacheUnityDragonBonesData.Count; i++) { if (this._cacheUnityDragonBonesData[i].dataName == unityData.dataName) { this._cacheUnityDragonBonesData[i] = unityData; return; } } this._cacheUnityDragonBonesData.Add(unityData); } } /// /// UnityFactory 辅助类 /// internal static class UnityFactoryHelper { /// /// 生成一个材质球 /// /// /// /// /// internal static Material GenerateMaterial(string shaderName, string materialName, Texture texture) { //创建材质球 Shader shader = Shader.Find(shaderName); Material material = new Material(shader); material.name = materialName; material.mainTexture = texture; return material; } /// /// 检查路径合法性 /// /// /// internal static string CheckResourecdPath(string path) { var index = path.LastIndexOf("Resources"); if (index > 0) { path = path.Substring(index + 10); } index = path.LastIndexOf("."); if (index > 0) { path = path.Substring(0, index); } return path; } /// /// 根据贴图JSON文件的路径和JSON文件中贴图名称获得贴图路径 /// /// 贴图JSON文件路径:NewDragon/NewDragon_tex /// 贴图名称:NewDragon.png /// internal static string GetTextureAtlasImagePath(string textureAtlasJSONPath, string textureAtlasImageName) { var index = textureAtlasJSONPath.LastIndexOf("Resources"); if (index > 0) { textureAtlasJSONPath = textureAtlasJSONPath.Substring(index + 10); } index = textureAtlasJSONPath.LastIndexOf("/"); string textureAtlasImagePath = textureAtlasImageName; if (index > 0) { textureAtlasImagePath = textureAtlasJSONPath.Substring(0, index + 1) + textureAtlasImageName; } index = textureAtlasImagePath.LastIndexOf("."); if (index > 0) { textureAtlasImagePath = textureAtlasImagePath.Substring(0, index); } return textureAtlasImagePath; } /// /// 根据贴图路径获得贴图名称 /// /// /// internal static string GetTextureAtlasNameByPath(string textureAtlasJSONPath) { string name = string.Empty; int index = textureAtlasJSONPath.LastIndexOf("/") + 1; int lastIdx = textureAtlasJSONPath.LastIndexOf("_tex"); if (lastIdx > -1) { if (lastIdx > index) { name = textureAtlasJSONPath.Substring(index, lastIdx - index); } else { name = textureAtlasJSONPath.Substring(index); } } else { if (index > -1) { name = textureAtlasJSONPath.Substring(index); } } return name; } internal static void DestroyUnityObject(UnityEngine.Object obj) { if (obj == null) { return; } #if UNITY_EDITOR UnityEngine.Object.DestroyImmediate(obj); #else UnityEngine.Object.Destroy(obj); #endif } } internal static class LogHelper { internal static void LogWarning(object message) { UnityEngine.Debug.LogWarning("[DragonBones]" + message); } } }