/**
* 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);
}
}
}