// Fins the first texture atlas public static Uni2DTextureAtlas FindFirstTextureAtlas(string a_rTextureGUID) { Uni2DEditorAssetTable rAssetTable = Uni2DEditorAssetTable.Instance; Uni2DTextureAtlas rAtlas = null; bool bSaveTable = false; string[] rAtlasGUIDs = rAssetTable.GetAtlasGUIDsUsingThisTexture(a_rTextureGUID); foreach (string rAtlasGUID in rAtlasGUIDs) { rAtlas = Uni2DEditorUtils.GetAssetFromUnityGUID <Uni2DTextureAtlas>(rAtlasGUID); if (rAtlas != null && rAtlas.Contains(a_rTextureGUID)) { //rAtlas = null; break; } else { rAssetTable.RemoveAtlasUsingTexture(rAtlasGUID, a_rTextureGUID); bSaveTable = true; } } if (bSaveTable) { rAssetTable.Save( ); } return(rAtlas); }
// Deep copy constructor public Uni2DEditorSpriteSettings(Uni2DEditorSpriteSettings a_rSpriteSettings) { this.textureContainer = new Texture2DContainer(a_rSpriteSettings.textureContainer); // Deep copy this.atlas = a_rSpriteSettings.atlas; this.sharedMaterial = a_rSpriteSettings.sharedMaterial; this.renderMesh = a_rSpriteSettings.renderMesh; this.usePhysicBuildSettings = a_rSpriteSettings.usePhysicBuildSettings; this.spriteScale = a_rSpriteSettings.spriteScale; this.pivotType = a_rSpriteSettings.pivotType; this.pivotCustomCoords = a_rSpriteSettings.pivotCustomCoords; this.vertexColor = a_rSpriteSettings.vertexColor; this.physicsMode = a_rSpriteSettings.physicsMode; this.collisionType = a_rSpriteSettings.collisionType; this.isKinematic = a_rSpriteSettings.isKinematic; this.renderMeshAlphaCutOff = a_rSpriteSettings.renderMeshAlphaCutOff; this.renderMeshPolygonizationAccuracy = a_rSpriteSettings.renderMeshPolygonizationAccuracy; this.renderMeshPolygonizeHoles = a_rSpriteSettings.renderMeshPolygonizeHoles; this.alphaCutOff = a_rSpriteSettings.alphaCutOff; this.extrusionDepth = a_rSpriteSettings.extrusionDepth; this.polygonizationAccuracy = a_rSpriteSettings.polygonizationAccuracy; this.polygonizeHoles = a_rSpriteSettings.polygonizeHoles; this.renderMeshGridHorizontalSubDivs = a_rSpriteSettings.renderMeshGridHorizontalSubDivs; this.renderMeshGridVerticalSubDivs = a_rSpriteSettings.renderMeshGridVerticalSubDivs; this.skinQuality = a_rSpriteSettings.skinQuality; this.boneInfluenceFalloff = a_rSpriteSettings.boneInfluenceFalloff; }
// Awake private void Awake() { #if UNITY_EDITOR if (Application.isPlaying) #endif { m_rCurrentFrameAtlas = m_rSpriteSettings.atlas; m_rCurrentFrameTextureContainer = m_rSpriteSettings.textureContainer; m_iCurrentFrameTextureWidth = (int)m_rSpriteData.spriteWidth; m_iCurrentFrameTextureHeight = (int)m_rSpriteData.spriteHeight; spriteAnimation.Start(this); } #if UNITY_EDITOR // Is a prefab instance else if (IsADuplicate( )) { //Debug.Log("Duplicate"); Uni2DEditorResourceCopyUtils.DuplicateResources(this); } #endif // Create the duplicata marker if needed if (m_oDuplicataMarker == null || m_oDuplicataMarker.IsADuplicate(this)) { m_oDuplicataMarker = ScriptableObject.CreateInstance <DuplicataMarker>(); m_oDuplicataMarker.Create(this); } }
// Set sprite frame public static void SetSpriteFrame(Uni2DSprite a_rSpriteComponent, Texture2DContainer a_rTextureContainer, Uni2DTextureAtlas a_rTextureAtlas, float a_fWidth, float a_fHeight, bool a_bUpdateMesh, bool a_bUpdateUV) { MeshFilter rMeshFilter = a_rSpriteComponent.GetComponent<MeshFilter>( ); SkinnedMeshRenderer rSkinnedMeshRenderer = a_rSpriteComponent.GetComponent<SkinnedMeshRenderer>( ); // The mesh to update Mesh rSpriteMesh = a_rSpriteComponent.EditableRenderMesh; if( rSpriteMesh != null ) { if( a_bUpdateMesh ) { rSpriteMesh = UpdateSpriteMeshSizeForAnim(a_rSpriteComponent, rSpriteMesh, a_fWidth, a_fHeight); } UpdateMaterialForAnim( a_rSpriteComponent, a_rTextureContainer, a_rTextureAtlas ); if( a_bUpdateUV ) { // Rebuild UVs rSpriteMesh.uv = BuildUVs( a_rTextureContainer, a_rSpriteComponent.SpriteData.renderMeshUVs, a_rTextureAtlas ); } if( rSkinnedMeshRenderer != null && rSkinnedMeshRenderer.sharedMesh != rMeshFilter.sharedMesh ) { rSkinnedMeshRenderer.sharedMesh = rSpriteMesh; } } }
// Update material and texture private static void UpdateMaterialForAnim(Uni2DSprite a_rSpriteComponent, Texture2DContainer a_rTextureContainer, Uni2DTextureAtlas a_rTextureAtlas) { Material oSpriteMaterial = a_rSpriteComponent.SpriteData.renderMeshMaterial; if(a_rTextureAtlas == null) { Material rAnimationMaterial = a_rSpriteComponent.RuntimeData.animationMaterial; if( rAnimationMaterial != null ) { oSpriteMaterial = rAnimationMaterial; } else { // Instantiate the material to prevent other sprites using this material // to be animated too oSpriteMaterial = (Material) Material.Instantiate( oSpriteMaterial ); a_rSpriteComponent.RuntimeData.animationMaterial = oSpriteMaterial; } oSpriteMaterial.mainTexture = a_rTextureContainer; } else { oSpriteMaterial = a_rTextureAtlas.GetMaterial( a_rTextureContainer.GUID ); } Renderer rRenderer = a_rSpriteComponent.GetComponent<Renderer>(); if(rRenderer != null) { rRenderer.sharedMaterial = oSpriteMaterial; rRenderer.material = oSpriteMaterial; } }
// On enable void OnEnable( ) { Uni2DTextureAtlas rAtlas = target as Uni2DTextureAtlas; rAtlas.RevertSettings( ); ms_oAtlasMaterials = rAtlas.GetAllMaterials( ); ms_oAtlasTextures = rAtlas.GetAllAtlasTextures( ); }
// Copy Constructor public Uni2DAnimationFrame(Uni2DAnimationFrame a_rFrameSource) { name = a_rFrameSource.name; atlas = a_rFrameSource.atlas; triggerEvent = a_rFrameSource.triggerEvent; a_rFrameSource.frameInfos.CopyTo(frameInfos); textureContainer = new Texture2DContainer(a_rFrameSource.textureContainer.GUID, atlas == null); }
private static void ApplySettings(Uni2DAnimationClip[] a_rAnimationClips, AnimationClipRegeneration a_eRegenerate) { int iClipCount = a_rAnimationClips.Length; if (iClipCount == 1) { a_rAnimationClips[0].ApplySettings(a_eRegenerate); } else if (iClipCount > 1) { // Apply clip settings first, atlases will be generated only after // (Atlases can be shared accross clips, so prevent them to be uselessly regenerated several times) HashSet <Uni2DTextureAtlas> oAtlases = new HashSet <Uni2DTextureAtlas>( ); for (int iClipIndex = 0; iClipIndex < iClipCount; ++iClipIndex) { Uni2DAnimationClip rAnimationClip = a_rAnimationClips[iClipIndex]; Uni2DTextureAtlas rGlobalAtlas = rAnimationClip.globalAtlas; if (rGlobalAtlas != null) { // Add the atlas if not already added if (a_eRegenerate == AnimationClipRegeneration.RegenerateAll || (a_eRegenerate == AnimationClipRegeneration.RegenerateAlsoAtlasIfNeeded && (rGlobalAtlas.UnappliedSettings || rGlobalAtlas.Contains(rAnimationClip.GetAllFramesTextureGUIDs( )) == false))) { oAtlases.Add(rGlobalAtlas); } } else // Null => atlas per frame { for (int iFrameIndex = 0, iFrameCount = rAnimationClip.FrameCount; iFrameIndex < iFrameCount; ++iFrameIndex) { Uni2DAnimationFrame rFrame = rAnimationClip.frames[iFrameIndex]; Uni2DTextureAtlas rFrameAtlas = rFrame.atlas; if (rFrameAtlas != null && (a_eRegenerate == AnimationClipRegeneration.RegenerateAll || (a_eRegenerate == AnimationClipRegeneration.RegenerateAlsoAtlasIfNeeded && (rFrameAtlas.UnappliedSettings || rFrameAtlas.Contains(rFrame.textureContainer.GUID) == false)))) { oAtlases.Add(rFrameAtlas); } } } // Regenerate clips only rAnimationClip.ApplySettings(AnimationClipRegeneration.RegenerateAnimationClipOnly); } // Then, regenerate atlases foreach (Uni2DTextureAtlas rAtlas in oAtlases) { rAtlas.ApplySettings( ); } } }
private static void ApplySettings(Uni2DTextureAtlas a_rAtlas) { if (a_rAtlas.ApplySettings( ) == false) { EditorUtility.DisplayDialog("Uni2D Texture Atlasing", "Uni2D could not pack all the specified textures into '" + a_rAtlas.name + "'.\n" + "Please check the maximum allowed atlas size and the input textures.", "OK"); } }
public static Vector2[ ] BuildUVs( Texture2DContainer a_rTextureContainer, Vector2[ ] a_rRenderMeshUVs, Uni2DTextureAtlas a_rTextureAtlas ) { // UV data Rect oUVRect; bool bIsUVRectFlipped; // No atlas if( a_rTextureAtlas == null ) { oUVRect = new Rect( 0.0f, 0.0f, 1.0f, 1.0f ); bIsUVRectFlipped = false; } else if( !string.IsNullOrEmpty( a_rTextureContainer.GUID ) && a_rTextureAtlas.GetUVs( a_rTextureContainer.GUID, out oUVRect, out bIsUVRectFlipped ) == false ) // Atlas { // Not found in atlas!!! Debug.LogError( "Uni2D: Atlas \'" + a_rTextureAtlas.name + "\' does not contain the texture with GUID \'" + a_rTextureContainer.GUID + "\'." + "\nCheck your animation clip and atlas settings.", a_rTextureAtlas ); } Vector2[ ] oMeshUVs = a_rRenderMeshUVs; int iVertexCount = oMeshUVs.Length; // UV normalization (computes mesh UVs coords in atlas UVs space) Vector2[ ] oNormalizedMeshUVs = new Vector2[ iVertexCount ]; Vector2 f2UVOffset; // Position (== min coords) of sprite UV rect in atlas. (0;0) if not atlased Vector2 f2UVRange; // UV range (== max coords - position) in atlas. (1;1) if not atlased // If UV rect is not flipped... if( bIsUVRectFlipped == false ) { f2UVOffset = new Vector2( oUVRect.xMin, oUVRect.yMin ); f2UVRange = new Vector2( oUVRect.xMax, oUVRect.yMax ) - f2UVOffset; for( int iUVIndex = 0; iUVIndex < iVertexCount; ++iUVIndex ) { oNormalizedMeshUVs[ iUVIndex ] = f2UVOffset + Vector2.Scale( f2UVRange, oMeshUVs[ iUVIndex ] ); } } else // UV rect is flipped { f2UVOffset = new Vector2( oUVRect.xMax, oUVRect.yMin ); f2UVRange = new Vector2( oUVRect.xMin, oUVRect.yMax ) - f2UVOffset; for( int iUVIndex = 0; iUVIndex < iVertexCount; ++iUVIndex ) { Vector2 f2UV = oMeshUVs[ iUVIndex ]; // Need to swap UV coords oNormalizedMeshUVs[ iUVIndex ] = f2UVOffset + new Vector2( f2UVRange.x * f2UV.y, f2UVRange.y * f2UV.x ); } } return oNormalizedMeshUVs; }
// On destroy void OnDisable( ) { Uni2DTextureAtlas rAtlas = target as Uni2DTextureAtlas; if (rAtlas.UnappliedSettings) { ms_oAtlasesWithUnappliedSettings.Enqueue(rAtlas); EditorApplication.delayCall += Uni2DTextureAtlasInspector.AskAboutUnappliedSettings; } }
// Creates a new sprite settings with the given texture. // If the a_bPhysic argument is set to true, the settings will // depict a physical sprite public Uni2DEditorSpriteSettings(Texture2D a_rTexture2D, bool a_bPhysic = false) { this.textureContainer = new Texture2DContainer(a_rTexture2D, true); atlas = Uni2DEditorUtils.FindFirstTextureAtlas(textureContainer.GUID); // Set physic mode accordingly to given argument this.physicsMode = a_bPhysic ? PhysicsMode.Dynamic : PhysicsMode.NoPhysics; }
private void ApplySettings( ) { if (target != null) { Uni2DTextureAtlas rAtlas = (Uni2DTextureAtlas)target; Uni2DTextureAtlasInspector.ApplySettings(rAtlas); ms_oAtlasMaterials = rAtlas.GetAllMaterials( ); ms_oAtlasTextures = rAtlas.GetAllAtlasTextures( ); } }
// Generate atlas private void GenerateAtlas(AnimationClipRegeneration a_eRegeneration) { int iFrameCount = this.FrameCount; if (globalAtlas != null) // global atlas { string[] oTextureGUIDs = this.GetAllFramesTextureGUIDs( ); if (a_eRegeneration == AnimationClipRegeneration.RegenerateAll || (a_eRegeneration == AnimationClipRegeneration.RegenerateAlsoAtlasIfNeeded && (globalAtlas.UnappliedSettings || globalAtlas.Contains(oTextureGUIDs) == false))) { globalAtlas.ApplySettings( ); } globalAtlas.AddTextures(oTextureGUIDs); } else // Atlas per frame { HashSet <Uni2DTextureAtlas> oFrameAtlases = new HashSet <Uni2DTextureAtlas>( ); for (int iFrameIndex = 0; iFrameIndex < iFrameCount; ++iFrameIndex) { Uni2DAnimationFrame rFrame = frames[iFrameIndex]; Uni2DTextureAtlas rFrameAtlas = rFrame.atlas; if (rFrameAtlas != null) { string oFrameTextureGUID = rFrame.textureContainer != null ? rFrame.textureContainer.GUID : null; if (a_eRegeneration == AnimationClipRegeneration.RegenerateAll || (a_eRegeneration == AnimationClipRegeneration.RegenerateAlsoAtlasIfNeeded && (rFrameAtlas.UnappliedSettings || rFrameAtlas.Contains(oFrameTextureGUID) == false))) { oFrameAtlases.Add(rFrameAtlas); } rFrameAtlas.AddTextures(new string[1] { oFrameTextureGUID }); } } // Regenerate atlases foreach (Uni2DTextureAtlas rFrameAtlas in oFrameAtlases) { rFrameAtlas.ApplySettings( ); } } }
private void ApplyAnimationClipGlobalAtlas(Uni2DTextureAtlas a_rGlobalAtlas) { for (int iClipIndex = 0, iClipCount = this.targets.Length; iClipIndex < iClipCount; ++iClipIndex) { Uni2DAnimationClip rAnimationClip = (Uni2DAnimationClip)this.targets[iClipIndex]; rAnimationClip.globalAtlas = a_rGlobalAtlas; for (int iFrameIndex = 0, iFrameCount = rAnimationClip.FrameCount; iFrameIndex < iFrameCount; ++iFrameIndex) { rAnimationClip.frames[iFrameIndex].atlas = a_rGlobalAtlas; } EditorUtility.SetDirty(rAnimationClip); } }
// Revert settings public void RevertSettings( ) { wrapMode = m_eSavedWrapMode; frameRate = m_fSavedFrameRate; globalAtlas = m_rSavedGlobalAtlas; if (globalAtlas != null) { globalAtlas.RevertSettings( ); } CopyFrames(m_oSavedFrames, frames); // m_oFrames -> frames (revert) EditorUtility.SetDirty(this); AssetDatabase.SaveAssets( ); }
// Apply settings from inspector public void ApplySettings(AnimationClipRegeneration a_eRegeneration = AnimationClipRegeneration.RegenerateAlsoAtlasIfNeeded) { m_eSavedWrapMode = wrapMode; m_fSavedFrameRate = frameRate; m_rSavedGlobalAtlas = globalAtlas; if (a_eRegeneration != AnimationClipRegeneration.RegenerateNothing) { Generate(a_eRegeneration); // Generate frames infos (and atlas if needed/asked) CopyFrames(frames, m_oSavedFrames); // frames -> m_oFrames (apply) } EditorUtility.SetDirty(this); AssetDatabase.SaveAssets( ); }
// Because of an Unity bug(?), SerializedProperty.hasMultipleDifferentValues and objectReferenceValue properties are inconsistent when // handling Uni2D atlases. This method does it manually. private void GetGlobalAtlas(out Uni2DTextureAtlas a_rGlobalAtlas, out bool a_bHasMultipleDifferentGlobalAtlasValues) { int iTargetCount = this.targets.Length; a_rGlobalAtlas = ((Uni2DAnimationClip)targets[0]).globalAtlas; a_bHasMultipleDifferentGlobalAtlasValues = false; for (int iTargetIndex = 1; iTargetIndex < iTargetCount; ++iTargetIndex) { if (a_rGlobalAtlas != ((Uni2DAnimationClip)targets[iTargetIndex]).globalAtlas) { a_rGlobalAtlas = null; a_bHasMultipleDifferentGlobalAtlasValues = true; return; } } }
private static void AskAboutUnappliedSettings( ) { if (ms_oAtlasesWithUnappliedSettings.Count > 0) { Uni2DTextureAtlas rAtlas = ms_oAtlasesWithUnappliedSettings.Dequeue( ); bool bApply = EditorUtility.DisplayDialog("Unapplied atlas settings", "Unapplied settings for '" + rAtlas.name + "'", "Apply", "Revert"); if (bApply) { Uni2DTextureAtlasInspector.ApplySettings(rAtlas); } else { rAtlas.RevertSettings( ); } } }
// Displays a popup menu filled with all potential atlases for the given input textures // Displays all available atlases if a_rTexturesToContain is null // Manages the serialized settings update public static Uni2DTextureAtlas SerializedAtlasPopup(SerializedSetting <Uni2DTextureAtlas> a_rSerializedTextureAtlas, IEnumerable <string> a_rTextureGUIDsToContain = null) { Uni2DTextureAtlas rCurrentAtlas = a_rSerializedTextureAtlas.HasMultipleDifferentValues ? null : a_rSerializedTextureAtlas.Value; bool bSavedShowMixedValue = EditorGUI.showMixedValue; EditorGUI.showMixedValue = a_rSerializedTextureAtlas.HasMultipleDifferentValues; { EditorGUI.BeginChangeCheck( ); { rCurrentAtlas = Uni2DEditorGUIUtils.AtlasPopup(rCurrentAtlas, a_rTextureGUIDsToContain); } if (EditorGUI.EndChangeCheck( )) { a_rSerializedTextureAtlas.Value = rCurrentAtlas; } } EditorGUI.showMixedValue = bSavedShowMixedValue; return(rCurrentAtlas); }
// Set the frame draw by the sprite private void SetSpriteFrame(Texture2DContainer a_rTextureContainer, Uni2DTextureAtlas a_rTextureAtlas, int a_iWidth, int a_iHeight) { bool a_bUpdateMesh = false; if (m_iCurrentFrameTextureWidth != a_iWidth || m_iCurrentFrameTextureHeight != a_iHeight) { m_iCurrentFrameTextureWidth = a_iWidth; m_iCurrentFrameTextureHeight = a_iHeight; a_bUpdateMesh = true; } bool a_bUpdateUV = false; if (m_rCurrentFrameAtlas != a_rTextureAtlas || (m_rCurrentFrameAtlas != null && m_rCurrentFrameTextureContainer != a_rTextureContainer)) { m_rCurrentFrameTextureContainer = a_rTextureContainer; m_rCurrentFrameAtlas = a_rTextureAtlas; a_bUpdateUV = true; } Uni2DSpriteUtils.SetSpriteFrame(this, a_rTextureContainer, a_rTextureAtlas, a_iWidth, a_iHeight, a_bUpdateMesh, a_bUpdateUV); }
private static GameObject UpdateSpriteGameObject( GameObject a_rOutdatedSpriteGameObject, Texture2D a_rSpriteTexture, Uni2DTextureAtlas a_rTextureAtlas, Color a_oVertexColor, List<Mesh> a_rMeshCollidersList, float a_fAlphaCutOff, float a_fPolygonizationAccuracy, float a_fExtrusionDepth, float a_fScale, bool a_bPolygonizeHoles, Vector2 a_f2PivotPoint, Uni2DSprite.PivotPointType a_ePivotPoint, Uni2DSprite.PhysicMode a_ePhysicMode, Uni2DSprite.CollisionType a_eCollisionType, bool a_bIsKinematic ) { //Debug.Log("UpdateSpriteGameObject"); float fScale = a_fScale * mc_fToUnit; if(a_rSpriteTexture == null) { return a_rOutdatedSpriteGameObject; } // Sprite component Uni2DSprite rSpriteMeshComponent = a_rOutdatedSpriteGameObject.GetComponent<Uni2DSprite>( ); if( rSpriteMeshComponent == null ) { rSpriteMeshComponent = Uni2DSprite.Create(a_rOutdatedSpriteGameObject); } MeshFilter rSpriteQuadMeshFilterComponent = a_rOutdatedSpriteGameObject.GetComponent<MeshFilter>( ); if( rSpriteQuadMeshFilterComponent == null ) { rSpriteQuadMeshFilterComponent = a_rOutdatedSpriteGameObject.AddComponent<MeshFilter>( ); } MeshRenderer rSpriteQuadMeshRendererComponent = a_rOutdatedSpriteGameObject.GetComponent<MeshRenderer>( ); if( rSpriteQuadMeshRendererComponent == null ) { rSpriteQuadMeshRendererComponent = a_rOutdatedSpriteGameObject.AddComponent<MeshRenderer>( ); } Vector2 f2PivotPoint = ComputePivotPoint( a_rSpriteTexture, a_ePivotPoint, a_f2PivotPoint ); // Scale texture width/height float fScaledWidth = fScale * a_rSpriteTexture.width; float fScaledHeight = fScale * a_rSpriteTexture.height; // (Scaled) Quad mesh creation Mesh oSpriteQuadMesh = CreateTexturedQuadMesh(fScaledWidth, fScaledHeight, fScale * f2PivotPoint, rSpriteMeshComponent.VertexColor); oSpriteQuadMesh.name = "mesh_SpriteQuad" + a_rSpriteTexture.name; Material oSpriteRendererMaterial; Material oSpriteQuadMeshMaterial; if(rSpriteMeshComponent.spriteQuadMaterial != null) { oSpriteQuadMeshMaterial = new Material(rSpriteMeshComponent.spriteQuadMaterial); } else { // Quad mesh material creation oSpriteQuadMeshMaterial = new Material( Shader.Find( mc_oSpriteDefaultShader ) ); } oSpriteQuadMeshMaterial.name = "mat_SpriteQuad" + a_rSpriteTexture.name; oSpriteQuadMeshMaterial.mainTexture = a_rSpriteTexture; if(a_rTextureAtlas == null) { oSpriteRendererMaterial = oSpriteQuadMeshMaterial; } else { oSpriteRendererMaterial = a_rTextureAtlas.atlasMaterial; } // Sprite components init. rSpriteQuadMeshFilterComponent.sharedMesh = oSpriteQuadMesh; rSpriteQuadMeshRendererComponent.sharedMaterial = oSpriteRendererMaterial; List<MeshCollider> oMeshColliderComponentsList = new List<MeshCollider>( ); GameObject rColliderParentGameObject = null; // Add collider children // Attach a mesh collider collider to current game object // if collider is not compound if(a_ePhysicMode != Uni2DSprite.PhysicMode.NoPhysic) { if(a_eCollisionType != Uni2DSprite.CollisionType.Compound) { MeshCollider rMeshColliderComponent = a_rOutdatedSpriteGameObject.GetComponent<MeshCollider>( ); if( rMeshColliderComponent == null ) { rMeshColliderComponent = a_rOutdatedSpriteGameObject.AddComponent<MeshCollider>( ); } rMeshColliderComponent.sharedMesh = a_rMeshCollidersList[ 0 ]; oMeshColliderComponentsList.Add( rMeshColliderComponent ); // Set whether or not mesh collider is convex if(a_eCollisionType == Uni2DSprite.CollisionType.Concave) { rMeshColliderComponent.convex = false; } else { rMeshColliderComponent.convex = true; } } else // Dynamic Compound mode { rColliderParentGameObject = rSpriteMeshComponent.meshCollidersRootGameObject; if( rColliderParentGameObject == null ) { rColliderParentGameObject = new GameObject( "root_Colliders" ); } // Create a game object for each mesh collider and attach them to sprite game object for( int iColliderIndex = 0; iColliderIndex < a_rMeshCollidersList.Count; ++iColliderIndex ) { GameObject oMeshColliderGameObject = new GameObject( "mesh_Collider" + iColliderIndex ); MeshCollider oMeshColliderComponent = oMeshColliderGameObject.AddComponent<MeshCollider>( ); oMeshColliderComponent.sharedMesh = a_rMeshCollidersList[ iColliderIndex ]; oMeshColliderComponent.convex = true; oMeshColliderComponentsList.Add( oMeshColliderComponent ); // Child -> parent attachment oMeshColliderGameObject.transform.parent = rColliderParentGameObject.transform; oMeshColliderGameObject.transform.localPosition = Vector3.zero; oMeshColliderGameObject.transform.localRotation = Quaternion.identity; oMeshColliderGameObject.transform.localScale = Vector3.one; } rColliderParentGameObject.transform.parent = a_rOutdatedSpriteGameObject.transform; rColliderParentGameObject.transform.localPosition = Vector3.zero; rColliderParentGameObject.transform.localRotation = Quaternion.identity; rColliderParentGameObject.transform.localScale = Vector3.one; } // Add rigidbody to sprite game object if any dynamic mode is specified if(a_ePhysicMode != Uni2DSprite.PhysicMode.Static) { SetupRigidbodyFor2D(a_rOutdatedSpriteGameObject.AddComponent<Rigidbody>(), a_bIsKinematic); } } // Pivot sprite mesh component init. rSpriteMeshComponent.spriteTexture = a_rSpriteTexture; rSpriteMeshComponent.alphaCutOff = a_fAlphaCutOff; rSpriteMeshComponent.polygonizationAccuracy = a_fPolygonizationAccuracy; rSpriteMeshComponent.extrusionDepth = a_fExtrusionDepth; rSpriteMeshComponent.spriteScale = a_fScale; rSpriteMeshComponent.polygonizeHoles = a_bPolygonizeHoles; rSpriteMeshComponent.meshCollidersList = a_rMeshCollidersList; rSpriteMeshComponent.meshColliderComponentsList = oMeshColliderComponentsList; rSpriteMeshComponent.meshCollidersRootGameObject = rColliderParentGameObject; rSpriteMeshComponent.spriteQuadMesh = oSpriteQuadMesh; rSpriteMeshComponent.spriteQuadMaterial = oSpriteQuadMeshMaterial; rSpriteMeshComponent.textureAtlas = a_rTextureAtlas; rSpriteMeshComponent.VertexColor = a_oVertexColor; rSpriteMeshComponent.physicMode = a_ePhysicMode; rSpriteMeshComponent.collisionType = a_eCollisionType; rSpriteMeshComponent.isKinematic = a_bIsKinematic; rSpriteMeshComponent.spriteTextureWidth = a_rSpriteTexture.width; rSpriteMeshComponent.spriteTextureHeight = a_rSpriteTexture.height; rSpriteMeshComponent.pivotPointType = a_ePivotPoint; rSpriteMeshComponent.pivotPointCoords = f2PivotPoint; rSpriteMeshComponent.isPhysicDirty = false; UpdateUVs(rSpriteMeshComponent); rSpriteMeshComponent.AfterBuild(); return a_rOutdatedSpriteGameObject; }
// Awake private void Awake() { #if UNITY_EDITOR if( Application.isPlaying ) #endif { m_rCurrentFrameAtlas = m_rSpriteSettings.atlas; m_rCurrentFrameTextureContainer = m_rSpriteSettings.textureContainer; m_iCurrentFrameTextureWidth = (int)m_rSpriteData.spriteWidth; m_iCurrentFrameTextureHeight = (int)m_rSpriteData.spriteHeight; spriteAnimation.Start( this ); } #if UNITY_EDITOR // Is a prefab instance else if( IsADuplicate( ) ) { //Debug.Log("Duplicate"); Uni2DEditorResourceCopyUtils.DuplicateResources( this ); } #endif // Create the duplicata marker if needed if(m_oDuplicataMarker == null || m_oDuplicataMarker.IsADuplicate(this)) { m_oDuplicataMarker = ScriptableObject.CreateInstance<DuplicataMarker>(); m_oDuplicataMarker.Create(this); } }
// Revert settings public void RevertSettings( ) { wrapMode = m_eSavedWrapMode; frameRate = m_fSavedFrameRate; globalAtlas = m_rSavedGlobalAtlas; if( globalAtlas != null ) { globalAtlas.RevertSettings( ); } CopyFrames( m_oSavedFrames, frames ); // m_oFrames -> frames (revert) EditorUtility.SetDirty( this ); AssetDatabase.SaveAssets( ); }
// Creates a new sprite settings with the given texture. // If the a_bPhysic argument is set to true, the settings will // depict a physical sprite public Uni2DEditorSpriteSettings( Texture2D a_rTexture2D, bool a_bPhysic = false ) { this.textureContainer = new Texture2DContainer( a_rTexture2D, true ); atlas = Uni2DEditorUtils.FindFirstTextureAtlas( textureContainer.GUID ); // Set physic mode accordingly to given argument this.physicsMode = a_bPhysic ? PhysicsMode.Dynamic : PhysicsMode.NoPhysics; }
// Copy Constructor public Uni2DAnimationFrame(Uni2DAnimationFrame a_rFrameSource) { name = a_rFrameSource.name; atlas = a_rFrameSource.atlas; triggerEvent = a_rFrameSource.triggerEvent; a_rFrameSource.frameInfos.CopyTo( frameInfos ); textureContainer = new Texture2DContainer( a_rFrameSource.textureContainer.GUID, atlas == null ); }
private static void OnPostprocessAllAssets(string[] a_rImportedAssets, string[] a_rDeletedAssets, string[] a_rMovedAssets, string[] a_rMovedFromPath) { if (ms_bEnabled) { bool bUpdateAssets = false; bool bPostprocessPrefabs = false; bool bSaveTable = false; Uni2DEditorAssetTable rAssetTable = Uni2DEditorAssetTable.Instance; foreach (string rImportedAssetPath in a_rImportedAssets) { // Check if the asset isn't re-processed due to a call to GenerateTextureImportGUID if (ms_oImportedTexturesWithUpdatedUni2DGUIDs.Contains(rImportedAssetPath) == false) { Texture2D rImportedTexture = (Texture2D)AssetDatabase.LoadAssetAtPath(rImportedAssetPath, typeof(Texture2D)); if (rImportedTexture != null) { //Debug.Log ( "Imported " + rImportedAssetPath ); string rImportedTextureGUID = AssetDatabase.AssetPathToGUID(rImportedAssetPath); ms_oImportedTextureGUIDs.Add(rImportedTextureGUID); if (Uni2DEditorUtils.ItIsTheFirstTimeWeUseTheTexture(rImportedTexture)) { Uni2DEditorSpriteBuilderUtils.SetDefaultTextureImporterSettings(rImportedTexture, false); } // This call will produce an unvoidable import of the texture (didn't find out how to prevent it) Uni2DEditorUtils.GenerateTextureImportGUID(rImportedTexture); // ... so, save the path reference to avoid to re-process it again ms_oImportedTexturesWithUpdatedUni2DGUIDs.Add(rImportedAssetPath); bUpdateAssets = true; rImportedTexture = null; EditorUtility.UnloadUnusedAssets( ); continue; } Uni2DTextureAtlas rImportedAtlas = (Uni2DTextureAtlas)AssetDatabase.LoadAssetAtPath(rImportedAssetPath, typeof(Uni2DTextureAtlas)); if (rImportedAtlas != null) { //Debug.Log ( "Imported atlas " + rImportedAssetPath ); bSaveTable = true; rAssetTable.AddAtlasPath(rImportedAssetPath, AssetDatabase.AssetPathToGUID(rImportedAssetPath)); rImportedAtlas = null; EditorUtility.UnloadUnusedAssets( ); continue; } Uni2DAnimationClip rImportedClip = (Uni2DAnimationClip)AssetDatabase.LoadAssetAtPath(rImportedAssetPath, typeof(Uni2DAnimationClip)); if (rImportedClip != null) { //Debug.Log ( "Imported clip " + rImportedClip ); bSaveTable = true; rAssetTable.AddClipPath(rImportedAssetPath, AssetDatabase.AssetPathToGUID(rImportedAssetPath)); rImportedClip = null; EditorUtility.UnloadUnusedAssets( ); continue; } GameObject rImportedGameObject = (GameObject)AssetDatabase.LoadAssetAtPath(rImportedAssetPath, typeof(GameObject)); if (rImportedGameObject != null) { //Debug.Log ( "Imported game object " + rImportedAssetPath ); ms_oGameObjectGUIDsToPostProcess.Add(AssetDatabase.AssetPathToGUID(rImportedAssetPath)); bPostprocessPrefabs = true; rImportedGameObject = null; EditorUtility.UnloadUnusedAssets( ); } } else { // ... remove the asset path from our list if it was already processed ms_oImportedTexturesWithUpdatedUni2DGUIDs.Remove(rImportedAssetPath); } } // Moved assets for (int iIndex = 0, iCount = a_rMovedAssets.Length; iIndex < iCount; ++iIndex) { //Debug.Log ( "Importing moved asset" ); Uni2DTextureAtlas rMovedAtlas = (Uni2DTextureAtlas)AssetDatabase.LoadAssetAtPath(a_rMovedAssets[iIndex], typeof(Uni2DTextureAtlas)); if (rMovedAtlas != null) { rAssetTable.RemoveAtlasFromPath(a_rMovedFromPath[iIndex], false); rAssetTable.AddAtlasPath(a_rMovedAssets[iIndex], AssetDatabase.AssetPathToGUID(a_rMovedAssets[iIndex])); bSaveTable = true; rMovedAtlas = null; EditorUtility.UnloadUnusedAssets( ); continue; } Uni2DAnimationClip rMovedClip = (Uni2DAnimationClip)AssetDatabase.LoadAssetAtPath(a_rMovedAssets[iIndex], typeof(Uni2DAnimationClip)); if (rMovedClip != null) { rAssetTable.RemoveClipFromPath(a_rMovedFromPath[iIndex], false); rAssetTable.AddClipPath(a_rMovedAssets[iIndex], AssetDatabase.AssetPathToGUID(a_rMovedAssets[iIndex])); bSaveTable = true; rMovedClip = null; EditorUtility.UnloadUnusedAssets( ); } } // Deleted assets foreach (string rDeletedAsset in a_rDeletedAssets) { string[] rSpritePrefabGUIDs = rAssetTable.GetSpritePrefabGUIDsUsingThisAtlasPath(rDeletedAsset); if (rSpritePrefabGUIDs.Length > 0) { bUpdateAssets = true; ms_oSpritePrefabGUIDsToUpdate.UnionWith(rSpritePrefabGUIDs); } /* * // TODO: mettre des paths au lieu d'IDs * string[ ] rClipGUIDs = rAssetTable.GetClipGUIDsUsingThisTexturePath( rDeletedAsset ); * if( rClipGUIDs.Length > 0 ) * { * bUpdateAssets = true; * ms_oAnimationClipGUIDsToUpdate.UnionWith( rClipGUIDs ); * } */ bSaveTable = rAssetTable.RemoveAtlasFromPath(rDeletedAsset, true) || bSaveTable; bSaveTable = rAssetTable.RemoveClipFromPath(rDeletedAsset, true) || bSaveTable; } if (bSaveTable) { rAssetTable.Save( ); } if (bUpdateAssets) { ms_oAtlasGUIDsToUpdate.UnionWith(rAssetTable.GetAtlasGUIDsUsingTheseTextures(ms_oImportedTextureGUIDs)); ms_oAnimationClipGUIDsToUpdate.UnionWith(rAssetTable.GetClipGUIDsUsingTheseTextures(ms_oImportedTextureGUIDs)); ms_oSpritePrefabGUIDsToUpdate.UnionWith(rAssetTable.GetSpritePrefabGUIDsUsingTheseTextures(ms_oImportedTextureGUIDs)); ms_oSpritePrefabGUIDsToUpdate.UnionWith(rAssetTable.GetSpritePrefabGUIDsUsingTheseAtlases(ms_oAtlasGUIDsToUpdate)); EditorApplication.delayCall += UpdateUni2DAssets; } if (bPostprocessPrefabs) { EditorApplication.delayCall += OnSpritePrefabPostprocess; } } }
public static GameObject UpdateSpriteFromTexture( GameObject a_rOutdatedSpriteMeshGameObject, Texture2D a_rTextureToPolygonize, Uni2DTextureAtlas a_rTextureAtlas, Color a_oVertexColor, float a_fAlphaCutOff, float a_fPoligonizationAccuracy, float a_fExtrusionDepth, float a_fScale, bool a_bPolygonizeHoles, Vector2 a_f2CustomPivotPoint, Uni2DSprite.PivotPointType a_ePivotPoint, Uni2DSprite.PhysicMode a_ePhysicMode, Uni2DSprite.CollisionType a_eCollisionType, bool a_bIsKinematic) { if(a_rTextureToPolygonize == null) { DisplayNoTextureWarning(a_rOutdatedSpriteMeshGameObject); return a_rOutdatedSpriteMeshGameObject; } string oTexturePath = AssetDatabase.GetAssetPath(a_rTextureToPolygonize); TextureImporter rTextureImporter = TextureImporter.GetAtPath(oTexturePath) as TextureImporter; if(rTextureImporter != null) { TextureImporterSettings oTextureImporterSettings = Uni2DEditorUtilsSpriteBuilder.TextureProcessingBegin(rTextureImporter); GameObject oUpdatedSpriteMeshGameObject = DoUpdateSpriteFromTexture( a_rOutdatedSpriteMeshGameObject, a_rTextureToPolygonize, a_rTextureAtlas, a_oVertexColor, a_fAlphaCutOff, a_fPoligonizationAccuracy, a_fExtrusionDepth, a_fScale, a_bPolygonizeHoles, a_f2CustomPivotPoint, a_ePivotPoint, a_ePhysicMode, a_eCollisionType, a_bIsKinematic ); Uni2DEditorUtilsSpriteBuilder.TextureProcessingEnd(rTextureImporter, oTextureImporterSettings); EditorUtility.UnloadUnusedAssets( ); return oUpdatedSpriteMeshGameObject; } else { return null; } }
public static Vector2[] BuildUVs(Texture2DContainer a_rTextureContainer, Vector2[] a_rRenderMeshUVs, Uni2DTextureAtlas a_rTextureAtlas) { // UV data Rect oUVRect = new Rect(0.0f, 0.0f, 1.0f, 1.0f); bool bIsUVRectFlipped = false; // No atlas if (a_rTextureAtlas == null) { oUVRect = new Rect(0.0f, 0.0f, 1.0f, 1.0f); bIsUVRectFlipped = false; } else if (!string.IsNullOrEmpty(a_rTextureContainer.GUID) && a_rTextureAtlas.GetUVs(a_rTextureContainer.GUID, out oUVRect, out bIsUVRectFlipped) == false) // Atlas { // Not found in atlas!!! Debug.LogError("Uni2D: Atlas \'" + a_rTextureAtlas.name + "\' does not contain the texture with GUID \'" + a_rTextureContainer.GUID + "\'." + "\nCheck your animation clip and atlas settings.", a_rTextureAtlas); } Vector2[] oMeshUVs = a_rRenderMeshUVs; int iVertexCount = oMeshUVs.Length; // UV normalization (computes mesh UVs coords in atlas UVs space) Vector2[] oNormalizedMeshUVs = new Vector2[iVertexCount]; Vector2 f2UVOffset; // Position (== min coords) of sprite UV rect in atlas. (0;0) if not atlased Vector2 f2UVRange; // UV range (== max coords - position) in atlas. (1;1) if not atlased // If UV rect is not flipped... if (bIsUVRectFlipped == false) { f2UVOffset = new Vector2(oUVRect.xMin, oUVRect.yMin); f2UVRange = new Vector2(oUVRect.xMax, oUVRect.yMax) - f2UVOffset; for (int iUVIndex = 0; iUVIndex < iVertexCount; ++iUVIndex) { oNormalizedMeshUVs[iUVIndex] = f2UVOffset + Vector2.Scale(f2UVRange, oMeshUVs[iUVIndex]); } } else // UV rect is flipped { f2UVOffset = new Vector2(oUVRect.xMax, oUVRect.yMin); f2UVRange = new Vector2(oUVRect.xMin, oUVRect.yMax) - f2UVOffset; for (int iUVIndex = 0; iUVIndex < iVertexCount; ++iUVIndex) { Vector2 f2UV = oMeshUVs[iUVIndex]; // Need to swap UV coords oNormalizedMeshUVs[iUVIndex] = f2UVOffset + new Vector2(f2UVRange.x * f2UV.y, f2UVRange.y * f2UV.x); } } return(oNormalizedMeshUVs); }
// Update material and texture private static void UpdateMaterialForAnim(Uni2DSprite a_rSpriteComponent, Texture2DContainer a_rTextureContainer, Uni2DTextureAtlas a_rTextureAtlas) { Material oSpriteMaterial = a_rSpriteComponent.SpriteData.renderMeshMaterial; if (a_rTextureAtlas == null) { Material rAnimationMaterial = a_rSpriteComponent.RuntimeData.animationMaterial; if (rAnimationMaterial != null) { oSpriteMaterial = rAnimationMaterial; } else { // Instantiate the material to prevent other sprites using this material // to be animated too oSpriteMaterial = (Material)Material.Instantiate(oSpriteMaterial); a_rSpriteComponent.RuntimeData.animationMaterial = oSpriteMaterial; } oSpriteMaterial.mainTexture = a_rTextureContainer; } else { oSpriteMaterial = a_rTextureAtlas.GetMaterial(a_rTextureContainer.GUID); } Renderer rRenderer = a_rSpriteComponent.GetComponent <Renderer>(); if (rRenderer != null) { rRenderer.sharedMaterial = oSpriteMaterial; rRenderer.material = oSpriteMaterial; } }
// Set sprite frame public static void SetSpriteFrame(Uni2DSprite a_rSpriteComponent, Texture2DContainer a_rTextureContainer, Uni2DTextureAtlas a_rTextureAtlas, float a_fWidth, float a_fHeight, bool a_bUpdateMesh, bool a_bUpdateUV) { MeshFilter rMeshFilter = a_rSpriteComponent.GetComponent <MeshFilter>( ); SkinnedMeshRenderer rSkinnedMeshRenderer = a_rSpriteComponent.GetComponent <SkinnedMeshRenderer>( ); // The mesh to update Mesh rSpriteMesh = a_rSpriteComponent.EditableRenderMesh; if (rSpriteMesh != null) { if (a_bUpdateMesh) { rSpriteMesh = UpdateSpriteMeshSizeForAnim(a_rSpriteComponent, rSpriteMesh, a_fWidth, a_fHeight); } UpdateMaterialForAnim(a_rSpriteComponent, a_rTextureContainer, a_rTextureAtlas); if (a_bUpdateUV) { // Rebuild UVs rSpriteMesh.uv = BuildUVs(a_rTextureContainer, a_rSpriteComponent.SpriteData.renderMeshUVs, a_rTextureAtlas); } if (rSkinnedMeshRenderer != null && rSkinnedMeshRenderer.sharedMesh != rMeshFilter.sharedMesh) { rSkinnedMeshRenderer.sharedMesh = rSpriteMesh; } } }
private static void ApplySettings( Uni2DTextureAtlas a_rAtlas ) { if( a_rAtlas.ApplySettings( ) == false ) { EditorUtility.DisplayDialog( "Uni2D Texture Atlasing", "Uni2D could not pack all the specified textures into '" + a_rAtlas.name + "'.\n" + "Please check the maximum allowed atlas size and the input textures.", "OK" ); } }
private static void OnPostprocessAllAssets(string[] a_rImportedAssets, string[] a_rDeletedAssets, string[] a_rMovedAssets, string[] a_rMovedFromPath) { if (ms_bEnabled) { bool bUpdateAssets = false; bool bPostprocessPrefabs = false; bool bSaveTable = false; Uni2DEditorAssetTable rAssetTable = Uni2DEditorAssetTable.Instance; foreach (string rImportedAssetPath in a_rImportedAssets) { Texture2D rImportedTexture = (Texture2D)AssetDatabase.LoadAssetAtPath(rImportedAssetPath, typeof(Texture2D)); if (rImportedTexture != null) { if (Uni2DEditorUtils.IsMarkedAsSourceTexture(rImportedTexture)) { //Debug.Log ( "Imported " + rImportedAssetPath ); string rImportedTextureGUID = AssetDatabase.AssetPathToGUID(rImportedAssetPath); ms_oImportedTextureGUIDs.Add(rImportedTextureGUID); Uni2DEditorUtils.GenerateTextureImportGUID(rImportedTexture); bUpdateAssets = true; rImportedTexture = null; MultiUnityVersionSupportUtility.UnloadUnusedAssets( ); continue; } } Uni2DTextureAtlas rImportedAtlas = (Uni2DTextureAtlas)AssetDatabase.LoadAssetAtPath(rImportedAssetPath, typeof(Uni2DTextureAtlas)); if (rImportedAtlas != null) { //Debug.Log ( "Imported atlas " + rImportedAssetPath ); bSaveTable = true; rAssetTable.AddAtlasPath(rImportedAssetPath, AssetDatabase.AssetPathToGUID(rImportedAssetPath)); rImportedAtlas = null; MultiUnityVersionSupportUtility.UnloadUnusedAssets( ); continue; } Uni2DAnimationClip rImportedClip = (Uni2DAnimationClip)AssetDatabase.LoadAssetAtPath(rImportedAssetPath, typeof(Uni2DAnimationClip)); if (rImportedClip != null) { //Debug.Log ( "Imported clip " + rImportedClip ); bSaveTable = true; rAssetTable.AddClipPath(rImportedAssetPath, AssetDatabase.AssetPathToGUID(rImportedAssetPath)); rImportedClip = null; MultiUnityVersionSupportUtility.UnloadUnusedAssets( ); continue; } GameObject rImportedGameObject = (GameObject)AssetDatabase.LoadAssetAtPath(rImportedAssetPath, typeof(GameObject)); if (rImportedGameObject != null) { //Debug.Log ( "Imported game object " + rImportedAssetPath ); ms_oGameObjectGUIDsToPostProcess.Add(AssetDatabase.AssetPathToGUID(rImportedAssetPath)); bPostprocessPrefabs = true; rImportedGameObject = null; MultiUnityVersionSupportUtility.UnloadUnusedAssets( ); } } // Moved assets for (int iIndex = 0, iCount = a_rMovedAssets.Length; iIndex < iCount; ++iIndex) { //Debug.Log ( "Importing moved asset" ); Uni2DTextureAtlas rMovedAtlas = (Uni2DTextureAtlas)AssetDatabase.LoadAssetAtPath(a_rMovedAssets[iIndex], typeof(Uni2DTextureAtlas)); if (rMovedAtlas != null) { rAssetTable.RemoveAtlasFromPath(a_rMovedFromPath[iIndex], false); rAssetTable.AddAtlasPath(a_rMovedAssets[iIndex], AssetDatabase.AssetPathToGUID(a_rMovedAssets[iIndex])); bSaveTable = true; rMovedAtlas = null; MultiUnityVersionSupportUtility.UnloadUnusedAssets( ); continue; } Uni2DAnimationClip rMovedClip = (Uni2DAnimationClip)AssetDatabase.LoadAssetAtPath(a_rMovedAssets[iIndex], typeof(Uni2DAnimationClip)); if (rMovedClip != null) { rAssetTable.RemoveClipFromPath(a_rMovedFromPath[iIndex], false); rAssetTable.AddClipPath(a_rMovedAssets[iIndex], AssetDatabase.AssetPathToGUID(a_rMovedAssets[iIndex])); bSaveTable = true; rMovedClip = null; MultiUnityVersionSupportUtility.UnloadUnusedAssets( ); } } // Deleted assets foreach (string rDeletedAsset in a_rDeletedAssets) { string[] rSpritePrefabGUIDs = rAssetTable.GetSpritePrefabGUIDsUsingThisAtlasPath(rDeletedAsset); if (rSpritePrefabGUIDs.Length > 0) { bUpdateAssets = true; ms_oSpritePrefabGUIDsToUpdate.UnionWith(rSpritePrefabGUIDs); } /* * // TODO: mettre des paths au lieu d'IDs * string[ ] rClipGUIDs = rAssetTable.GetClipGUIDsUsingThisTexturePath( rDeletedAsset ); * if( rClipGUIDs.Length > 0 ) * { * bUpdateAssets = true; * ms_oAnimationClipGUIDsToUpdate.UnionWith( rClipGUIDs ); * } */ bSaveTable = rAssetTable.RemoveAtlasFromPath(rDeletedAsset, true) || bSaveTable; bSaveTable = rAssetTable.RemoveClipFromPath(rDeletedAsset, true) || bSaveTable; } if (bSaveTable) { rAssetTable.Save( ); } if (bUpdateAssets) { ms_oAtlasGUIDsToUpdate.UnionWith(rAssetTable.GetAtlasGUIDsUsingTheseTextures(ms_oImportedTextureGUIDs)); ms_oAnimationClipGUIDsToUpdate.UnionWith(rAssetTable.GetClipGUIDsUsingTheseTextures(ms_oImportedTextureGUIDs)); ms_oSpritePrefabGUIDsToUpdate.UnionWith(rAssetTable.GetSpritePrefabGUIDsUsingTheseTextures(ms_oImportedTextureGUIDs)); ms_oSpritePrefabGUIDsToUpdate.UnionWith(rAssetTable.GetSpritePrefabGUIDsUsingTheseAtlases(ms_oAtlasGUIDsToUpdate)); EditorApplication.delayCall += UpdateUni2DAssets; } if (bPostprocessPrefabs) { EditorApplication.delayCall += OnSpritePrefabPostprocess; } } }
public static void UpdateSpriteInteractiveParameters( Uni2DSprite a_rSpriteComponent, float a_fScale, float a_fExtrusionDepth, Uni2DSprite.PivotPointType a_eSpritePivot, Vector2 a_f2CustomPivotPoint, Uni2DTextureAtlas a_rTextureAtlas, Color a_oVertexColor) { // Current pivot point Vector2 f2CurrentPivotPoint = a_rSpriteComponent.pivotPointCoords; float fSpriteScale = a_rSpriteComponent.spriteScale; // New pivot to apply Vector2 f2NewPivotPoint = ComputePivotPoint( a_rSpriteComponent.spriteTextureWidth, a_rSpriteComponent.spriteTextureHeight, a_eSpritePivot, a_f2CustomPivotPoint ); // The delta to apply float fScalingDelta = a_fScale/fSpriteScale; float fRealScale = a_fScale * mc_fToUnit; Vector3 f3ScaledDeltaPivot = ( f2NewPivotPoint - f2CurrentPivotPoint ) * fRealScale; // Apply delta to mesh colliders for( int iMeshIndex = 0, iMeshCount = a_rSpriteComponent.meshCollidersList.Count; iMeshIndex < iMeshCount; ++iMeshIndex ) { Mesh rMesh = a_rSpriteComponent.meshCollidersList[ iMeshIndex ]; Vector3[ ] oMeshVerticesArray = rMesh.vertices; for( int iVertexIndex = 0, iVertexCount = rMesh.vertexCount; iVertexIndex < iVertexCount; ++iVertexIndex ) { Vector3 f3Vertex = oMeshVerticesArray[ iVertexIndex ]; f3Vertex -= f3ScaledDeltaPivot; f3Vertex.x *= fScalingDelta; f3Vertex.y *= fScalingDelta; f3Vertex.z = Mathf.Sign(f3Vertex.z) * a_fExtrusionDepth * 0.5f; oMeshVerticesArray[ iVertexIndex ] = f3Vertex; } // Must set array again ("vertices" getter gives a copy) rMesh.vertices = oMeshVerticesArray; MeshCollider rMeshCollider = a_rSpriteComponent.meshColliderComponentsList[ iMeshIndex ]; rMeshCollider.sharedMesh = null; rMeshCollider.sharedMesh = rMesh; } // Apply delta to sprite quad mesh Mesh rSpriteQuadMesh = a_rSpriteComponent.spriteQuadMesh; Vector3[ ] oSpriteQuadMeshVerticesArray = rSpriteQuadMesh.vertices; for( int iVertexIndex = 0, iVertexCount = rSpriteQuadMesh.vertexCount; iVertexIndex < iVertexCount; ++iVertexIndex ) { Vector3 f3Vertex = oSpriteQuadMeshVerticesArray[ iVertexIndex ]; f3Vertex -= f3ScaledDeltaPivot; f3Vertex.x *= fScalingDelta; f3Vertex.y *= fScalingDelta; oSpriteQuadMeshVerticesArray[ iVertexIndex ] = f3Vertex; } // Update UV UpdateUVs(a_rSpriteComponent, a_rTextureAtlas); // Must set array again ("vertices" getter gives a copy) rSpriteQuadMesh.vertices = oSpriteQuadMeshVerticesArray; rSpriteQuadMesh.RecalculateBounds(); // If the pivot point has changed Vector3 f3NewPivotPoint = f2NewPivotPoint; if(a_rSpriteComponent.pivotPointCoords != f3NewPivotPoint) { // Compute the local position change Vector3 f3PivotMovement = (f3NewPivotPoint - a_rSpriteComponent.pivotPointCoords) * fRealScale; Vector3 f3SpriteTransformLocalScale = a_rSpriteComponent.transform.localScale; f3PivotMovement.x *= f3SpriteTransformLocalScale.x; f3PivotMovement.y *= f3SpriteTransformLocalScale.y; f3PivotMovement.z *= f3SpriteTransformLocalScale.z; f3PivotMovement = a_rSpriteComponent.transform.TransformDirection(f3PivotMovement); Transform rParentTransform = a_rSpriteComponent.transform.parent; if(rParentTransform != null) { f3PivotMovement = rParentTransform.InverseTransformDirection(f3PivotMovement); } a_rSpriteComponent.transform.localPosition += f3PivotMovement; } // Save pivot settings a_rSpriteComponent.pivotPointType = a_eSpritePivot; a_rSpriteComponent.pivotPointCoords = f2NewPivotPoint; a_rSpriteComponent.spriteScale = a_fScale; a_rSpriteComponent.extrusionDepth = a_fExtrusionDepth; a_rSpriteComponent.textureAtlas = a_rTextureAtlas; a_rSpriteComponent.VertexColor = a_oVertexColor; }
////////// Animation clip utils ////////// // Handles texture drop over inspector private void CheckTextureDragAndDrop(Rect a_rDropAreaRect) { // Handle drag only if not multi selecting if (targets.Length == 1) { // Current Event Event rCurrentEvent = Event.current; EventType rCurrentEventType = rCurrentEvent.type; Vector2 f2MousePos = rCurrentEvent.mousePosition; // Dragging over clip inspector area if (a_rDropAreaRect.Contains(f2MousePos)) { bool bShouldAccept = false; // Does contain at least one texture2D? foreach (Object rObject in DragAndDrop.objectReferences) { if (rObject is Texture2D) { bShouldAccept = true; break; } } if (bShouldAccept) { // Accept if (rCurrentEventType == EventType.DragPerform) { DragAndDrop.AcceptDrag( ); rCurrentEvent.Use( ); DragAndDrop.activeControlID = 0; Uni2DTextureAtlas rGlobalAtlas = ((Uni2DAnimationClip)target).globalAtlas; List <Uni2DAnimationFrame> rAnimationFrames = ((Uni2DAnimationClip)target).frames; // Sort the dropped elements IOrderedEnumerable <Object> rSortedObjects = DragAndDrop.objectReferences.OrderBy(x => x.name); // Add the textures foreach (Object rObject in rSortedObjects) { if (rObject is Texture2D) { Texture2D rTexture = (Texture2D)rObject; // TODO: refactor animation frame insert // Create a new frame Uni2DAnimationFrame oNewAnimationFrame = new Uni2DAnimationFrame( ); oNewAnimationFrame.atlas = rGlobalAtlas; // Keep texture reference if no atlas oNewAnimationFrame.textureContainer = new Texture2DContainer(rTexture, rGlobalAtlas == null); // Add frame to clip rAnimationFrames.Add(oNewAnimationFrame); } } EditorUtility.SetDirty(target); } else if (rCurrentEventType == EventType.DragUpdated) // Hint drop is possible { DragAndDrop.visualMode = DragAndDropVisualMode.Copy; } } else // Reject { DragAndDrop.visualMode = DragAndDropVisualMode.Rejected; } } } }
// On init inspector public void OnInitInspector(Uni2DSprite a_rSpriteMesh) { SaveInspectorInitParameter(a_rSpriteMesh); // Parameters spriteTexture = a_rSpriteMesh.spriteTexture; textureAtlas = a_rSpriteMesh.textureAtlas; vertexColor = a_rSpriteMesh.VertexColor; physicMode = a_rSpriteMesh.physicMode; collisionType = a_rSpriteMesh.collisionType; isKinematic = a_rSpriteMesh.isKinematic; spriteScale = a_rSpriteMesh.spriteScale; pivotPointType = a_rSpriteMesh.pivotPointType; pivotPointCoords = a_rSpriteMesh.pivotPointCoords; alphaCutOff = a_rSpriteMesh.alphaCutOff; polygonizationAccuracy = a_rSpriteMesh.polygonizationAccuracy; polygonizeHoles = a_rSpriteMesh.polygonizeHoles; extrusionDepth = a_rSpriteMesh.extrusionDepth; // Info colliderTriangleCount = a_rSpriteMesh.GetColliderTriangleCount(); // Data spriteTextureWidth = a_rSpriteMesh.spriteTextureWidth; spriteTextureHeight = a_rSpriteMesh.spriteTextureHeight; spriteQuadMesh = a_rSpriteMesh.spriteQuadMesh; spriteQuadMaterial = a_rSpriteMesh.spriteQuadMaterial; meshCollidersList.Clear(); if(a_rSpriteMesh.meshCollidersList != null) { meshCollidersList.AddRange(a_rSpriteMesh.meshCollidersList); } meshCollidersRootGameObject = a_rSpriteMesh.meshCollidersRootGameObject; meshColliderComponentsList.Clear(); if(a_rSpriteMesh.meshColliderComponentsList != null) { meshColliderComponentsList.AddRange(a_rSpriteMesh.meshColliderComponentsList); } ms_bInspectorHasBeenInit = true; }
private static void UpdateUVs( Uni2DSprite a_rSpriteComponent, Uni2DTextureAtlas a_rTextureAtlas) { Mesh rSpriteQuadMesh = a_rSpriteComponent.spriteQuadMesh; // Update UV Rect oUVRect; Material oQuadSpriteMaterial = a_rSpriteComponent.spriteQuadMaterial; if(a_rTextureAtlas == null) { oUVRect = new Rect(0,0,1,1); } else { oUVRect = a_rTextureAtlas.GetUvs(a_rSpriteComponent.spriteTexture); oQuadSpriteMaterial = a_rTextureAtlas.atlasMaterial; } rSpriteQuadMesh.uv = new Vector2[ 4 ] { new Vector2( oUVRect.xMin, oUVRect.yMin ), new Vector2( oUVRect.xMax, oUVRect.yMin ), new Vector2( oUVRect.xMax, oUVRect.yMax ), new Vector2( oUVRect.xMin, oUVRect.yMax ) }; Renderer rRenderer = a_rSpriteComponent.renderer; if(rRenderer != null) { rRenderer.material = oQuadSpriteMaterial; } if(a_rTextureAtlas == null) { a_rSpriteComponent.atlasGenerationID = ""; } else { a_rSpriteComponent.atlasGenerationID = a_rTextureAtlas.generationId; } }
private static void UpdateUni2DAssets( ) { EditorApplication.delayCall -= UpdateUni2DAssets; Uni2DEditorAssetTable rAssetTable = Uni2DEditorAssetTable.Instance; try { Uni2DAssetPostprocessor.LockTo(false); // Update animation clips first, because they can change the atlases foreach (string rAnimationClipGUID in ms_oAnimationClipGUIDsToUpdate) { Uni2DAnimationClip rAnimationClip = Uni2DEditorUtils.GetAssetFromUnityGUID <Uni2DAnimationClip>(rAnimationClipGUID); if (rAnimationClip != null) { //Debug.Log ( "Updating clip " + rAnimationClipGUID ); rAnimationClip.OnTexturesChange(ms_oImportedTextureGUIDs); rAnimationClip = null; EditorUtility.UnloadUnusedAssets( ); } else { // Clean asset table foreach (string rTextureGUID in ms_oImportedTextureGUIDs) { rAssetTable.RemoveClipUsingTexture(rAnimationClipGUID, rTextureGUID); } } } foreach (string rAtlasGUID in ms_oAtlasGUIDsToUpdate) { Uni2DTextureAtlas rAtlas = Uni2DEditorUtils.GetAssetFromUnityGUID <Uni2DTextureAtlas>(rAtlasGUID); if (rAtlas != null) { //Debug.Log( "Updating atlas " + rAtlasGUID ); rAtlas.OnTextureChange( ); rAtlas = null; EditorUtility.UnloadUnusedAssets( ); } else { // Clean foreach (string rTextureGUID in ms_oImportedTextureGUIDs) { rAssetTable.RemoveAtlasUsingTexture(rAtlasGUID, rTextureGUID); } } } foreach (string rSpritePrefabGUID in ms_oSpritePrefabGUIDsToUpdate) { GameObject rSpritePrefab = Uni2DEditorUtils.GetAssetFromUnityGUID <GameObject>(rSpritePrefabGUID); if (rSpritePrefab != null) { //Debug.Log( "Updating sprite prefab " + rSpritePrefabGUID ); foreach (Uni2DSprite rSpritePrefabComponent in rSpritePrefab.GetComponentsInChildren <Uni2DSprite>(true)) { Uni2DEditorSpriteSettings rSpriteSettings = rSpritePrefabComponent.SpriteSettings; string rSpriteTextureGUID = rSpriteSettings.textureContainer.GUID; string rSpriteAtlasGUID = rSpriteSettings.atlas != null?Uni2DEditorUtils.GetUnityAssetGUID(rSpriteSettings.atlas) : null; if (ms_oImportedTextureGUIDs.Contains(rSpriteTextureGUID) || (!string.IsNullOrEmpty(rSpriteAtlasGUID) && ms_oAtlasGUIDsToUpdate.Contains(rSpriteAtlasGUID))) { rSpritePrefabComponent.Regenerate(true); } EditorUtility.UnloadUnusedAssets( ); } rSpritePrefab = null; EditorUtility.UnloadUnusedAssets( ); } else { // Clean foreach (string rTextureGUID in ms_oImportedTextureGUIDs) { rAssetTable.RemoveSpritePrefabUsingTexture(rSpritePrefabGUID, rTextureGUID); } foreach (string rAtlasGUID in ms_oAtlasGUIDsToUpdate) { rAssetTable.RemoveSpritePrefabUsingAtlas(rSpritePrefabGUID, rAtlasGUID); } } } } finally { ms_oImportedTextureGUIDs.Clear( ); ms_oAtlasGUIDsToUpdate.Clear( ); ms_oAnimationClipGUIDsToUpdate.Clear( ); ms_oSpritePrefabGUIDsToUpdate.Clear( ); rAssetTable.Save( ); Uni2DAssetPostprocessor.Unlock( ); Uni2DAssetPostprocessor.Enabled = true; } }
// Because of an Unity bug(?), SerializedProperty.hasMultipleDifferentValues and objectReferenceValue properties are inconsistent when // handling Uni2D atlases. This method does it manually. private void GetGlobalAtlas( out Uni2DTextureAtlas a_rGlobalAtlas, out bool a_bHasMultipleDifferentGlobalAtlasValues ) { int iTargetCount = this.targets.Length; a_rGlobalAtlas = ( (Uni2DAnimationClip) targets[ 0 ] ).globalAtlas; a_bHasMultipleDifferentGlobalAtlasValues = false; for( int iTargetIndex = 1; iTargetIndex < iTargetCount; ++iTargetIndex ) { if( a_rGlobalAtlas != ( (Uni2DAnimationClip) targets[ iTargetIndex ] ).globalAtlas ) { a_rGlobalAtlas = null; a_bHasMultipleDifferentGlobalAtlasValues = true; return; } } }
public void Rebuild( ) { //Debug.Log( "Rebuilding Uni2D Asset Table..." ); m_oAtlasGUIDSpritePrefabGUIDsMultiDict.Clear( ); m_oTextureGUIDAtlasGUIDsMultiDict.Clear( ); m_oTextureGUIDClipGUIDsMultiDict.Clear( ); m_oTextureGUIDSpritePrefabGUIDsMultiDict.Clear( ); m_oAtlasPathGUIDDict.Clear( ); m_oClipPathGUIDDict.Clear( ); // Iterate project's assets string[] rAssetPaths = AssetDatabase.GetAllAssetPaths( ); int iAssetCount = rAssetPaths.Length; float fInvAssetCount = 1.0f / (float)iAssetCount; int iProcessedAssets = 0; try { foreach (string rPath in rAssetPaths) { EditorUtility.DisplayProgressBar("Uni2D - Asset Table Rebuilding Progress", iProcessedAssets + " out of " + iAssetCount + " asset(s) processed...", fInvAssetCount * iProcessedAssets); Object rAssetObject = null; // Might be an atlas or a clip if (rPath.EndsWith(".prefab")) { rAssetObject = AssetDatabase.LoadAssetAtPath(rPath, typeof(Uni2DTextureAtlas)); if (rAssetObject != null) // It's an atlas { Uni2DTextureAtlas rAtlasAsset = (Uni2DTextureAtlas)rAssetObject; string rAtlasGUID = AssetDatabase.AssetPathToGUID(rPath); foreach (string rTextureGUID in rAtlasAsset.GetTextureGUIDs( )) { this.AddAtlasUsingTexture(rAtlasGUID, rTextureGUID); } m_oAtlasPathGUIDDict.Add(rPath, rAtlasGUID); rAtlasAsset = null; EditorUtility.UnloadUnusedAssets( ); } rAssetObject = AssetDatabase.LoadAssetAtPath(rPath, typeof(Uni2DAnimationClip)); if (rAssetObject != null) // It's an animation clip { Uni2DAnimationClip rAnimationClipAsset = (Uni2DAnimationClip)rAssetObject; string rAnimationClipGUID = AssetDatabase.AssetPathToGUID(rPath); foreach (string rTextureGUID in rAnimationClipAsset.GetAllFramesTextureGUIDs( )) { this.AddClipUsingTexture(rAnimationClipGUID, rTextureGUID); } m_oClipPathGUIDDict.Add(rPath, rAnimationClipGUID); rAnimationClipAsset = null; EditorUtility.UnloadUnusedAssets( ); } rAssetObject = AssetDatabase.LoadAssetAtPath(rPath, typeof(GameObject)); if (rAssetObject != null) // It's a sprite prefab { GameObject rPrefabAsset = (GameObject)rAssetObject; string rPrefabGUID = AssetDatabase.AssetPathToGUID(rPath); Uni2DSprite[] rSpritePrefabComponents = rPrefabAsset.GetComponentsInChildren <Uni2DSprite>(true); foreach (Uni2DSprite rSpritePrefabComponent in rSpritePrefabComponents) { Uni2DEditorSpriteSettings rSpriteSettings = rSpritePrefabComponent.SpriteSettings; this.AddSpritePrefabUsingTexture(rPrefabGUID, rSpriteSettings.textureContainer.GUID); if (rSpriteSettings.atlas != null) { this.AddSpritePrefabUsingAtlas(rPrefabGUID, Uni2DEditorUtils.GetUnityAssetGUID(rSpriteSettings.atlas)); } } rPrefabAsset = null; rSpritePrefabComponents = null; EditorUtility.UnloadUnusedAssets( ); } } ++iProcessedAssets; } } finally { this.Save( ); EditorUtility.UnloadUnusedAssets( ); EditorUtility.SetDirty(this); EditorUtility.ClearProgressBar( ); } //Debug.Log( "Uni2D Asset Table Rebuild: Done." ); }
//---------------- // Update Uvs //---------------- // Update the sprite in current scene and resources accordingly to texture change public static void UpdateSpriteInCurrentSceneAndResourcesAccordinglyToAtlasChange(Uni2DTextureAtlas a_rAtlas) { Uni2DEditorSpriteBuilderUtils.DoUpdateAllResourcesSpritesAccordinglyToAtlasChange(a_rAtlas); Uni2DEditorSpriteBuilderUtils.DoUpdateAllSceneSpritesAccordinglyToAtlasChange(a_rAtlas); }
// Deep copy constructor public Uni2DEditorSpriteSettings( Uni2DEditorSpriteSettings a_rSpriteSettings ) { this.textureContainer = new Texture2DContainer( a_rSpriteSettings.textureContainer ); // Deep copy this.atlas = a_rSpriteSettings.atlas; this.sharedMaterial = a_rSpriteSettings.sharedMaterial; this.renderMesh = a_rSpriteSettings.renderMesh; this.usePhysicBuildSettings = a_rSpriteSettings.usePhysicBuildSettings; this.spriteScaleMode = a_rSpriteSettings.spriteScaleMode; this.spriteScale = a_rSpriteSettings.spriteScale; this.spriteScaleNotUniform = a_rSpriteSettings.spriteScaleNotUniform; this.pivotType = a_rSpriteSettings.pivotType; this.pivotCustomCoords = a_rSpriteSettings.pivotCustomCoords; this.vertexColor = a_rSpriteSettings.vertexColor; this.dimensionMode = a_rSpriteSettings.dimensionMode; this.physicsMode = a_rSpriteSettings.physicsMode; this.collisionType = a_rSpriteSettings.collisionType; this.isKinematic = a_rSpriteSettings.isKinematic; this.isTrigger = a_rSpriteSettings.isTrigger; this.renderMeshAlphaCutOff = a_rSpriteSettings.renderMeshAlphaCutOff; this.renderMeshPolygonizationAccuracy = a_rSpriteSettings.renderMeshPolygonizationAccuracy; this.renderMeshPolygonizeHoles = a_rSpriteSettings.renderMeshPolygonizeHoles; this.alphaCutOff = a_rSpriteSettings.alphaCutOff; this.extrusionDepth = a_rSpriteSettings.extrusionDepth; this.polygonizationAccuracy = a_rSpriteSettings.polygonizationAccuracy; this.polygonizeHoles = a_rSpriteSettings.polygonizeHoles; this.onlyBorder = a_rSpriteSettings.onlyBorder; this.subdivide = a_rSpriteSettings.subdivide; this.subdivisionCount = a_rSpriteSettings.subdivisionCount; this.renderMeshGridHorizontalSubDivs = a_rSpriteSettings.renderMeshGridHorizontalSubDivs; this.renderMeshGridVerticalSubDivs = a_rSpriteSettings.renderMeshGridVerticalSubDivs; this.skinQuality = a_rSpriteSettings.skinQuality; this.boneInfluenceFalloff = a_rSpriteSettings.boneInfluenceFalloff; }
// Do Update all scene sprites accordingly to texture change for a texture change private static void DoUpdateAllSceneSpritesAccordinglyToAtlasChange(Uni2DTextureAtlas a_rAtlas) { // Loop through all the scene sprites foreach(Uni2DSprite rSprite in MonoBehaviour.FindObjectsOfType(typeof(Uni2DSprite))) { if(rSprite.SpriteSettings.atlas == a_rAtlas) { rSprite.UpdateUvs(); } } }
// Apply settings from inspector public void ApplySettings( AnimationClipRegeneration a_eRegeneration = AnimationClipRegeneration.RegenerateAlsoAtlasIfNeeded ) { m_eSavedWrapMode = wrapMode; m_fSavedFrameRate = frameRate; m_rSavedGlobalAtlas = globalAtlas; if( a_eRegeneration != AnimationClipRegeneration.RegenerateNothing ) { Generate( a_eRegeneration ); // Generate frames infos (and atlas if needed/asked) CopyFrames( frames, m_oSavedFrames ); // frames -> m_oFrames (apply) } EditorUtility.SetDirty( this ); AssetDatabase.SaveAssets( ); }
// Do Update all scene sprites accordingly to texture change for a texture change private static void DoUpdateAllResourcesSpritesAccordinglyToAtlasChange( Uni2DTextureAtlas a_rAtlas ) { Uni2DEditorAssetTable rAssetTable = Uni2DEditorAssetTable.Instance; string rAtlasGUID = Uni2DEditorUtils.GetUnityAssetGUID( a_rAtlas ); string[ ] rSpritePrefabGUIDs = rAssetTable.GetSpritePrefabGUIDsUsingThisAtlas( rAtlasGUID ); foreach( string rSpritePrefabGUID in rSpritePrefabGUIDs ) { GameObject rPrefab = Uni2DEditorUtils.GetAssetFromUnityGUID<GameObject>( rSpritePrefabGUID ); // Don't trust the table to be completly up to date if(rPrefab != null) { Uni2DSprite[ ] rSpritePrefabComponents = rPrefab.GetComponentsInChildren<Uni2DSprite>( true ); foreach( Uni2DSprite rSpritePrefabComponent in rSpritePrefabComponents ) { Uni2DEditorSpriteSettings rSpriteSettings = rSpritePrefabComponent.SpriteSettings; Uni2DTextureAtlas rAtlas = rSpriteSettings.atlas; string rSpritePrefabAtlasGUID = rAtlas != null ? Uni2DEditorUtils.GetUnityAssetGUID( rAtlas ) : null; if( !string.IsNullOrEmpty( rSpritePrefabAtlasGUID ) && rSpritePrefabGUID == rAtlasGUID ) { rSpritePrefabComponent.Regenerate( true ); } EditorUtility.UnloadUnusedAssets( ); } rPrefab = null; rSpritePrefabComponents = null; EditorUtility.UnloadUnusedAssets( ); } else { //Debug.Log("Sprite prefab " + rSpritePrefabGUID + " don't found."); rAssetTable.RemoveSpritePrefabUsingAtlas(rSpritePrefabGUID, rAtlasGUID); } } /* List<GameObject> rGameObjectsList = Uni2DEditorUtils.GetProjectResources<GameObject>( ); // Loop through all the prefab containing at least a sprite foreach( GameObject rGameObject in rGameObjectsList ) { // Is there at least one sprite containing the atlas in the prefab if( IsThereAtLeastOneSpriteContainingTheAtlasInResourceHierarchy( rGameObject.transform, a_rAtlas ) ) { DoUpdatePrefabContainingSpriteAccordinglyToAtlasChange( rGameObject, a_rAtlas ); } } */ }
// Set the frame draw by the sprite private void SetSpriteFrame(Texture2DContainer a_rTextureContainer, Uni2DTextureAtlas a_rTextureAtlas, int a_iWidth, int a_iHeight) { bool a_bUpdateMesh = false; if(m_iCurrentFrameTextureWidth != a_iWidth || m_iCurrentFrameTextureHeight != a_iHeight ) { m_iCurrentFrameTextureWidth = a_iWidth; m_iCurrentFrameTextureHeight = a_iHeight; a_bUpdateMesh = true; } bool a_bUpdateUV = false; if(m_rCurrentFrameAtlas != a_rTextureAtlas || (m_rCurrentFrameAtlas != null && m_rCurrentFrameTextureContainer != a_rTextureContainer)) { m_rCurrentFrameTextureContainer = a_rTextureContainer; m_rCurrentFrameAtlas = a_rTextureAtlas; a_bUpdateUV = true; } Uni2DSpriteUtils.SetSpriteFrame(this, a_rTextureContainer, a_rTextureAtlas, a_iWidth, a_iHeight, a_bUpdateMesh, a_bUpdateUV); }
// Do Update all scene prefab containing at least a sprite accordingly to atlas change for a texture change private static void DoUpdatePrefabContainingSpriteAccordinglyToAtlasChange(GameObject a_rPrefab, Uni2DTextureAtlas a_rAtlas) { DoUpdatePrefabContainingSpriteAccordinglyToAtlasChangeRecursively(a_rPrefab.transform, a_rAtlas); }
// Set default atlas private void SetDefaultAtlas() { textureAtlas = Uni2DEditorUtils.FindFirstTextureAtlas(spriteTexture); }
// On inspector gui public override void OnInspectorGUI( ) { Uni2DTextureAtlas rAtlas = target as Uni2DTextureAtlas; #if BEFORE_UNITY_4_3 EditorGUIUtility.LookLikeInspector( ); #endif // Material override EditorGUILayout.BeginVertical( ); { rAtlas.materialOverride = (Material)EditorGUILayout.ObjectField("Material Override", rAtlas.materialOverride, typeof(Material), false); rAtlas.maximumAtlasSize = (AtlasSize)EditorGUILayout.EnumPopup("Maximum Atlas Size", rAtlas.maximumAtlasSize); rAtlas.padding = EditorGUILayout.IntField("Padding", rAtlas.padding); rAtlas.padding = Mathf.Abs(rAtlas.padding); // Texture to pack list // Custom list GUI: displays Texture2D objects, handles asset GUIDs serializedObject.Update( ); SerializedProperty rSerializedProperty_Textures = serializedObject.FindProperty("textures"); int iContainerIndex = 0; EditorGUILayout.Space( ); while (true) { string oPropertyPath = rSerializedProperty_Textures.propertyPath; string oPropertyName = rSerializedProperty_Textures.name; bool bIsTextureContainer = oPropertyPath.Contains("textures"); // Indent EditorGUI.indentLevel = rSerializedProperty_Textures.depth; if (bIsTextureContainer) { if (oPropertyName == "textures") { GUIContent oGUIContentTexturesLabel = new GUIContent("Textures"); Rect rFoldoutRect = GUILayoutUtility.GetRect(oGUIContentTexturesLabel, EditorStyles.foldout); Event rCurrentEvent = Event.current; switch (rCurrentEvent.type) { // Drag performed case EventType.DragPerform: { // Check if dragged objects are inside the foldout rect if (rFoldoutRect.Contains(rCurrentEvent.mousePosition)) { // Accept and use the event DragAndDrop.AcceptDrag( ); rCurrentEvent.Use( ); EditorGUIUtility.hotControl = 0; DragAndDrop.activeControlID = 0; // Add the textures to the current list foreach (Object rDraggedObject in DragAndDrop.objectReferences) { if (rDraggedObject is Texture2D) { int iCurrentSize = rSerializedProperty_Textures.arraySize; ++rSerializedProperty_Textures.arraySize; SerializedProperty rSerializedProperty_Data = rSerializedProperty_Textures.GetArrayElementAtIndex(iCurrentSize); rSerializedProperty_Data = rSerializedProperty_Data.FindPropertyRelative("m_oTextureGUID"); rSerializedProperty_Data.stringValue = rDraggedObject != null ? Uni2DEditorUtils.GetUnityAssetGUID((Texture2D)rDraggedObject) : null; } } } } break; case EventType.DragUpdated: { if (rFoldoutRect.Contains(rCurrentEvent.mousePosition)) { DragAndDrop.visualMode = DragAndDropVisualMode.Copy; } } break; } EditorGUI.indentLevel = 0; ms_bTexturesFoldout = EditorGUI.Foldout(rFoldoutRect, ms_bTexturesFoldout, oGUIContentTexturesLabel); } else if (oPropertyName == "data") { SerializedProperty rSerializedProperty_TextureGUID = rSerializedProperty_Textures.FindPropertyRelative("m_oTextureGUID"); Texture2D rTexture = Uni2DEditorUtils.GetAssetFromUnityGUID <Texture2D>(rSerializedProperty_TextureGUID.stringValue); EditorGUI.BeginChangeCheck( ); { rTexture = (Texture2D)EditorGUILayout.ObjectField("Element " + iContainerIndex, rTexture, typeof(Texture2D), false); ++iContainerIndex; } if (EditorGUI.EndChangeCheck( )) { rSerializedProperty_TextureGUID.stringValue = rTexture != null ? Uni2DEditorUtils.GetUnityAssetGUID(rTexture) : null; } } else { // Default draw of the property field EditorGUILayout.PropertyField(rSerializedProperty_Textures); } } if (rSerializedProperty_Textures.NextVisible(ms_bTexturesFoldout) == false) { break; } } serializedObject.ApplyModifiedProperties( ); EditorGUILayout.Space( ); EditorGUI.indentLevel = 0; ///// Generated assets section ///// // Materials ms_bGeneratedMaterialsFoldout = EditorGUILayout.Foldout(ms_bGeneratedMaterialsFoldout, "Generated Materials"); if (ms_bGeneratedMaterialsFoldout) { ++EditorGUI.indentLevel; { if (ms_oAtlasMaterials.Length > 0) { foreach (Material rAtlasMaterial in ms_oAtlasMaterials) { EditorGUILayout.BeginHorizontal( ); { GUILayout.Space(16.0f); if (GUILayout.Button(EditorGUIUtility.ObjectContent(rAtlasMaterial, typeof(Material)), EditorStyles.label, GUILayout.ExpandWidth(false), GUILayout.MaxWidth(225.0f), GUILayout.MaxHeight(16.0f))) { EditorGUIUtility.PingObject(rAtlasMaterial); } } EditorGUILayout.EndHorizontal( ); } } else { EditorGUILayout.PrefixLabel("(None)"); } } --EditorGUI.indentLevel; } EditorGUILayout.Space( ); // Atlas textures ms_bGeneratedTexturesFoldout = EditorGUILayout.Foldout(ms_bGeneratedTexturesFoldout, "Generated Textures"); if (ms_bGeneratedTexturesFoldout) { ++EditorGUI.indentLevel; { if (ms_oAtlasTextures.Length > 0) { foreach (Texture2D rAtlasTexture in ms_oAtlasTextures) { EditorGUILayout.BeginHorizontal( ); { GUILayout.Space(16.0f); if (GUILayout.Button(EditorGUIUtility.ObjectContent(rAtlasTexture, typeof(Texture2D)), EditorStyles.label, GUILayout.ExpandWidth(false), GUILayout.MaxWidth(225.0f), GUILayout.MaxHeight(16.0f))) { EditorGUIUtility.PingObject(rAtlasTexture); } } EditorGUILayout.EndHorizontal( ); } } else { EditorGUILayout.PrefixLabel("(None)"); } } --EditorGUI.indentLevel; } bool bUnappliedSettings = rAtlas.UnappliedSettings; EditorGUI.BeginDisabledGroup(bUnappliedSettings == false); { // Apply/Revert EditorGUILayout.BeginHorizontal( ); { if (GUILayout.Button("Apply")) { this.ApplySettings( ); } if (GUILayout.Button("Revert")) { rAtlas.RevertSettings( ); } } EditorGUILayout.EndHorizontal( ); } EditorGUI.EndDisabledGroup(); // Generate if (GUILayout.Button("Force atlas regeneration")) { this.ApplySettings( ); } } EditorGUILayout.EndVertical( ); }
// Do Update all scene sprites accordingly to texture change for a texture change private static void DoUpdateAllResourcesSpritesAccordinglyToAtlasChange(Uni2DTextureAtlas a_rAtlas) { // Loop through all the prefab containing at least a sprite foreach(string rAssetPath in AssetDatabase.GetAllAssetPaths()) { GameObject rPrefab = AssetDatabase.LoadAssetAtPath(rAssetPath, typeof(GameObject)) as GameObject; if(rPrefab != null) { // Is there at least one sprite containing the atlas in the prefab if(IsThereAtLeastOneSpriteContainingTheAtlasInResourceHierarchy(rPrefab.transform, a_rAtlas)) { DoUpdatePrefabContainingSpriteAccordinglyToAtlasChange(rPrefab, a_rAtlas); } } } }
// Displays the animation frame GUI // Returns the performed user action public static AnimationGUIAction DisplayAnimationFrame(Uni2DAnimationFrame a_rAnimationFrame, Uni2DTextureAtlas a_rGlobalAtlas, ref bool a_bEventFoldout) { AnimationGUIAction eAction = AnimationGUIAction.None; // Box EditorGUILayout.BeginVertical(EditorStyles.textField); { ///// Top toolbar ///// EditorGUILayout.BeginHorizontal(EditorStyles.toolbar, GUILayout.ExpandWidth(true)); { // ^ if (GUILayout.Button("\u25B2" /*"\u2191"*/, EditorStyles.toolbarButton, GUILayout.ExpandWidth(false))) { eAction = AnimationGUIAction.MoveUp; } // v if (GUILayout.Button("\u25BC" /*"\u2193"*/, EditorStyles.toolbarButton, GUILayout.ExpandWidth(false))) { eAction = AnimationGUIAction.MoveDown; } // + ^ if (GUILayout.Button("+ \u25B2" /*"+ \u2191"*/, EditorStyles.toolbarButton, GUILayout.ExpandWidth(true))) { eAction = AnimationGUIAction.AddUp; } // X if (GUILayout.Button("X", EditorStyles.toolbarButton, GUILayout.ExpandWidth(false))) { eAction = AnimationGUIAction.Close; } } EditorGUILayout.EndHorizontal( ); /////////////// EditorGUILayout.Space( ); ///// Animation Frame box ///// EditorGUILayout.BeginHorizontal( ); { Texture2D rFrameTexture = a_rAnimationFrame.textureContainer; string rFrameTextureGUID = a_rAnimationFrame.textureContainer.GUID; bool bHasFrameTextureChanged; // Display frame texture on the left Rect oClipTextureRect = GUILayoutUtility.GetRect(64.0f, 64.0f, 64.0f, 64.0f, GUILayout.ExpandWidth(false)); EditorGUI.BeginChangeCheck( ); { rFrameTexture = (Texture2D)EditorGUI.ObjectField(oClipTextureRect, GUIContent.none, rFrameTexture, typeof(Texture2D), false); } bHasFrameTextureChanged = EditorGUI.EndChangeCheck( ); EditorGUILayout.BeginVertical(GUILayout.ExpandWidth(true)); { // Frame texture name GUILayout.Label(rFrameTexture != null ? rFrameTexture.name : "(No Texture)", EditorStyles.boldLabel, GUILayout.ExpandWidth(false)); // Frame Name a_rAnimationFrame.name = EditorGUILayout.TextField("Frame Name", a_rAnimationFrame.name); // Frame atlas EditorGUILayout.BeginHorizontal( ); { // Disable popup menu if global atlas is set EditorGUI.BeginDisabledGroup(a_rGlobalAtlas != null); { // Atlas popup string[] oTextureGUID = (rFrameTexture != null) ? new string[1] { rFrameTextureGUID } : new string[0]; EditorGUILayout.PrefixLabel("Use Atlas"); a_rAnimationFrame.atlas = Uni2DEditorGUIUtils.AtlasPopup(a_rAnimationFrame.atlas, oTextureGUID); } EditorGUI.EndDisabledGroup( ); // Atlas select button EditorGUI.BeginDisabledGroup(a_rAnimationFrame.atlas == null); { if (GUILayout.Button("Select", GUILayout.Width(80.0f))) { EditorGUIUtility.PingObject(a_rAnimationFrame.atlas.gameObject); } } EditorGUI.EndDisabledGroup( ); } EditorGUILayout.EndHorizontal( ); // Trigger? a_rAnimationFrame.triggerEvent = EditorGUILayout.Toggle("Trigger Event", a_rAnimationFrame.triggerEvent); // Event param a_bEventFoldout = EditorGUILayout.Foldout(a_bEventFoldout, "Frame Infos"); if (a_bEventFoldout) { Uni2DAnimationFrameInfos rFrameInfos = a_rAnimationFrame.frameInfos; ++EditorGUI.indentLevel; { rFrameInfos.stringInfo = EditorGUILayout.TextField("String Info", rFrameInfos.stringInfo); rFrameInfos.intInfo = EditorGUILayout.IntField("Int Info", rFrameInfos.intInfo); rFrameInfos.floatInfo = EditorGUILayout.FloatField("Float Info", rFrameInfos.floatInfo); rFrameInfos.objectInfo = EditorGUILayout.ObjectField("Object Info", rFrameInfos.objectInfo, typeof(Object), true); } --EditorGUI.indentLevel; } EditorGUILayout.Space( ); } EditorGUILayout.EndVertical( ); if (bHasFrameTextureChanged) { // Save texture in texture container, keep reference to the asset if not using an atlas a_rAnimationFrame.textureContainer = new Texture2DContainer(rFrameTexture, a_rGlobalAtlas == null); } } EditorGUILayout.EndHorizontal( ); /////////////// EditorGUILayout.Space( ); ///// Bottom toolbar ///// EditorGUILayout.BeginHorizontal(EditorStyles.toolbar, GUILayout.ExpandWidth(true)); { // + v if (GUILayout.Button("+ \u25BC" /*"+ \u2193"*/, EditorStyles.toolbarButton, GUILayout.ExpandWidth(true))) { eAction = AnimationGUIAction.AddDown; } } EditorGUILayout.EndHorizontal( ); } EditorGUILayout.EndVertical( ); return(eAction); }
// Save inspector public void SaveInspectorInitParameter(Uni2DSprite a_rSpriteMesh) { // Parameters m_rSpriteTextureInit = a_rSpriteMesh.spriteTexture; m_rTextureAtlasInit = a_rSpriteMesh.textureAtlas; m_oVertexColorInit = a_rSpriteMesh.VertexColor; m_ePhysicModeInit = a_rSpriteMesh.physicMode; m_eCollisionTypeInit = a_rSpriteMesh.collisionType; m_bIsKinematicInit = a_rSpriteMesh.isKinematic; m_fSpriteScaleInit = a_rSpriteMesh.spriteScale; m_ePivotPointTypeInit = a_rSpriteMesh.pivotPointType; m_f2PivotPointCoordsInit = a_rSpriteMesh.pivotPointCoords; m_fAlphaCutOffInit = a_rSpriteMesh.alphaCutOff; m_fPolygonizationAccuracyInit = a_rSpriteMesh.polygonizationAccuracy; m_bPolygonizeHolesInit = a_rSpriteMesh.polygonizeHoles; m_fExtrusionDepthInit = a_rSpriteMesh.extrusionDepth; }
public static Uni2DTextureAtlas AtlasPopup(Uni2DTextureAtlas a_rTextureAtlas, IEnumerable <string> a_rTextureGUIDs, params GUILayoutOption[] a_rGUILayoutOptions) { // Get button control ID int iControlID = GUIUtility.GetControlID(FocusType.Passive); // Get selected value for our control // If no PopupCallbackInfo instance exists, the returned value is a_rTextureAtlas a_rTextureAtlas = PopupCallbackInfo <Uni2DTextureAtlas> .GetSelectedValueForControl(iControlID, a_rTextureAtlas); // Create a new generic menu // Each item menu will use AtlasPopupCallback as callback // AtlasPopupCallback will perform the logic and save the selected atlas to // the PopupCallbackInfo instance. string oPopupSelected = EditorGUI.showMixedValue ? "-" : (a_rTextureAtlas != null ? a_rTextureAtlas.name : "(None)"); if (GUILayout.Button(oPopupSelected, EditorStyles.popup, a_rGUILayoutOptions)) { string rAtlasGUID = Uni2DEditorUtils.GetUnityAssetGUID(a_rTextureAtlas); // Create a new popup callback info (control ID) and save it as current instance PopupCallbackInfo <Uni2DTextureAtlas> .instance = new PopupCallbackInfo <Uni2DTextureAtlas>(iControlID, a_rTextureAtlas); // Create our generic menu GenericMenu oPopupMenu = new GenericMenu( ); if (a_rTextureAtlas != null) { oPopupMenu.AddItem(new GUIContent(a_rTextureAtlas.name), true, AtlasPopupCallback, rAtlasGUID); oPopupMenu.AddSeparator(""); } // "None" special item menu oPopupMenu.AddItem(new GUIContent("(None)", "No atlasing"), a_rTextureAtlas == null, AtlasPopupCallback, ""); oPopupMenu.AddSeparator(""); // "Create" special item menu oPopupMenu.AddItem(new GUIContent("Create a new atlas...", "Creates a new Uni2D atlas and add the texture(s) right away"), false, AtlasPopupCallback, "NEW"); Uni2DEditorAssetTable rAssetTable = Uni2DEditorAssetTable.Instance; // List atlases containing the texture(s) Dictionary <string, string> oAtlasesReadyToUse = rAssetTable.GetAtlasNamesUsingTheseTextures(a_rTextureGUIDs); if (!string.IsNullOrEmpty(rAtlasGUID)) { oAtlasesReadyToUse.Remove(rAtlasGUID); } if (oAtlasesReadyToUse.Count > 0) { oPopupMenu.AddSeparator(""); // Add an item menu for each ready to use atlas foreach (KeyValuePair <string, string> rAtlasNameGUIDPair in oAtlasesReadyToUse) { oPopupMenu.AddItem(new GUIContent(rAtlasNameGUIDPair.Value), rAtlasNameGUIDPair.Key == rAtlasGUID, AtlasPopupCallback, rAtlasNameGUIDPair.Key); } } // List all available atlases Dictionary <string, string> oAvailableAtlases = rAssetTable.GetAllAtlasNames( ); if (oAvailableAtlases.Count > 0) { oPopupMenu.AddSeparator(""); // Add an item menu for each available atlas, in a submenu foreach (KeyValuePair <string, string> rAtlasNameGUIDPair in oAvailableAtlases) { oPopupMenu.AddItem(new GUIContent("All atlases/" + rAtlasNameGUIDPair.Value), rAtlasNameGUIDPair.Key == rAtlasGUID, AtlasPopupCallback, rAtlasNameGUIDPair.Key); } } // Finally show up the menu oPopupMenu.ShowAsContext( ); } return(a_rTextureAtlas); }
// Do Update all scene prefab containing at least a sprite accordingly to atlas change for a texture change private static void DoUpdatePrefabContainingSpriteAccordinglyToAtlasChangeRecursively(Transform a_rRoot, Uni2DTextureAtlas a_rAtlas) { // loop through the sprite containing the changed texture foreach(Uni2DSprite rSpritePrefabInstance in a_rRoot.GetComponents<Uni2DSprite>()) { if(rSpritePrefabInstance.SpriteSettings.atlas == a_rAtlas) { rSpritePrefabInstance.UpdateUvs(); } } // Recursive call foreach(Transform rChild in a_rRoot) { DoUpdatePrefabContainingSpriteAccordinglyToAtlasChangeRecursively(rChild, a_rAtlas); } }
public static GameObject DoUpdateSpriteFromTexture( GameObject a_rOutdatedSpriteMeshGameObject, Texture2D a_rTextureToPolygonize, Uni2DTextureAtlas a_rTextureAtlas, Color a_oVertexColor, float a_fAlphaCutOff, float a_fPoligonizationAccuracy, float a_fExtrusionDepth, float a_fScale, bool a_bPolygonizeHoles, Vector2 a_f2CustomPivotPoint, Uni2DSprite.PivotPointType a_ePivotPoint, Uni2DSprite.PhysicMode a_ePhysicMode, Uni2DSprite.CollisionType a_eCollisionType, bool a_bIsKinematic) { if(ms_bUndoEnabled) { // Allow undo this update Undo.RegisterSceneUndo("Update Sprite"); } Uni2DSprite rOutdatedSpriteMeshComponent = a_rOutdatedSpriteMeshGameObject.GetComponent<Uni2DSprite>(); if(rOutdatedSpriteMeshComponent != null) { // Delete resources // Delete game objects in excess foreach(MeshCollider rMeshColliderComponent in rOutdatedSpriteMeshComponent.meshColliderComponentsList) { if(rMeshColliderComponent != null) { // If the mesh collider component is attached to another game object // than the sprite itself, we destroy it too (because that component was its unique purpose) if(rMeshColliderComponent.gameObject != a_rOutdatedSpriteMeshGameObject) { // Destroy game object AND component GameObject.DestroyImmediate(rMeshColliderComponent.gameObject); } else { // Destroy component MonoBehaviour.DestroyImmediate(rMeshColliderComponent); } } } // Destroy mesh collider root game object (if any) if(rOutdatedSpriteMeshComponent.meshCollidersRootGameObject != null) { GameObject.DestroyImmediate(rOutdatedSpriteMeshComponent.meshCollidersRootGameObject); } // Delete components in excess Rigidbody rRigidbodyComponent = rOutdatedSpriteMeshComponent.GetComponent<Rigidbody>(); if(rRigidbodyComponent != null) { // Destroy component MonoBehaviour.DestroyImmediate(rRigidbodyComponent); } } Vector2 f2PivotPoint = ComputePivotPoint(a_rTextureToPolygonize, a_ePivotPoint, a_f2CustomPivotPoint); List<Mesh> oMeshesList = null; if(a_ePhysicMode != Uni2DSprite.PhysicMode.NoPhysic) { // Rebuild mesh collider oMeshesList = CreateMeshFromTexture( a_rTextureToPolygonize, a_fAlphaCutOff, a_fPoligonizationAccuracy, a_fExtrusionDepth, a_fScale, a_bPolygonizeHoles, f2PivotPoint, a_ePhysicMode, a_eCollisionType, a_bIsKinematic); } // Update game object GameObject oUpdatedSpriteMeshGameObject = UpdateSpriteGameObject( a_rOutdatedSpriteMeshGameObject, a_rTextureToPolygonize, a_rTextureAtlas, a_oVertexColor, oMeshesList, a_fAlphaCutOff, a_fPoligonizationAccuracy, a_fExtrusionDepth, a_fScale, a_bPolygonizeHoles, f2PivotPoint, a_ePivotPoint, a_ePhysicMode, a_eCollisionType, a_bIsKinematic); return oUpdatedSpriteMeshGameObject; }
// Is there at least one sprite in a resource hierarchy public static bool IsThereAtLeastOneSpriteContainingTheAtlasInResourceHierarchy(Transform a_rRoot, Uni2DTextureAtlas a_rTextureAtlas) { Uni2DSprite rSprite = a_rRoot.GetComponent<Uni2DSprite>(); if(rSprite != null) { if(rSprite.SpriteSettings.atlas == a_rTextureAtlas) { return true; } } // Recursive call foreach(Transform rChild in a_rRoot) { if(IsThereAtLeastOneSpriteContainingTheAtlasInResourceHierarchy(rChild, a_rTextureAtlas)) { return true; } } return false; }
private void ApplyAnimationClipGlobalAtlas( Uni2DTextureAtlas a_rGlobalAtlas ) { for( int iClipIndex = 0, iClipCount = this.targets.Length; iClipIndex < iClipCount; ++iClipIndex ) { Uni2DAnimationClip rAnimationClip = (Uni2DAnimationClip) this.targets[ iClipIndex ]; rAnimationClip.globalAtlas = a_rGlobalAtlas; for( int iFrameIndex = 0, iFrameCount = rAnimationClip.FrameCount; iFrameIndex < iFrameCount; ++iFrameIndex ) { rAnimationClip.frames[ iFrameIndex ].atlas = a_rGlobalAtlas; } EditorUtility.SetDirty( rAnimationClip ); } }