// Returns true if the Uni2DSprite data have been generated // for a given physic mode public bool AreDataGenerated(Uni2DEditorSpriteSettings a_rSpriteSettings) { bool bArePhysicsDataGenerated = true; if (a_rSpriteSettings.physicsMode != Uni2DSprite.PhysicsMode.NoPhysics) { if (a_rSpriteSettings.dimensionMode == Uni2DSprite.DimensionMode._2D) { #if AFTER_UNITY_4_3 bArePhysicsDataGenerated = polygonCollider2D != null && mesh2D != null; #endif } else { bArePhysicsDataGenerated = (this.meshCollidersList != null && this.meshCollidersList.Contains(null) == false && this.meshColliderComponentsList != null && this.meshColliderComponentsList.Contains(null) == false); } } return(this.renderMesh != null && this.renderMeshMaterial != null && bArePhysicsDataGenerated); }
// 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; }
public static void GenerateBoneWeightsFromSettings( Uni2DEditorSpriteSettings a_rNewSpriteSettings, Uni2DSprite a_rSprite ) { a_rSprite.RestorePosePosition( ); a_rSprite.UpdatePosing( ); a_rSprite.SpriteSettings.boneInfluenceFalloff = a_rNewSpriteSettings.boneInfluenceFalloff; a_rSprite.SpriteSettings.skinQuality = a_rNewSpriteSettings.skinQuality; }
// // Returns true if the given settings imply to rebuild the sprite quad // public bool DoNewSettingsImplyToRebuildQuad( Uni2DEditorSpriteSettings a_rSpriteSettings ) // { // return this.InteractiveParametersEquals( a_rSpriteSettings ) == false // || this.spriteTexture != a_rSpriteSettings.spriteTexture; // } // Returns true if the given settings imply to rebuild the sprite physic public bool DoNewSettingsImplyToRebuildPhysics(Uni2DEditorSpriteSettings a_rSpriteSettings) { return(this.NonInteractiveParametersEquals(a_rSpriteSettings) == false || this.pivotType != a_rSpriteSettings.pivotType || (this.pivotType == PivotType.Custom && this.pivotCustomCoords != a_rSpriteSettings.pivotCustomCoords) || this.SpriteScale != a_rSpriteSettings.SpriteScale); }
// Update the quad mesh size public static Mesh UpdateSpriteMeshSizeForAnim(Uni2DSprite a_rSprite, Mesh a_rSpriteMesh, float a_fWidth, float a_fHeight) { Uni2DEditorSpriteSettings rSpriteSettings = a_rSprite.SpriteSettings; Uni2DEditorSpriteData rSpriteData = a_rSprite.SpriteData; // Scale Vector2 fScale = rSpriteData.Scale; float fWidth = fScale.x * a_fWidth; float fHeight = fScale.y * a_fHeight; // Pivot Vector2 f2ScaledPivotCoords = ComputePivotCoords(a_fWidth, a_fHeight, rSpriteSettings.pivotType, rSpriteSettings.pivotCustomCoords); f2ScaledPivotCoords.x *= fScale.x; f2ScaledPivotCoords.y *= fScale.y; if (a_rSpriteMesh != null) { switch (rSpriteSettings.renderMesh) { case SpriteRenderMesh.Quad: { // Update vertices a_rSpriteMesh.vertices = GenerateQuadVertices(fWidth, fHeight, f2ScaledPivotCoords); } break; default: case SpriteRenderMesh.TextureToMesh: case SpriteRenderMesh.Grid: { // Resize the sprite mesh // From the saved original vertices Vo in ( 0; 0 ) base, // apply mesh dimensions ratio R = ( Wn; Hn ) / ( Wo; Ho ) // and finally sub new pivot Pn to have Vn // Vo * R - Pn = Vn Vector3 f3Ratio = new Vector3(a_fWidth / rSpriteData.spriteWidth, a_fHeight / rSpriteData.spriteHeight, 0.0f); Vector3 f3ScaledPivotCoords = f2ScaledPivotCoords; int iVertexCount = a_rSpriteMesh.vertexCount; Vector3[] oResizedVertices = new Vector3[iVertexCount]; for (int iVertexIndex = 0; iVertexIndex < iVertexCount; ++iVertexIndex) { oResizedVertices[iVertexIndex] = Vector3.Scale(rSpriteData.renderMeshVertices[iVertexIndex], f3Ratio) - f3ScaledPivotCoords; } a_rSpriteMesh.vertices = oResizedVertices; } break; } a_rSpriteMesh.RecalculateBounds( ); } return(a_rSpriteMesh); }
// Returns true if and only if a_rSpriteParameters is not null and if interactive parameters are equal public bool InteractiveParametersEquals(Uni2DEditorSpriteSettings a_rSpriteSettings) { return(a_rSpriteSettings != null && this.usePhysicBuildSettings == a_rSpriteSettings.usePhysicBuildSettings && this.pivotType == a_rSpriteSettings.pivotType && this.pivotCustomCoords == a_rSpriteSettings.pivotCustomCoords && this.spriteScale == a_rSpriteSettings.spriteScale && this.extrusionDepth == a_rSpriteSettings.extrusionDepth && this.atlas == a_rSpriteSettings.atlas && this.sharedMaterial == a_rSpriteSettings.sharedMaterial && this.vertexColor == a_rSpriteSettings.vertexColor && this.isKinematic == a_rSpriteSettings.isKinematic && this.skinQuality == a_rSpriteSettings.skinQuality && this.boneInfluenceFalloff == a_rSpriteSettings.boneInfluenceFalloff); }
// Returns true if and only if a_rSpriteSettings is not null and if non-interactive parameters are equal public bool NonInteractiveParametersEquals(Uni2DEditorSpriteSettings a_rSpriteSettings) { return(a_rSpriteSettings != null && this.physicsMode == a_rSpriteSettings.physicsMode && this.collisionType == a_rSpriteSettings.collisionType && this.alphaCutOff == a_rSpriteSettings.alphaCutOff && this.polygonizationAccuracy == a_rSpriteSettings.polygonizationAccuracy && this.polygonizeHoles == a_rSpriteSettings.polygonizeHoles && this.textureContainer == a_rSpriteSettings.textureContainer && this.renderMesh == a_rSpriteSettings.renderMesh && this.renderMeshAlphaCutOff == a_rSpriteSettings.renderMeshAlphaCutOff && this.renderMeshPolygonizationAccuracy == a_rSpriteSettings.renderMeshPolygonizationAccuracy && this.renderMeshPolygonizeHoles == a_rSpriteSettings.renderMeshPolygonizeHoles && this.renderMeshGridHorizontalSubDivs == a_rSpriteSettings.renderMeshGridHorizontalSubDivs && this.renderMeshGridVerticalSubDivs == a_rSpriteSettings.renderMeshGridVerticalSubDivs); }
// NEW // Same as CreateSpriteFromSettings but updates instead of create if a_rSpriteToUpdate != null // Rebuild only if necessary but can be forced with a_bForceRebuild == true. public static GameObject GenerateSpriteFromSettings( Uni2DEditorSpriteSettings a_rNewSpriteSettings, Uni2DSprite a_rSprite = null, bool a_bForceRebuild = false, bool a_bInABatch = false ) { // Are we updating or creating? bool bUpdating = ( a_rSprite != null ); // Are we allowed to undo if updating bool bRegisterUpdateUndo = ms_bUndoEnabled && bUpdating; // Game object GameObject oSpriteGameObject = bUpdating ? a_rSprite.gameObject : new GameObject( "Sprite_" + a_rNewSpriteSettings.textureContainer.Texture.name ); // Sprite component Uni2DSprite rSprite = bUpdating ? a_rSprite : Uni2DSprite.Create( oSpriteGameObject ); if( a_bInABatch == false ) { // Get texture importer... string oTexturePath = AssetDatabase.GetAssetPath( a_rNewSpriteSettings.textureContainer.Texture ); TextureImporter rTextureImporter = TextureImporter.GetAtPath( oTexturePath ) as TextureImporter; // ...if any... if( rTextureImporter != null ) { if( bRegisterUpdateUndo ) { // Allow undo this update Undo.RegisterSceneUndo( "Update Uni2D sprite" ); } TextureImporterSettings oTextureImporterSettings = Uni2DEditorSpriteBuilderUtils.TextureProcessingBegin( rTextureImporter ); // Create/update sprite material GenerateSpriteMatFromSettings( a_rNewSpriteSettings, rSprite ); // Create/update sprite mesh GenerateSpriteMeshFromSettings( a_rNewSpriteSettings, rSprite ); // Create/update colliders GenerateCollidersFromSettings( a_rNewSpriteSettings, rSprite, a_bForceRebuild ); // Post build operations rSprite.AfterBuild(); Uni2DEditorSpriteBuilderUtils.TextureProcessingEnd( rTextureImporter, oTextureImporterSettings ); } // Allow undo the creation (i.e. bUpdating == false) if( bUpdating == false && ms_bUndoEnabled ) { Undo.RegisterCreatedObjectUndo( oSpriteGameObject, "Create Uni2D sprite" ); } } else // Batching: no texture imports, no register undos... { // Create/update sprite material GenerateSpriteMatFromSettings( a_rNewSpriteSettings, rSprite ); // Create/update sprite mesh GenerateSpriteMeshFromSettings( a_rNewSpriteSettings, rSprite ); // Create/update colliders GenerateCollidersFromSettings( a_rNewSpriteSettings, rSprite, a_bForceRebuild ); // Post build operations rSprite.AfterBuild(); } return oSpriteGameObject; }
// NEW // Creates/updates colliders according to given new settings public static GameObject GenerateCollidersFromSettings( Uni2DEditorSpriteSettings a_rNewSpriteSettings, Uni2DSprite a_rSprite, bool a_bForceRebuild ) { Uni2DEditorSpriteSettings rCurrentSpriteSettings = a_rSprite.SpriteSettings; Uni2DEditorSpriteData rCurrentSpriteData = a_rSprite.SpriteData; GameObject rSpriteGameObject = a_rSprite.gameObject; // Is rebuilding needed? bool bRebuild = a_bForceRebuild || a_rSprite.isPhysicsDirty || rCurrentSpriteSettings.DoNewSettingsImplyToRebuildPhysics( a_rNewSpriteSettings ); if( bRebuild ) { // Clean the sprite (if needed) RemoveGeneratedColliders( a_rSprite ); // Generate meshes List<Mesh> rMeshList = PolygonizeTextureToMeshColliderFromSettings( a_rNewSpriteSettings ); if( rMeshList == null ) { rMeshList = new List<Mesh>( ); } List<MeshCollider> oMeshColliderComponentsList = new List<MeshCollider>( rMeshList.Count ); // Add collider children // Attach a mesh collider collider to current game object // if collider is not compound GameObject oColliderParentGameObject = null; // Mesh collider triangle count int iMeshColliderTriangleCount = 0; // Components creation if( a_rNewSpriteSettings.physicsMode != Uni2DSprite.PhysicsMode.NoPhysics ) { // Compound if( a_rNewSpriteSettings.collisionType == Uni2DSprite.CollisionType.Compound ) { oColliderParentGameObject = new GameObject( "root_Colliders" ); // Create a game object for each mesh collider and attach them to sprite game object for( int iColliderIndex = 0, iMeshCount = rMeshList.Count; iColliderIndex < iMeshCount; ++iColliderIndex ) { GameObject oMeshColliderGameObject = new GameObject( "mesh_Collider_" + iColliderIndex ); MeshCollider oMeshColliderComponent = oMeshColliderGameObject.AddComponent<MeshCollider>( ); oMeshColliderComponent.sharedMesh = rMeshList[ iColliderIndex ]; oMeshColliderComponent.convex = true; oMeshColliderComponentsList.Add( oMeshColliderComponent ); // Child -> parent attachment oMeshColliderGameObject.transform.parent = oColliderParentGameObject.transform; iMeshColliderTriangleCount += rMeshList[ iColliderIndex ].triangles.Length; } Transform rColliderParentTransform = oColliderParentGameObject.transform; rColliderParentTransform.parent = rSpriteGameObject.transform; rColliderParentTransform.localPosition = Vector3.zero; rColliderParentTransform.localRotation = Quaternion.identity; rColliderParentTransform.localScale = Vector3.one; } else // Static / Dynamic { MeshCollider oMeshColliderComponent = rSpriteGameObject.GetComponent<MeshCollider>( ); if( oMeshColliderComponent == null ) { oMeshColliderComponent = rSpriteGameObject.AddComponent<MeshCollider>( ); } oMeshColliderComponent.sharedMesh = rMeshList[ 0 ]; oMeshColliderComponentsList.Add( oMeshColliderComponent ); // Set whether or not mesh collider is convex oMeshColliderComponent.convex = ( a_rNewSpriteSettings.collisionType == Uni2DSprite.CollisionType.Convex ); iMeshColliderTriangleCount = rMeshList[ 0 ].triangles.Length; } // Add rigidbody to sprite game object if any dynamic mode is specified Uni2DEditorSpriteBuilderUtils.SetupRigidbodyFor2D( a_rSprite, a_rNewSpriteSettings ); } // Settings rCurrentSpriteSettings.alphaCutOff = a_rNewSpriteSettings.alphaCutOff; rCurrentSpriteSettings.collisionType = a_rNewSpriteSettings.collisionType; rCurrentSpriteSettings.extrusionDepth = a_rNewSpriteSettings.extrusionDepth; rCurrentSpriteSettings.isKinematic = a_rNewSpriteSettings.isKinematic; rCurrentSpriteSettings.physicsMode = a_rNewSpriteSettings.physicsMode; rCurrentSpriteSettings.pivotType = a_rNewSpriteSettings.pivotType; rCurrentSpriteSettings.pivotCustomCoords = a_rNewSpriteSettings.pivotCustomCoords; rCurrentSpriteSettings.polygonizationAccuracy = a_rNewSpriteSettings.polygonizationAccuracy; rCurrentSpriteSettings.polygonizeHoles = a_rNewSpriteSettings.polygonizeHoles; // Generated data rCurrentSpriteData.meshColliderComponentsList = oMeshColliderComponentsList; rCurrentSpriteData.meshCollidersList = rMeshList; rCurrentSpriteData.meshCollidersRootGameObject = oColliderParentGameObject; rCurrentSpriteData.colliderTriangleCount = ( iMeshColliderTriangleCount / 3 ); rCurrentSpriteData.pivotCoords = a_rNewSpriteSettings.PivotCoords; } // Is up to date! a_rSprite.isPhysicsDirty = false; return rSpriteGameObject; }
// Setup rigidbody 2d private static void SetupRigidbodyFor2D( Uni2DSprite a_rSprite, Uni2DEditorSpriteSettings a_rNewSettings = null ) { Uni2DEditorSpriteSettings rCurrentSettings = a_rNewSettings == null ? a_rSprite.SpriteSettings : a_rNewSettings; Rigidbody rSpriteRigidbody = a_rSprite.GetComponent<Rigidbody>( ); // Setup the rigidbody if( rCurrentSettings.physicsMode == Uni2DSprite.PhysicsMode.Dynamic ) { // Add the rigidbody component if( rSpriteRigidbody == null ) { rSpriteRigidbody = a_rSprite.gameObject.AddComponent<Rigidbody>( ); } rSpriteRigidbody.constraints = RigidbodyConstraints.FreezePositionZ | RigidbodyConstraints.FreezeRotationX | RigidbodyConstraints.FreezeRotationY; rSpriteRigidbody.isKinematic = rCurrentSettings.isKinematic; } else if( rSpriteRigidbody != null ) // a rigidbody is not needed in the other modes { MonoBehaviour.DestroyImmediate( rSpriteRigidbody ); } }
// NEW // Creates/updates the quad mesh material of a sprite according to given new settings. public static GameObject GenerateSpriteMatFromSettings( Uni2DEditorSpriteSettings a_rNewSpriteSettings, Uni2DSprite a_rSprite ) { Material oSpriteRendererMaterial; Material oSpriteMeshMaterial; Uni2DEditorSpriteData rCurrentSpriteData = a_rSprite.SpriteData; Uni2DEditorSpriteSettings rCurrentSpriteSettings = a_rSprite.SpriteSettings; Texture2D rNewSpriteTexture = a_rNewSpriteSettings.textureContainer; GameObject rSpriteGameObject = a_rSprite.gameObject; // If a shared material is used with a texture different from the sprite texture // or if an atlas is used if(a_rNewSpriteSettings.ShouldUseAtlas( ) || (a_rNewSpriteSettings.sharedMaterial != null && a_rNewSpriteSettings.textureContainer.Texture != a_rNewSpriteSettings.sharedMaterial.mainTexture) ) { // don't use the shared material a_rNewSpriteSettings.sharedMaterial = null; } Material rGeneratedMaterial = null; if(a_rNewSpriteSettings.sharedMaterial == null && a_rNewSpriteSettings.ShouldUseAtlas( ) == false) { // If the material doesn't exist yet, create it rGeneratedMaterial = rCurrentSpriteData.generatedMaterial; if( rGeneratedMaterial == null ) { // create a new one rGeneratedMaterial = new Material( Shader.Find( mc_oSpriteDefaultShader ) ); // Set mat name rGeneratedMaterial.name = "mat_Generated_Sprite_" + rNewSpriteTexture.name; rCurrentSpriteData.generatedMaterial = rGeneratedMaterial; } } rCurrentSpriteData.generatedMaterial = rGeneratedMaterial; Material rSharedMaterial = a_rNewSpriteSettings.sharedMaterial; if(rSharedMaterial == null) { oSpriteMeshMaterial = rGeneratedMaterial; } else { oSpriteMeshMaterial = rSharedMaterial; } // If no atlas... if( a_rNewSpriteSettings.ShouldUseAtlas( ) == false ) { oSpriteRendererMaterial = oSpriteMeshMaterial; a_rNewSpriteSettings.atlas = null; // Set mat texture oSpriteMeshMaterial.mainTexture = rNewSpriteTexture; } else { oSpriteRendererMaterial = a_rNewSpriteSettings.atlas.GetMaterial( rNewSpriteTexture ); oSpriteMeshMaterial = oSpriteRendererMaterial; } // Init. rendering component // Add it if not created Renderer rSpriteMeshRendererComponent = a_rSprite.renderer;// a_rSprite.GetComponent<MeshRenderer>( ); if( rSpriteMeshRendererComponent == null ) { if( a_rSprite.Bones.Length > 0 ) { rSpriteMeshRendererComponent = rSpriteGameObject.AddComponent<SkinnedMeshRenderer>( ); } else { rSpriteMeshRendererComponent = rSpriteGameObject.AddComponent<MeshRenderer>( ); } } // Set new material to mesh renderer rSpriteMeshRendererComponent.sharedMaterial = oSpriteRendererMaterial; // Update sprite settings rCurrentSpriteSettings.textureContainer = new Texture2DContainer( rNewSpriteTexture, a_rNewSpriteSettings.atlas == null ); rCurrentSpriteSettings.atlas = a_rNewSpriteSettings.atlas; // Update sprite generated data rCurrentSpriteData.renderMeshMaterial = oSpriteMeshMaterial; return rSpriteGameObject; }
// NEW // Removes the generated physic colliders attached to a sprite private static void RemoveGeneratedComponents(Uni2DSprite a_rSpriteToClean, Uni2DEditorSpriteSettings a_rNewSpriteSettings) { if(a_rSpriteToClean != null) { // 3D // Colliders // Retrieve the generated data of the sprite to clean Uni2DEditorSpriteData rSpriteData = a_rSpriteToClean.SpriteData; // Delete resources // Delete game objects in excess if(rSpriteData.meshColliderComponentsList != null) { for(int i = rSpriteData.meshColliderComponentsList.Count - 1; i >= 0; --i) { MeshCollider rMeshColliderComponent = rSpriteData.meshColliderComponentsList[i]; bool bRemove = false; 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_rSpriteToClean.gameObject) { // Destroy game object AND component GameObject.DestroyImmediate(rMeshColliderComponent.gameObject); bRemove = true; } else { // If we doesn't need a collider on the game object anymore if(a_rNewSpriteSettings.physicsMode == Uni2DSprite.PhysicsMode.NoPhysics || a_rNewSpriteSettings.collisionType == Uni2DSprite.CollisionType.Compound || a_rNewSpriteSettings.dimensionMode != Uni2DSprite.DimensionMode._3D ) { // Destroy component MonoBehaviour.DestroyImmediate(rMeshColliderComponent); bRemove = true; } } } else { bRemove = true; } if(bRemove) { rSpriteData.meshColliderComponentsList.RemoveAt(i); rSpriteData.meshCollidersList.RemoveAt(i); } } } if(rSpriteData.meshCollidersList == null || rSpriteData.meshCollidersList.Count <= 0) { rSpriteData.meshCollidersList = null; rSpriteData.meshColliderComponentsList = null; rSpriteData.colliderTriangleCount = 0; } // Destroy mesh collider root game object (if any) if( rSpriteData.meshCollidersRootGameObject != null ) { // Destroy game object GameObject.DestroyImmediate(rSpriteData.meshCollidersRootGameObject); } // Rigidbody if(a_rNewSpriteSettings.physicsMode != Uni2DSprite.PhysicsMode.Dynamic || a_rNewSpriteSettings.dimensionMode != Uni2DSprite.DimensionMode._3D) { Rigidbody rRigidbodyComponent = a_rSpriteToClean.GetComponent<Rigidbody>( ); if(rRigidbodyComponent != null) { // Destroy component MonoBehaviour.DestroyImmediate( rRigidbodyComponent ); } } // 2D #if AFTER_UNITY_4_3 // Rigidbody if(a_rNewSpriteSettings.physicsMode != Uni2DSprite.PhysicsMode.Dynamic || a_rNewSpriteSettings.dimensionMode != Uni2DSprite.DimensionMode._2D) { Rigidbody2D rRigidbodyComponent2D = a_rSpriteToClean.GetComponent<Rigidbody2D>( ); if(rRigidbodyComponent2D != null) { // Destroy component MonoBehaviour.DestroyImmediate( rRigidbodyComponent2D ); } } rSpriteData.polygonCollider2D = null; PolygonCollider2D rPolygonCollider2D = a_rSpriteToClean.GetComponent<PolygonCollider2D>(); if(rPolygonCollider2D != null) { if(a_rNewSpriteSettings.physicsMode == Uni2DSprite.PhysicsMode.NoPhysics || a_rNewSpriteSettings.dimensionMode != Uni2DSprite.DimensionMode._2D) { MonoBehaviour.DestroyImmediate(rPolygonCollider2D); } else { rSpriteData.polygonCollider2D = rPolygonCollider2D; } } #endif } }
// NEW // Creates/updates the quad mesh of a sprite according to given new settings. public static GameObject GenerateSpriteMeshFromSettings( Uni2DEditorSpriteSettings a_rNewSpriteSettings, Uni2DSprite a_rSprite ) { GameObject rSpriteGameObject = a_rSprite.gameObject; Uni2DEditorSpriteData rCurrentSpriteData = a_rSprite.SpriteData; Uni2DEditorSpriteSettings rCurrentSpriteSettings = a_rSprite.SpriteSettings; Texture2DContainer rTextureContainer = a_rNewSpriteSettings.textureContainer; Texture2D rSpriteTexture = rTextureContainer; // Init. mesh filter component // Add it if not created MeshFilter rSpriteMeshFilter = a_rSprite.GetComponent<MeshFilter>( ); if( rSpriteMeshFilter == null ) { rSpriteMeshFilter = rSpriteGameObject.AddComponent<MeshFilter>( ); } // Retrieve pivot coords Vector2 f2ScaledPivotCoords = a_rNewSpriteSettings.ScaledPivotCoords; // Quad mesh Mesh oSpriteMesh; Uni2DTextureAtlas rTextureAtlas = a_rNewSpriteSettings.atlas; Vector3[ ] oRenderMeshVertices = null; Vector2[ ] oRenderMeshNormalizedUVs = null; int iVertexCount; SpriteRenderMesh eRenderMesh = a_rNewSpriteSettings.renderMesh; // Check if using atlas and texture is well included in this atlas if( a_rNewSpriteSettings.ShouldUseAtlas( ) == false ) { // No atlas => clean settings a_rNewSpriteSettings.atlas = null; rTextureAtlas = null; } // Render Mesh switch( eRenderMesh ) { // Quad default: case SpriteRenderMesh.Quad: { // Mesh creation oSpriteMesh = new Mesh( ); // Quad vertices oRenderMeshVertices = Uni2DSpriteUtils.GenerateQuadVertices( a_rNewSpriteSettings.SpriteWidth, a_rNewSpriteSettings.SpriteHeight, f2ScaledPivotCoords ); oSpriteMesh.vertices = oRenderMeshVertices; iVertexCount = 4; // Quad triangles oSpriteMesh.triangles = new int[ 6 ] { 1, 0, 2, 2, 0, 3 }; // Quad UVs oRenderMeshNormalizedUVs = new Vector2[ 4 ] { new Vector2( 0.0f, 0.0f ), new Vector2( 1.0f, 0.0f ), new Vector2( 1.0f, 1.0f ), new Vector2( 0.0f, 1.0f ) }; } break; // Create a sprite via texture polygonization case SpriteRenderMesh.Grid: case SpriteRenderMesh.TextureToMesh: { oSpriteMesh = PolygonizeTextureToMeshFromSettings( a_rNewSpriteSettings ); // Copy render mesh vertices/UVs (.vertices & .uv return a copy) oRenderMeshNormalizedUVs = oSpriteMesh.uv; oRenderMeshVertices = oSpriteMesh.vertices; iVertexCount = oSpriteMesh.vertexCount; } break; } // Build UVs from various settings (atlasing, render mesh, etc) oSpriteMesh.uv = Uni2DSpriteUtils.BuildUVs( rTextureContainer, oRenderMeshNormalizedUVs, rTextureAtlas ); // Re-iterate vertices and unapply pivot in order to have // a copy of all mesh vertices in ( 0; 0 ) base Vector3 f3ScaledPivotCoords = f2ScaledPivotCoords; for( int iVertexIndex = 0; iVertexIndex < iVertexCount; ++iVertexIndex ) { oRenderMeshVertices[ iVertexIndex ] += f3ScaledPivotCoords; } // Set vertex color array (32bits) Uni2DSpriteUtils.UpdateMeshVertexColor( oSpriteMesh, a_rNewSpriteSettings.vertexColor ); // Optim. mesh oSpriteMesh.RecalculateBounds( ); oSpriteMesh.RecalculateNormals( ); oSpriteMesh.Optimize( ); oSpriteMesh.name = "mesh_Sprite_"; if(rSpriteTexture != null) { oSpriteMesh.name += rSpriteTexture.name; } else { oSpriteMesh.name += "MissingTexture"; } // Set new sprite settings rCurrentSpriteSettings.pivotType = a_rNewSpriteSettings.pivotType; rCurrentSpriteSettings.pivotCustomCoords = a_rNewSpriteSettings.pivotCustomCoords; rCurrentSpriteSettings.spriteScale = a_rNewSpriteSettings.spriteScale; rCurrentSpriteSettings.atlas = rTextureAtlas; rCurrentSpriteSettings.textureContainer = new Texture2DContainer( rSpriteTexture, rTextureAtlas == null ); rCurrentSpriteSettings.renderMeshAlphaCutOff = a_rNewSpriteSettings.renderMeshAlphaCutOff; rCurrentSpriteSettings.renderMeshPolygonizationAccuracy = a_rNewSpriteSettings.renderMeshPolygonizationAccuracy; rCurrentSpriteSettings.renderMeshPolygonizeHoles = a_rNewSpriteSettings.renderMeshPolygonizeHoles; rCurrentSpriteSettings.usePhysicBuildSettings = a_rNewSpriteSettings.usePhysicBuildSettings; rCurrentSpriteSettings.renderMesh = a_rNewSpriteSettings.renderMesh; rCurrentSpriteSettings.renderMeshGridHorizontalSubDivs = a_rNewSpriteSettings.renderMeshGridHorizontalSubDivs; rCurrentSpriteSettings.renderMeshGridVerticalSubDivs = a_rNewSpriteSettings.renderMeshGridVerticalSubDivs; // Set new sprite generated data rCurrentSpriteData.renderMesh = oSpriteMesh; rCurrentSpriteData.renderMeshVertices = oRenderMeshVertices; rCurrentSpriteData.renderMeshUVs = oRenderMeshNormalizedUVs; if(rSpriteTexture != null) { rCurrentSpriteData.spriteWidth = rSpriteTexture.width; rCurrentSpriteData.spriteHeight = rSpriteTexture.height; } // Set computed pivot coords rCurrentSpriteData.pivotCoords = a_rNewSpriteSettings.PivotCoords; rCurrentSpriteData.scale = a_rNewSpriteSettings.ScaleFactor; a_rSprite.atlasGenerationID = ( rTextureAtlas != null ) ? rTextureAtlas.generationId : ""; // Set mesh to mesh filter component rSpriteMeshFilter.sharedMesh = oSpriteMesh; // Compute bone weights if needed GenerateBoneWeightsFromSettings( a_rNewSpriteSettings, a_rSprite ); return rSpriteGameObject; }
// Returns true if the Uni2DSprite data have been generated // for a given physic mode public bool AreDataGenerated(Uni2DEditorSpriteSettings a_rSpriteSettings) { bool bArePhysicsDataGenerated = true; if(a_rSpriteSettings.physicsMode != Uni2DSprite.PhysicsMode.NoPhysics) { if(a_rSpriteSettings.dimensionMode == Uni2DSprite.DimensionMode._2D) { #if AFTER_UNITY_4_3 bArePhysicsDataGenerated = polygonCollider2D != null && mesh2D != null; #endif } else { bArePhysicsDataGenerated = ( this.meshCollidersList != null && this.meshCollidersList.Contains( null ) == false && this.meshColliderComponentsList != null && this.meshColliderComponentsList.Contains( null ) == false); } } return this.renderMesh != null && this.renderMeshMaterial != null && bArePhysicsDataGenerated; }
// Returns true if and only if a_rSpriteParameters is not null and if interactive parameters are equal public bool InteractiveParametersEquals( Uni2DEditorSpriteSettings a_rSpriteSettings ) { return a_rSpriteSettings != null && this.usePhysicBuildSettings == a_rSpriteSettings.usePhysicBuildSettings && this.pivotType == a_rSpriteSettings.pivotType && this.pivotCustomCoords == a_rSpriteSettings.pivotCustomCoords && this.spriteScaleMode == a_rSpriteSettings.spriteScaleMode && this.spriteScale == a_rSpriteSettings.spriteScale && this.spriteScaleNotUniform == a_rSpriteSettings.spriteScaleNotUniform && this.extrusionDepth == a_rSpriteSettings.extrusionDepth && this.atlas == a_rSpriteSettings.atlas && this.sharedMaterial == a_rSpriteSettings.sharedMaterial && this.vertexColor == a_rSpriteSettings.vertexColor && this.isKinematic == a_rSpriteSettings.isKinematic && this.isTrigger == a_rSpriteSettings.isTrigger && this.skinQuality == a_rSpriteSettings.skinQuality && this.boneInfluenceFalloff == a_rSpriteSettings.boneInfluenceFalloff; }
// Same as above but with an Uni2DEditorSpriteSettings argument. public bool Equals(Uni2DEditorSpriteSettings a_rSpriteSettings) { return(this.InteractiveParametersEquals(a_rSpriteSettings) && this.NonInteractiveParametersEquals(a_rSpriteSettings)); }
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; } }
// Same as above but with an Uni2DEditorSpriteSettings argument. public bool Equals( Uni2DEditorSpriteSettings a_rSpriteSettings ) { return this.InteractiveParametersEquals( a_rSpriteSettings ) && this.NonInteractiveParametersEquals( a_rSpriteSettings ); }
// // Returns true if the given settings imply to rebuild the sprite quad // public bool DoNewSettingsImplyToRebuildQuad( Uni2DEditorSpriteSettings a_rSpriteSettings ) // { // return this.InteractiveParametersEquals( a_rSpriteSettings ) == false // || this.spriteTexture != a_rSpriteSettings.spriteTexture; // } // Returns true if the given settings imply to rebuild the sprite physic public bool DoNewSettingsImplyToRebuildPhysics( Uni2DEditorSpriteSettings a_rSpriteSettings ) { return this.NonInteractiveParametersEquals( a_rSpriteSettings ) == false || this.pivotType != a_rSpriteSettings.pivotType || ( this.pivotType == PivotType.Custom && this.pivotCustomCoords != a_rSpriteSettings.pivotCustomCoords ) || this.SpriteScale != a_rSpriteSettings.SpriteScale; }
// Returns true if and only if a_rSpriteSettings is not null and if non-interactive parameters are equal public bool NonInteractiveParametersEquals( Uni2DEditorSpriteSettings a_rSpriteSettings ) { return a_rSpriteSettings != null && this.dimensionMode == a_rSpriteSettings.dimensionMode && this.physicsMode == a_rSpriteSettings.physicsMode && this.collisionType == a_rSpriteSettings.collisionType && this.alphaCutOff == a_rSpriteSettings.alphaCutOff && this.polygonizationAccuracy == a_rSpriteSettings.polygonizationAccuracy && this.polygonizeHoles == a_rSpriteSettings.polygonizeHoles && this.textureContainer == a_rSpriteSettings.textureContainer && this.renderMesh == a_rSpriteSettings.renderMesh && this.renderMeshAlphaCutOff == a_rSpriteSettings.renderMeshAlphaCutOff && this.renderMeshPolygonizationAccuracy == a_rSpriteSettings.renderMeshPolygonizationAccuracy && this.renderMeshPolygonizeHoles == a_rSpriteSettings.renderMeshPolygonizeHoles && this.renderMeshGridHorizontalSubDivs == a_rSpriteSettings.renderMeshGridHorizontalSubDivs && this.renderMeshGridVerticalSubDivs == a_rSpriteSettings.renderMeshGridVerticalSubDivs && this.onlyBorder == a_rSpriteSettings.onlyBorder && this.subdivide == a_rSpriteSettings.subdivide && this.subdivisionCount == a_rSpriteSettings.subdivisionCount; }
// NEW // Parse a 2D texture and make mesh colliders from edges public static Mesh PolygonizeTextureToMeshFromSettings( Uni2DEditorSpriteSettings a_rSpriteSettings ) { // Ensure we have an input texture and an output render mesh requiring to parse that texture to be built if( a_rSpriteSettings.textureContainer == null || a_rSpriteSettings.renderMesh == SpriteRenderMesh.Quad ) { return null; } // The texture to polygonize Texture2D rTextureToPolygonize = a_rSpriteSettings.textureContainer; float fAlphaCutOff; float fPolygonizationAccuracy; if( a_rSpriteSettings.usePhysicBuildSettings ) { fAlphaCutOff = a_rSpriteSettings.alphaCutOff; fPolygonizationAccuracy = a_rSpriteSettings.polygonizationAccuracy; } else { fAlphaCutOff = a_rSpriteSettings.renderMeshAlphaCutOff; fPolygonizationAccuracy = a_rSpriteSettings.renderMeshPolygonizationAccuracy; } // Step 1 // Distinguish completely transparent pixels from significant pixel by "binarizing" the texture. Uni2DEditorUtilsBuildingProgressBar.AddProcessedSpriteBuildStep( ); BinarizedImage rBinarizedImage = Uni2DEditorShapeExtractionUtils.BinarizeTexture( rTextureToPolygonize, fAlphaCutOff ); // Mesh creation Mesh rMesh; switch( a_rSpriteSettings.renderMesh ) { case SpriteRenderMesh.TextureToMesh: { // Step 2 // Build binarized outer/inner contours and label image regions List<Contour> oOuterContours; List<Contour> oInnerContours; Uni2DEditorUtilsBuildingProgressBar.AddProcessedSpriteBuildStep( ); Uni2DEditorContourExtractionUtils.CombinedContourLabeling( rBinarizedImage, a_rSpriteSettings.renderMeshPolygonizeHoles, out oOuterContours, out oInnerContours ); // Step 3: vectorization (determine dominant points) if( a_rSpriteSettings.renderMeshPolygonizeHoles ) { // Step 3a: if hole support asked by user, merge inner contours into outer contours first oOuterContours = Uni2DEditorContourPolygonizationUtils.MergeInnerAndOuterContours( oOuterContours, oInnerContours ); } // Simplify contours Uni2DEditorUtilsBuildingProgressBar.AddProcessedSpriteBuildStep( ); List<Contour> oDominantContoursList = Uni2DEditorContourPolygonizationUtils.SimplifyContours( oOuterContours, fPolygonizationAccuracy ); // Step 4: triangulation Uni2DEditorUtilsBuildingProgressBar.AddProcessedSpriteBuildStep( ); rMesh = Uni2DEditorPolygonTriangulationUtils.PolygonizeContours( oDominantContoursList, a_rSpriteSettings.ScaleFactor, a_rSpriteSettings.PivotCoords, rTextureToPolygonize.width, rTextureToPolygonize.height ); } break; case SpriteRenderMesh.Grid: { // Step 2 // Triangulate the grid straight from binarized image Uni2DEditorUtilsBuildingProgressBar.AddProcessedSpriteBuildStep( ); rMesh = Uni2DEditorPolygonTriangulationUtils.PolygonizeGrid( rBinarizedImage, a_rSpriteSettings.ScaleFactor, a_rSpriteSettings.PivotCoords, a_rSpriteSettings.renderMeshGridHorizontalSubDivs, a_rSpriteSettings.renderMeshGridVerticalSubDivs ); } break; default: { return null; } } // Wrap up the mesh before delivering ;^) rMesh.name = "mesh_Sprite_" + rTextureToPolygonize.name; rMesh.RecalculateBounds( ); rMesh.RecalculateNormals( ); rMesh.Optimize( ); return rMesh; }
public static List<Uni2DMeshShape2D> PolygonizeTextureToBorder2DVerticesFromSettings( Uni2DEditorSpriteSettings a_rSpriteSettings ) { if( a_rSpriteSettings.textureContainer == null || a_rSpriteSettings.physicsMode == Uni2DSprite.PhysicsMode.NoPhysics ) { return new List<Uni2DMeshShape2D>(); } // The texture to polygonize Texture2D rTextureToPolygonize = a_rSpriteSettings.textureContainer; // Polygonize holes? bool bPolygonizeHoles = a_rSpriteSettings.polygonizeHoles; // Step 1 // Distinguish completely transparent pixels from significant pixel by "binarizing" the texture. Uni2DEditorUtilsBuildingProgressBar.AddProcessedSpriteBuildStep( ); BinarizedImage rBinarizedImage = Uni2DEditorShapeExtractionUtils.BinarizeTexture( rTextureToPolygonize, a_rSpriteSettings.alphaCutOff ); // Step 2 // Build binarized outer/inner contours and label image regions List<Contour> oOuterContours; List<Contour> oInnerContours; Uni2DEditorUtilsBuildingProgressBar.AddProcessedSpriteBuildStep( ); Uni2DEditorContourExtractionUtils.CombinedContourLabeling( rBinarizedImage, bPolygonizeHoles, out oOuterContours, out oInnerContours ); // Step 3: vectorization (determine dominant points) if( a_rSpriteSettings.polygonizeHoles ) { // Step 3a: if hole support asked by user, merge inner contours into outer contours first oOuterContours = Uni2DEditorContourPolygonizationUtils.MergeInnerAndOuterContours( oOuterContours, oInnerContours ); } // Simplify contours Uni2DEditorUtilsBuildingProgressBar.AddProcessedSpriteBuildStep( ); List<Contour> oSimplifiedContoursList = Uni2DEditorContourPolygonizationUtils.SimplifyContours( oOuterContours, a_rSpriteSettings.polygonizationAccuracy ); List<Contour> oDominantContoursList; if(a_rSpriteSettings.subdivide) { // subdivide contours float fSubdivisionLength = Mathf.Max(rTextureToPolygonize.width, rTextureToPolygonize.height)/(a_rSpriteSettings.subdivisionCount + 1.0f); oDominantContoursList = Uni2DEditorContourPolygonizationUtils.SubdivideContours( oSimplifiedContoursList, fSubdivisionLength ); } else { oDominantContoursList = oSimplifiedContoursList; } List<Uni2DMeshShape2D> oShapes = Uni2DEditorPolygonTriangulationUtils.Get2DVerticesFromContours( oDominantContoursList, a_rSpriteSettings.ScaleFactor, a_rSpriteSettings.PivotCoords); return oShapes; }
// NEW // Parse a 2D texture and make mesh colliders from edges public static List<Mesh> PolygonizeTextureToMeshColliderFromSettings( Uni2DEditorSpriteSettings a_rSpriteSettings ) { if( a_rSpriteSettings.textureContainer == null || a_rSpriteSettings.physicsMode == Uni2DSprite.PhysicsMode.NoPhysics ) { return null; } // The texture to polygonize Texture2D rTextureToPolygonize = a_rSpriteSettings.textureContainer; // Polygonize holes? bool bPolygonizeHoles = ( a_rSpriteSettings.collisionType != Uni2DSprite.CollisionType.Convex && a_rSpriteSettings.polygonizeHoles ); // Step 1 // Distinguish completely transparent pixels from significant pixel by "binarizing" the texture. Uni2DEditorUtilsBuildingProgressBar.AddProcessedSpriteBuildStep( ); BinarizedImage rBinarizedImage = Uni2DEditorShapeExtractionUtils.BinarizeTexture( rTextureToPolygonize, a_rSpriteSettings.alphaCutOff ); // Step 2 // Build binarized outer/inner contours and label image regions List<Contour> oOuterContours; List<Contour> oInnerContours; Uni2DEditorUtilsBuildingProgressBar.AddProcessedSpriteBuildStep( ); Uni2DEditorContourExtractionUtils.CombinedContourLabeling( rBinarizedImage, bPolygonizeHoles, out oOuterContours, out oInnerContours ); // Step 3: vectorization (determine dominant points) if( a_rSpriteSettings.polygonizeHoles ) { // Step 3a: if hole support asked by user, merge inner contours into outer contours first oOuterContours = Uni2DEditorContourPolygonizationUtils.MergeInnerAndOuterContours( oOuterContours, oInnerContours ); } // Simplify contours Uni2DEditorUtilsBuildingProgressBar.AddProcessedSpriteBuildStep( ); List<Contour> oDominantContoursList = Uni2DEditorContourPolygonizationUtils.SimplifyContours( oOuterContours, a_rSpriteSettings.polygonizationAccuracy ); // Step 4: triangulation List<Mesh> oMeshesList; Uni2DEditorUtilsBuildingProgressBar.AddProcessedSpriteBuildStep( ); if( a_rSpriteSettings.collisionType == Uni2DSprite.CollisionType.Compound ) { // Compound mesh oMeshesList = Uni2DEditorPolygonTriangulationUtils.CompoundPolygonizeAndExtrudeContours( oDominantContoursList, a_rSpriteSettings.extrusionDepth, a_rSpriteSettings.ScaleFactor, a_rSpriteSettings.PivotCoords ); int iMeshIndex = 0; foreach( Mesh rMesh in oMeshesList ) { rMesh.name = "mesh_Collider_" + rTextureToPolygonize.name + "_" + iMeshIndex; ++iMeshIndex; } } else { // Single mesh Mesh rMesh = Uni2DEditorPolygonTriangulationUtils.PolygonizeAndExtrudeContours( oDominantContoursList, a_rSpriteSettings.extrusionDepth, a_rSpriteSettings.ScaleFactor, a_rSpriteSettings.PivotCoords ); rMesh.name = "mesh_Collider_" + rTextureToPolygonize.name; oMeshesList = new List<Mesh>( 1 ); oMeshesList.Add( rMesh ); } // Optimize meshes foreach( Mesh rMesh in oMeshesList ) { rMesh.RecalculateBounds( ); rMesh.RecalculateNormals( ); rMesh.Optimize( ); } return oMeshesList; }
// 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; }
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." ); }
// Setup rigidbody 2d private static void SetupRigidbodyFor2D( Uni2DSprite a_rSprite, Uni2DEditorSpriteSettings a_rNewSettings = null ) { Uni2DEditorSpriteSettings rCurrentSettings = a_rNewSettings == null ? a_rSprite.SpriteSettings : a_rNewSettings; switch(rCurrentSettings.dimensionMode) { case DimensionMode._3D: { #if AFTER_UNITY_4_3 // Destroy 2d rigidbody Rigidbody2D rSpriteRigidbody2D = a_rSprite.GetComponent<Rigidbody2D>(); if( rSpriteRigidbody2D != null ) { MonoBehaviour.DestroyImmediate(rSpriteRigidbody2D); } #endif Rigidbody rSpriteRigidbody = a_rSprite.GetComponent<Rigidbody>( ); // Setup the rigidbody if( rCurrentSettings.physicsMode == Uni2DSprite.PhysicsMode.Dynamic ) { // Add the rigidbody component if( rSpriteRigidbody == null ) { rSpriteRigidbody = a_rSprite.gameObject.AddComponent<Rigidbody>( ); } rSpriteRigidbody.constraints = RigidbodyConstraints.FreezePositionZ | RigidbodyConstraints.FreezeRotationX | RigidbodyConstraints.FreezeRotationY; rSpriteRigidbody.isKinematic = rCurrentSettings.isKinematic; } else if( rSpriteRigidbody != null ) // a rigidbody is not needed in the other modes { MonoBehaviour.DestroyImmediate( rSpriteRigidbody ); } } break; case DimensionMode._2D: { // Destroy 3d rigidbody Rigidbody rSpriteRigidbody = a_rSprite.GetComponent<Rigidbody>(); if( rSpriteRigidbody != null ) // a rigidbody is not needed in the other modes { MonoBehaviour.DestroyImmediate(rSpriteRigidbody); } #if AFTER_UNITY_4_3 Rigidbody2D rSpriteRigidbody2D = a_rSprite.GetComponent<Rigidbody2D>( ); // Setup the rigidbody if( rCurrentSettings.physicsMode == Uni2DSprite.PhysicsMode.Dynamic ) { // Add the rigidbody component if( rSpriteRigidbody2D == null ) { rSpriteRigidbody2D = a_rSprite.gameObject.AddComponent<Rigidbody2D>( ); } rSpriteRigidbody2D.isKinematic = rCurrentSettings.isKinematic; } else if( rSpriteRigidbody2D != null ) // a rigidbody is not needed in the other modes { MonoBehaviour.DestroyImmediate( rSpriteRigidbody2D ); } #endif } break; } }