// 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; } }
public bool ApplySettings(Uni2DSprite a_rSpriteMesh) { if(spriteTexture != null) { settingsChanged = false; GameObject rSpriteMeshGameObject = a_rSpriteMesh.gameObject; Uni2DEditorUtilsSpriteBuilder.UpdateSpriteFromTexture( rSpriteMeshGameObject, spriteTexture, textureAtlas, vertexColor, alphaCutOff, polygonizationAccuracy, extrusionDepth, spriteScale, polygonizeHoles, pivotPointCoords, pivotPointType, physicMode, collisionType, isKinematic); EditorUtility.SetDirty(a_rSpriteMesh); return true; } else { return false; } }
// 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; } } }
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; }
// Save Mesh resources public static void DuplicateResources( Uni2DSprite a_rSprite, bool a_bPrefab = false) { // Sprite mesh Mesh rSpriteMesh = a_rSprite.SpriteData.renderMesh; if( rSpriteMesh != null ) { Mesh rDuplicatedMesh = Uni2DEditorResourceCopyUtils.DuplicateMesh( rSpriteMesh ); MeshFilter rMeshFilterComponent = a_rSprite.GetComponent<MeshFilter>( ); SkinnedMeshRenderer rSkinnedMeshRendererComponent = a_rSprite.GetComponent<SkinnedMeshRenderer>( ); // Apply the new generated mesh to the mesh filter component // and save it as generated data if( rMeshFilterComponent != null ) { rMeshFilterComponent.sharedMesh = rDuplicatedMesh; a_rSprite.SpriteData.renderMesh = rDuplicatedMesh; } if( rSkinnedMeshRendererComponent != null ) { rSkinnedMeshRendererComponent.sharedMesh = rDuplicatedMesh; } } // Duplicate the generated material if(a_rSprite.SpriteData.generatedMaterial != null) { // Duplicate generated mesh a_rSprite.SpriteData.generatedMaterial = new Material(a_rSprite.SpriteData.generatedMaterial); // Change the render mesh material ref to the duplicate a_rSprite.SpriteData.renderMeshMaterial = a_rSprite.SpriteData.generatedMaterial; // Update the renderer material a_rSprite.GetComponent<Renderer>().sharedMaterial = a_rSprite.SpriteData.generatedMaterial; } // Mesh collider(s) List<Mesh> rMeshCollidersList = a_rSprite.SpriteData.meshCollidersList; List<MeshCollider> rMeshColliderComponentsList = a_rSprite.SpriteData.meshColliderComponentsList; for( int iMeshIndex = 0, iMeshCount = rMeshCollidersList.Count; iMeshIndex < iMeshCount; ++iMeshIndex ) { Mesh rDuplicatedMeshCollider = Uni2DEditorResourceCopyUtils.DuplicateMesh( rMeshCollidersList[ iMeshIndex ] ); MeshCollider rMeshCollider = rMeshColliderComponentsList[ iMeshIndex ]; if( rMeshCollider != null ) { rMeshCollider.sharedMesh = rDuplicatedMeshCollider; } rMeshCollidersList[ iMeshIndex ] = rDuplicatedMeshCollider; } #if UNITY_EDITOR EditorUtility.SetDirty( a_rSprite ); #endif }
// Adds a bone to a sprite from a given mouse GUI position public static Uni2DSmoothBindingBone AddBoneToSprite( Uni2DSprite a_rSprite, Vector2 a_f2MouseGUIPos, Uni2DSmoothBindingBone a_rBoneRoot ) { Transform rSpriteTransform = a_rSprite.transform; Ray oWorldRay = HandleUtility.GUIPointToWorldRay( a_f2MouseGUIPos ); Plane oSpritePlane = new Plane( rSpriteTransform.forward, rSpriteTransform.position ); // INFO: normal specific to Uni2D's planes float fDistance; if( oSpritePlane.Raycast( oWorldRay, out fDistance ) ) { Uni2DSmoothBindingBone oBone; if( a_rBoneRoot == null ) { oBone = Uni2DEditorSmoothBindingUtils.CreateNewBone( a_rSprite ); } else { switch( a_rBoneRoot.ChildCount ) { case 0: { // Add child oBone = Uni2DEditorSmoothBindingUtils.CreateNewBone( a_rBoneRoot ); } break; case 1: { // Create branch for existing child + add another one Uni2DSmoothBindingBone oFakeParent1 = Uni2DEditorSmoothBindingUtils.CreateNewBone( a_rBoneRoot, true ); Uni2DSmoothBindingBone oFakeParent2 = Uni2DEditorSmoothBindingUtils.CreateNewBone( a_rBoneRoot, true ); a_rBoneRoot.Children[ 0 ].Parent = oFakeParent1; oBone = Uni2DEditorSmoothBindingUtils.CreateNewBone( oFakeParent2 ); } break; default: { // Add branch Uni2DSmoothBindingBone oFakeParent = Uni2DEditorSmoothBindingUtils.CreateNewBone( a_rBoneRoot, true ); oBone = Uni2DEditorSmoothBindingUtils.CreateNewBone( oFakeParent ); } break; } } oBone.transform.position = oWorldRay.GetPoint( fDistance ); return oBone; } return null; }
// Use this for initialization void Start() { free = RigidbodyConstraints.FreezePositionZ | RigidbodyConstraints.FreezeRotationX | RigidbodyConstraints.FreezeRotationY; locked = RigidbodyConstraints.FreezePosition | RigidbodyConstraints.FreezeRotation; sprite = this.GetComponent<Uni2DSprite> (); linkColor = new Color32 (255, 255, 255, 255); freeColor = new Color32 (255, 255, 255, 128); IsLink = true; isLock = false; bodyT=this.GetComponent<SpringJoint> ().connectedBody.transform; }
public void MoveBoneAlongSpritePlane(Vector2 a_f2MouseGUIPos, bool a_bMoveChildren = true) { Uni2DSprite rSprite = this.Sprite; if (rSprite != null) { Transform rSpriteTransform = rSprite.transform; Ray oWorldRay = HandleUtility.GUIPointToWorldRay(a_f2MouseGUIPos); Plane oSpritePlane = new Plane(rSpriteTransform.forward, rSpriteTransform.position); float fDistance; if (oSpritePlane.Raycast(oWorldRay, out fDistance)) { Vector3 f3Delta = oWorldRay.GetPoint(fDistance) - this.transform.position; this.transform.position += f3Delta; EditorUtility.SetDirty(this); if (a_bMoveChildren == false) { foreach (Uni2DSmoothBindingBone rBoneChild in this.Children) { if (rBoneChild.IsFakeRootBone == false) { rBoneChild.transform.position -= f3Delta; } else { foreach (Uni2DSmoothBindingBone rFakeBoneChild in rBoneChild.Children) { rFakeBoneChild.transform.position -= f3Delta; EditorUtility.SetDirty(rFakeBoneChild.transform); } } EditorUtility.SetDirty(rBoneChild.transform); } } } } }
///// Picking ///// private static Uni2DSmoothBindingBone PickNearestBone( Uni2DSprite a_rSprite, Vector2 a_f2MouseGUIPos, out BoneHandle a_ePickedHandle, Uni2DSmoothBindingBone a_rExclude = null, bool a_bAlsoPickBoneLink = false, float a_fBonePickRadius = Uni2DEditorSmoothBindingUtils.bonePosingPickRadius, float a_fBoneLinkPickRadius = Uni2DEditorSmoothBindingUtils.boneLinkAnimPickRadius ) { Uni2DSmoothBindingBone rNearestBone = null; Uni2DSmoothBindingBone rNearestBoneLink = null; // Squarred pick radius float fMinSqrBoneDistance = a_fBonePickRadius * a_fBonePickRadius; float fMinBoneLinkDistance = a_fBoneLinkPickRadius; Uni2DSmoothBindingBone[ ] rBones = a_rSprite.Bones; //rSpriteTransform.GetComponentsInChildren<Transform>( false ).Except( oBonesToExclude ).ToArray( ); // Look for nearest bone for( int iBoneIndex = 0, iBoneCount = rBones.Length; iBoneIndex < iBoneCount; ++iBoneIndex ) { Uni2DSmoothBindingBone rBone = rBones[ iBoneIndex ]; if( a_rExclude != rBone && rBone.IsFakeRootBone == false ) { Vector2 f2BoneGUIPos = HandleUtility.WorldToGUIPoint( rBone.transform.position ); Vector2 f2BoneToMouseGUI = a_f2MouseGUIPos - f2BoneGUIPos; float fSqrDistance = f2BoneToMouseGUI.sqrMagnitude; // New min/nearest if( fSqrDistance < fMinSqrBoneDistance ) { rNearestBone = rBone; fMinSqrBoneDistance = fSqrDistance; } // Look for nearest bone link Uni2DSmoothBindingBone rBoneParent = rBone.Parent; if( a_bAlsoPickBoneLink && rBoneParent != null ) { float fLinkDistance = HandleUtility.DistancePointToLineSegment( a_f2MouseGUIPos, f2BoneGUIPos, HandleUtility.WorldToGUIPoint( rBoneParent.transform.position ) ); if( fLinkDistance < fMinBoneLinkDistance ) { fMinBoneLinkDistance = fLinkDistance; rNearestBoneLink = rBone; } } } } // Picking result if( rNearestBone == null && rNearestBoneLink == null ) { a_ePickedHandle = BoneHandle.None; } else if( rNearestBone != null ) { if( fMinSqrBoneDistance <= a_fBonePickRadius * a_fBonePickRadius * 0.25f ) { a_ePickedHandle = /*invertActionAreas == false ?*/ BoneHandle.InnerDisc; //: BoneHandle.OuterDisc; } else { a_ePickedHandle = /*invertActionAreas == false ?*/ BoneHandle.OuterDisc; //: BoneHandle.InnerDisc; } } else { rNearestBone = rNearestBoneLink; a_ePickedHandle = BoneHandle.Link; } return rNearestBone; }
// Update a sprite in resource public static void UpdateSpriteInResourceInABatch(Uni2DSprite a_rSprite) { ms_bUndoEnabled = false; //Uni2DSprite.prefabUpdateInProgress = true; GameObject rPrefab = PrefabUtility.FindPrefabRoot(a_rSprite.gameObject); // Instantiate the prefab GameObject rPrefabInstance = InstantiateSpritePrefabWithoutConnection(rPrefab); Uni2DSprite[] oSpritesPrefabInstance = rPrefabInstance.GetComponentsInChildren<Uni2DSprite>(); // Retrieve the instance of the sprite Uni2DSprite rSpriteInstance = null; foreach(Uni2DSprite rSpritePrefabInstance in oSpritesPrefabInstance) { if(PrefabUtility.GetPrefabParent(rSpritePrefabInstance) == a_rSprite) { rSpriteInstance = rSpritePrefabInstance; } } if(rSpriteInstance != null) { // Rebuild the sprite rSpriteInstance.RebuildInABatch(); // Replace prefab ReplaceSpritePrefab(rPrefabInstance, rPrefab); } // Clear the prefab instance Editor.DestroyImmediate(rPrefabInstance); //Uni2DSprite.prefabUpdateInProgress = false; AssetDatabase.SaveAssets( ); AssetDatabase.Refresh( ); ms_bUndoEnabled = true; }
public static void DeleteBone( Uni2DSprite a_rSprite, Uni2DSmoothBindingBone a_rBoneToDelete ) { if( a_rBoneToDelete != null ) { Uni2DSmoothBindingBone rBoneParent = a_rBoneToDelete.Parent; // Need to pack bone hierarchy if( rBoneParent != null && rBoneParent.IsFakeRootBone ) { Uni2DSmoothBindingBone rBoneGrandParent = rBoneParent.Parent; Object.DestroyImmediate( rBoneParent.gameObject ); // We broke the branch => flatten bone hierarchy if( rBoneGrandParent != null && rBoneGrandParent.IsBranchBone == false ) { Uni2DSmoothBindingBone rFakeParent = rBoneGrandParent.Children[ 0 ]; rFakeParent.Children[ 0 ].Parent = rBoneGrandParent; Object.DestroyImmediate( rFakeParent.gameObject ); } } else { Object.DestroyImmediate( a_rBoneToDelete.gameObject ); } } }
// Specialized picking call used in posing mode public static Uni2DSmoothBindingBone PickNearestBoneInPosingMode( Uni2DSprite a_rSprite, Vector2 a_f2MouseGUIPos, out BoneHandle a_ePickedHandle, Uni2DSmoothBindingBone a_rExclude = null ) { return Uni2DEditorSmoothBindingUtils.PickNearestBone( a_rSprite, a_f2MouseGUIPos, out a_ePickedHandle, a_rExclude, true, Uni2DEditorSmoothBindingUtils.bonePosingPickRadius, Uni2DEditorSmoothBindingUtils.boneLinkPosingPickRadius ); }
// 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; }
// 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 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; }
// 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; }
// Get help message private string GetHelpMessage(Uni2DSprite.PhysicMode a_ePhysicMode, Uni2DSprite.CollisionType a_eCollisionType) { string oHelpMessage = ""; if(a_ePhysicMode == Uni2DSprite.PhysicMode.NoPhysic) { oHelpMessage = "In no physic mode, there is no collider attached to the sprite."; } else if(a_ePhysicMode == Uni2DSprite.PhysicMode.Static) { if(a_eCollisionType == Uni2DSprite.CollisionType.Convex) { oHelpMessage = "In static convex mode, the mesh collider does not respond to collisions (e.g. not a rigidbody) as a convex mesh.\n" + "Unity computes a convex hull if the mesh collider is not convex."; } else if(a_eCollisionType == Uni2DSprite.CollisionType.Concave) { oHelpMessage = "In static concave mode, mesh collider does not respond to collisions (e.g. not a rigidbody) as a concave mesh.\n" + "A mesh collider marked as concave only interacts with primitive colliders (boxes, spheres...) and convex meshes."; } else if(a_eCollisionType == Uni2DSprite.CollisionType.Compound) { oHelpMessage = "In static compound mode, mesh collider does not respond to collisions (e.g. not a rigidbody) as a concave mesh composed of small convex meshes.\n" + "It allows the collider to block any other collider at the expense of performances."; } } else if(a_ePhysicMode == Uni2DSprite.PhysicMode.Dynamic) { if(a_eCollisionType == Uni2DSprite.CollisionType.Convex) { oHelpMessage = "In dynamic convex mode, mesh collider does respond to collisions (e.g. rigidbody) as a convex mesh.\n" + "Unity computes a convex hull if the mesh collider is not convex."; } else if(a_eCollisionType == Uni2DSprite.CollisionType.Concave) { oHelpMessage = "In dynamic concave mode, mesh collider does respond to collisions (e.g. rigidbody) as a concave mesh.\n" + "A mesh collider marked as concave only interacts with primitive colliders (boxes, spheres...)."; } else if(a_eCollisionType == Uni2DSprite.CollisionType.Compound) { oHelpMessage = "In dynamic compound mode, mesh collider does respond to collisions (e.g. rigidbody) as a concave mesh composed of small convex meshes.\n" + "It allows the collider to interact with any other collider at the expense of performances."; } } return oHelpMessage; }
// 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; }
//////////////////////////////////////////////////////////////////////////////// public static void RegenerateInteractiveDataFromSettings( Uni2DSprite a_rSprite ) { // New sprite settings Uni2DEditorSpriteSettings rSpriteSettings = a_rSprite.SpriteSettings; // Current sprite data Uni2DEditorSpriteData rSpriteData = a_rSprite.SpriteData; if(rSpriteSettings.ShouldUseAtlas()) { // If using the atlas remove the shared material rSpriteSettings.sharedMaterial = null; } else if(rSpriteSettings.sharedMaterial != null) { // If the shared material is in use // Ensure the sprite texture is the shared material texture Texture rSharedMaterialTexture = rSpriteSettings.sharedMaterial.mainTexture; if(rSharedMaterialTexture != null) { rSpriteSettings.textureContainer = new Texture2DContainer( (Texture2D)rSharedMaterialTexture, false ); } else { rSpriteSettings.sharedMaterial.mainTexture = rSpriteSettings.textureContainer; } } Texture2DContainer rSpriteTextureContainer = rSpriteSettings.textureContainer; Texture2D rSpriteTexture = rSpriteTextureContainer; a_rSprite.RestorePosePosition( ); // If texture changed... if( a_rSprite.m_oTextureImportGUID != Uni2DEditorUtils.GetTextureImportGUID( rSpriteTexture ) ) { string oTexturePath = AssetDatabase.GetAssetPath( rSpriteTexture ); TextureImporter rTextureImporter = TextureImporter.GetAtPath(oTexturePath) as TextureImporter; if(rTextureImporter != null) { // Regenerate sprite mat & mesh TextureImporterSettings oTextureImporterSettings = Uni2DEditorSpriteBuilderUtils.TextureProcessingBegin(rTextureImporter); Uni2DEditorSpriteBuilderUtils.GenerateSpriteMatFromSettings( rSpriteSettings, a_rSprite ); Uni2DEditorSpriteBuilderUtils.GenerateSpriteMeshFromSettings( rSpriteSettings, a_rSprite ); // Don't forget to update texture import ID a_rSprite.AfterBuild(); Uni2DEditorSpriteBuilderUtils.TextureProcessingEnd( rTextureImporter, oTextureImporterSettings ); } } else { Uni2DEditorSpriteBuilderUtils.GenerateSpriteMatFromSettings( rSpriteSettings, a_rSprite ); float fRealScale = rSpriteSettings.ScaleFactor; // Current pivot point Vector2 f2CurrentPivotPoint = rSpriteData.pivotCoords; Vector2 f2NewPivotCoords = Uni2DSpriteUtils.ComputePivotCoords( rSpriteData.spriteWidth, rSpriteData.spriteHeight, rSpriteSettings.pivotType, rSpriteSettings.pivotCustomCoords ); // The delta to apply float fScalingDelta = fRealScale / rSpriteData.scale; Vector3 f3ScaledDeltaPivot = ( f2NewPivotCoords - f2CurrentPivotPoint ) * fRealScale; // Rigidbody settings (kinematic, constraints...) Uni2DEditorSpriteBuilderUtils.SetupRigidbodyFor2D( a_rSprite ); // Apply delta to mesh colliders for( int iMeshIndex = 0, iMeshCount = rSpriteData.meshCollidersList.Count; iMeshIndex < iMeshCount; ++iMeshIndex ) { Mesh rMesh = rSpriteData.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 ) * rSpriteSettings.extrusionDepth * 0.5f; oMeshVerticesArray[ iVertexIndex ] = f3Vertex; } // Must set array again ("vertices" getter gives a copy) rMesh.vertices = oMeshVerticesArray; // Force mesh collider update by setting it null then reassigning it MeshCollider rMeshCollider = rSpriteData.meshColliderComponentsList[ iMeshIndex ]; rMeshCollider.sharedMesh = null; rMeshCollider.sharedMesh = rMesh; } // Apply delta to sprite mesh Mesh rSpriteMesh = rSpriteData.renderMesh; Vector3[ ] oSpriteQuadMeshVerticesArray = rSpriteMesh.vertices; for( int iVertexIndex = 0, iVertexCount = rSpriteMesh.vertexCount; iVertexIndex < iVertexCount; ++iVertexIndex ) { Vector3 f3Vertex = oSpriteQuadMeshVerticesArray[ iVertexIndex ]; f3Vertex -= f3ScaledDeltaPivot; f3Vertex.x *= fScalingDelta; f3Vertex.y *= fScalingDelta; oSpriteQuadMeshVerticesArray[ iVertexIndex ] = f3Vertex; } // Must set array again ("vertices" getter gives a copy) rSpriteMesh.vertices = oSpriteQuadMeshVerticesArray; // Recalc mesh bounds rSpriteMesh.RecalculateBounds( ); // Update vertex color Uni2DSpriteUtils.UpdateMeshVertexColor( rSpriteMesh, rSpriteSettings.vertexColor ); // Update UV // Check first the atlas is still valid Uni2DTextureAtlas rTextureAtlas = rSpriteSettings.atlas; Material rSpriteMaterial; if( rSpriteSettings.ShouldUseAtlas( ) ) { // Update atlas generation ID a_rSprite.atlasGenerationID = rTextureAtlas.generationId; rSpriteMaterial = rTextureAtlas.GetMaterial( rSpriteTextureContainer.GUID ); } else { a_rSprite.atlasGenerationID = ""; rSpriteSettings.atlas = null; rTextureAtlas = null; rSpriteMaterial = rSpriteData.renderMeshMaterial; } // .. and rebuild UVs rSpriteMesh.uv = Uni2DSpriteUtils.BuildUVs( rSpriteTextureContainer, rSpriteData.renderMeshUVs, rTextureAtlas ); // Update material Renderer rRenderer = a_rSprite.renderer; if( rRenderer != null ) { rRenderer.sharedMaterial = rSpriteMaterial; } // If the pivot point has changed if( f2CurrentPivotPoint != f2NewPivotCoords ) { // Compute the local position change Vector3 f3LocalPivotMovement = f3ScaledDeltaPivot; Vector3 f3PivotMovement = f3ScaledDeltaPivot; Vector3 f3SpriteTransformLocalScale = a_rSprite.transform.localScale; f3PivotMovement.Scale( f3SpriteTransformLocalScale ); f3PivotMovement = a_rSprite.transform.TransformDirection( f3PivotMovement ); Transform rParentTransform = a_rSprite.transform.parent; if(rParentTransform != null) { f3PivotMovement = rParentTransform.InverseTransformDirection(f3PivotMovement); } a_rSprite.transform.localPosition += f3PivotMovement; // Update bone roots local pos (if any) /*a_rSprite.RestorePosePosition( ); foreach( Uni2DSmoothBindingBone rBone in a_rSprite.Bones ) { if( rBone.Parent == null ) { Vector3 f3BonePivotMovement = rBone.transform.InverseTransformDirection( f3PivotMovement ); rBone.transform.localPosition -= f3BonePivotMovement; } }*/ Transform rMeshCollidersRootTransform = rSpriteData.meshCollidersRootGameObject != null ? rSpriteData.meshCollidersRootGameObject.transform : null; foreach(Transform rChild in a_rSprite.transform) { if( rChild != rMeshCollidersRootTransform ) { rChild.localPosition -= f3LocalPivotMovement; } } } a_rSprite.UpdatePosing( ); // Save new pivot coords rSpriteData.pivotCoords = f2NewPivotCoords; rSpriteData.scale = rSpriteSettings.ScaleFactor; } }
// NEW // Removes the generated physic colliders attached to a sprite private static void RemoveGeneratedColliders( Uni2DSprite a_rSpriteToClean ) { if( a_rSpriteToClean != null ) { // Retrieve the generated data of the sprite to clean Uni2DEditorSpriteData rSpriteData = a_rSpriteToClean.SpriteData; // Delete resources // Delete game objects in excess foreach( MeshCollider rMeshColliderComponent in rSpriteData.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_rSpriteToClean.gameObject ) { // Destroy game object AND component GameObject.DestroyImmediate( rMeshColliderComponent.gameObject ); } else { // Destroy component MonoBehaviour.DestroyImmediate( rMeshColliderComponent ); } } } // Destroy mesh collider root game object (if any) if( rSpriteData.meshCollidersRootGameObject != null ) { // Destroy game object GameObject.DestroyImmediate( rSpriteData.meshCollidersRootGameObject ); } // Delete components in excess Rigidbody rRigidbodyComponent = a_rSpriteToClean.GetComponent<Rigidbody>( ); if( rRigidbodyComponent != null ) { // Destroy component MonoBehaviour.DestroyImmediate( rRigidbodyComponent ); } // Reset mesh list rSpriteData.meshCollidersList = null; rSpriteData.meshColliderComponentsList = null; rSpriteData.colliderTriangleCount = 0; } }
// 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; }
// On sprite reset public void OnSpriteReset(Uni2DSprite a_rSpriteMesh) { if(ms_bInspectorHasBeenInit) { // Cancel Reset // Parameters RestoreInspectorInitParameter(a_rSpriteMesh); // Data a_rSpriteMesh.spriteTextureWidth = spriteTextureWidth; a_rSpriteMesh.spriteTextureHeight = spriteTextureHeight; a_rSpriteMesh.spriteQuadMesh = spriteQuadMesh; a_rSpriteMesh.spriteQuadMaterial = spriteQuadMaterial; a_rSpriteMesh.meshCollidersList.Clear(); a_rSpriteMesh.meshCollidersList.AddRange(meshCollidersList); a_rSpriteMesh.meshCollidersRootGameObject = meshCollidersRootGameObject; a_rSpriteMesh.meshColliderComponentsList.Clear(); a_rSpriteMesh.meshColliderComponentsList.AddRange(meshColliderComponentsList); // Reset the temporary values Uni2DEditorSpriteBuilderWindow.ResetSpriteParameters( ref vertexColor, ref alphaCutOff, ref polygonizationAccuracy, ref extrusionDepth, ref spriteScale, ref polygonizeHoles, ref pivotPointCoords, ref pivotPointType, ref physicMode, ref collisionType, ref isKinematic); settingsChanged = false; ApplySettings(a_rSpriteMesh); } }
// 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; }
// Restore inspector public void RestoreInspectorInitParameter(Uni2DSprite a_rSpriteMesh) { // Parameters a_rSpriteMesh.spriteTexture = m_rSpriteTextureInit; a_rSpriteMesh.textureAtlas = m_rTextureAtlasInit; a_rSpriteMesh.VertexColor = m_oVertexColorInit; a_rSpriteMesh.physicMode = m_ePhysicModeInit; a_rSpriteMesh.collisionType = m_eCollisionTypeInit; a_rSpriteMesh.isKinematic = m_bIsKinematicInit; a_rSpriteMesh.spriteScale = m_fSpriteScaleInit; a_rSpriteMesh.pivotPointType = m_ePivotPointTypeInit; a_rSpriteMesh.pivotPointCoords = m_f2PivotPointCoordsInit; a_rSpriteMesh.alphaCutOff = m_fAlphaCutOffInit; a_rSpriteMesh.polygonizationAccuracy = m_fPolygonizationAccuracyInit; a_rSpriteMesh.polygonizeHoles = m_bPolygonizeHolesInit; a_rSpriteMesh.extrusionDepth = m_fExtrusionDepthInit; }
public Uni2DEditorSmoothBindingGUI( Uni2DSprite a_rSprite ) { this.Reset( a_rSprite ); }
// Reset a sprite public static void ResetSpriteParameters( ref Color a_rVertexColor, ref float a_fAlphaCutOff, ref float a_fPoligonizationAccuracy, ref float a_fExtrusionDepth, ref float a_fScale, ref bool a_bPolygonizeHoles, ref Vector2 a_f2CustomPivotPoint, ref Uni2DSprite.PivotPointType a_ePivotPoint, ref Uni2DSprite.PhysicMode a_ePhysicMode, ref Uni2DSprite.CollisionType a_eCollisionType, ref bool a_bIsKinematic) { // Default sprite parameters a_rVertexColor = m_oVertexColorSprite; a_ePhysicMode = m_ePhysicModeSprite; a_eCollisionType = m_eCollisionTypeSprite; a_bIsKinematic = m_bIsKinematicSprite; a_fScale = m_fScaleSprite; a_ePivotPoint = m_ePivotPointSprite; a_f2CustomPivotPoint = m_f2CustomPivotPointSprite; // Default physic sprite parameters a_fAlphaCutOff = m_fAlphaCutOffPhysicSprite; a_fPoligonizationAccuracy = m_fPolygonizationAccuracyPhysicSprite; a_bPolygonizeHoles = m_bPolygonizeHolesPhysicSprite; a_fExtrusionDepth = m_fExtrusionDepthPhysicSprite; }
// 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; }
public void Reset( Uni2DSprite a_rSprite, bool a_bKeepCurrentModeIfPossible = false ) { m_rLastAddedBone = null; m_rBoneChainOrigin = null; Uni2DEditorSmoothBindingGUI.activeBone = null; m_f2MouseGUIOffset = Vector2.zero; ms_eEditorTool = BoneEditorTool.Select; BoneEditMode eSavedEditMode = Uni2DEditorSmoothBindingGUI.CurrentBoneEditMode; Uni2DEditorSmoothBindingGUI.CurrentBoneEditMode = BoneEditMode.None; ms_rSprite = a_rSprite; if( a_bKeepCurrentModeIfPossible ) { Uni2DEditorSmoothBindingGUI.CurrentBoneEditMode = eSavedEditMode; } }
public static Uni2DSmoothBindingBone CreateNewBone( Uni2DSprite a_rSprite ) { return Uni2DEditorSmoothBindingUtils.CreateNewBone( a_rSprite.transform, false ); }
// Returns true if the Uni2DSprite data have been generated // for a given physic mode public bool AreDataGenerated( Uni2DSprite.PhysicsMode a_ePhysicMode ) { return this.renderMesh != null && this.renderMeshMaterial != null && ( a_ePhysicMode == Uni2DSprite.PhysicsMode.NoPhysics // No physic == no mesh collider to generate || ( this.meshCollidersList != null && this.meshCollidersList.Contains( null ) == false && this.meshColliderComponentsList != null && this.meshColliderComponentsList.Contains( null ) == false ) ); }
public static void UpdateSpriteSize( Uni2DSprite a_rSprite, float a_fWidth, float a_fHeight ) { Uni2DEditorSpriteSettings rSpriteSettings = a_rSprite.SpriteSettings; Uni2DEditorSpriteData rSpriteData = a_rSprite.SpriteData; float fExtrusionDepth = rSpriteSettings.extrusionDepth; Vector2 f2OldPivotCoords = rSpriteData.pivotCoords; // The delta to apply Vector2 f2ScalingDelta = new Vector2( a_fWidth / rSpriteData.spriteWidth, a_fHeight / rSpriteData.spriteHeight ); // Apply to the pivot point Vector2 f2NewPivotCoords = Vector2.Scale( f2OldPivotCoords, f2ScalingDelta ); // Apply delta to mesh colliders List<Mesh> rMeshCollidersList = rSpriteData.meshCollidersList; if( rMeshCollidersList != null) { for( int iMeshIndex = 0, iMeshCount = rMeshCollidersList.Count; iMeshIndex < iMeshCount; ++iMeshIndex ) { Mesh rMesh = rMeshCollidersList[ iMeshIndex ]; Vector3[ ] oMeshVerticesArray = rMesh.vertices; for( int iVertexIndex = 0, iVertexCount = rMesh.vertexCount; iVertexIndex < iVertexCount; ++iVertexIndex ) { Vector3 f3Vertex = oMeshVerticesArray[ iVertexIndex ]; f3Vertex.x *= f2ScalingDelta.x; f3Vertex.y *= f2ScalingDelta.y; //f3Vertex -= f3ScaledDeltaPivot; f3Vertex.z = Mathf.Sign( f3Vertex.z ) * fExtrusionDepth * 0.5f; oMeshVerticesArray[ iVertexIndex ] = f3Vertex; } // Must set array again ("vertices" getter gives a copy) rMesh.vertices = oMeshVerticesArray; MeshCollider rMeshCollider = rSpriteData.meshColliderComponentsList[ iMeshIndex ]; if(rMeshCollider != null) { rMeshCollider.sharedMesh = null; rMeshCollider.sharedMesh = rMesh; } } } // Apply delta to sprite quad mesh Mesh rSpriteMesh = rSpriteData.renderMesh; Vector3[ ] oSpriteQuadMeshVerticesArray = rSpriteMesh.vertices; for( int iVertexIndex = 0, iVertexCount = rSpriteMesh.vertexCount; iVertexIndex < iVertexCount; ++iVertexIndex ) { Vector3 f3Vertex = oSpriteQuadMeshVerticesArray[ iVertexIndex ]; f3Vertex.x *= f2ScalingDelta.x; f3Vertex.y *= f2ScalingDelta.y; //f3Vertex -= f3ScaledDeltaPivot; oSpriteQuadMeshVerticesArray[ iVertexIndex ] = f3Vertex; } rSpriteSettings.pivotCustomCoords = f2NewPivotCoords; // Must set array again ("vertices" getter gives a copy) rSpriteMesh.vertices = oSpriteQuadMeshVerticesArray; }