// On new frame private void OnNewFrame() { if (m_rCurrentClip != null) { int iFrameCount = m_rCurrentClip.FrameCount; int iFrame; if (iFrameCount > 0) { if (iFrameCount == 1) { iFrame = 0; } else { iFrame = (int)Mathf.PingPong(m_iCurrentFrameIndex, iFrameCount - 1); } m_rCurrentFrame = m_rCurrentClip.frames[iFrame]; //m_rSprite.SetFrame(m_rCurrentFrame); RaiseAnimationNewFrameEvent(); RaiseAnimationFrameEvent(); } else { m_rCurrentFrame = null; } } }
public override void OnPreviewGUI(Rect a_rRect, GUIStyle a_rBackgroundStyle) { float fDeltaTime = this.ComputeDeltaTime(ref m_lLastPreviewTimeTicks); m_oAnimationPlayerClipPreview.Update(fDeltaTime); if (Event.current.type == EventType.Repaint) { Uni2DAnimationFrame rFrame = m_oAnimationPlayerClipPreview.Frame; Texture2D rFrameTexture; if (rFrame == null || rFrame.textureContainer == null || rFrame.textureContainer.Texture == null) { rFrameTexture = null; } else { rFrameTexture = rFrame.textureContainer; } GUIContent rPreviewContent = new GUIContent(rFrameTexture); a_rBackgroundStyle.alignment = TextAnchor.MiddleCenter; a_rBackgroundStyle.Draw(a_rRect, rPreviewContent, GUIUtility.GetControlID(rPreviewContent, FocusType.Passive)); } }
// Constructor public Uni2DAnimationFrameEvent(Uni2DSpriteAnimation a_rSpriteAnimation, int a_iClipIndex, Uni2DAnimationClip a_rClip, int a_iFrameIndex, Uni2DAnimationFrame a_rFrame) { spriteAnimation = a_rSpriteAnimation; clipIndex = a_iClipIndex; clip = a_rClip; frameIndex = a_iFrameIndex; frame = a_rFrame; }
// Is this frame is different from an other frame public bool IsDifferentFrom(Uni2DAnimationFrame a_rOtherFrame) { return(textureContainer != a_rOtherFrame.textureContainer || name != a_rOtherFrame.name || atlas != a_rOtherFrame.atlas || triggerEvent != a_rOtherFrame.triggerEvent || frameInfos.IsDifferentFrom(a_rOtherFrame.frameInfos)); }
// Is this frame is different from an other frame public bool IsDifferentFrom( Uni2DAnimationFrame a_rOtherFrame ) { return textureContainer != a_rOtherFrame.textureContainer || name != a_rOtherFrame.name || atlas != a_rOtherFrame.atlas || triggerEvent != a_rOtherFrame.triggerEvent || frameInfos.IsDifferentFrom( a_rOtherFrame.frameInfos ); }
// Constructor public Uni2DAnimationFrameEvent(Uni2DSpriteAnimation a_rSpriteAnimation, int a_iClipIndex, Uni2DAnimationClip a_rClip, int a_iFrameIndex, Uni2DAnimationFrame a_rFrame) { spriteAnimation = a_rSpriteAnimation; clipIndex = a_iClipIndex; clip = a_rClip; frameIndex = a_iFrameIndex; frame = a_rFrame; }
// Copy Constructor public Uni2DAnimationFrame(Uni2DAnimationFrame a_rFrameSource) { name = a_rFrameSource.name; atlas = a_rFrameSource.atlas; triggerEvent = a_rFrameSource.triggerEvent; a_rFrameSource.frameInfos.CopyTo(frameInfos); textureContainer = new Texture2DContainer(a_rFrameSource.textureContainer.GUID, atlas == null); }
private static void ApplySettings(Uni2DAnimationClip[] a_rAnimationClips, AnimationClipRegeneration a_eRegenerate) { int iClipCount = a_rAnimationClips.Length; if (iClipCount == 1) { a_rAnimationClips[0].ApplySettings(a_eRegenerate); } else if (iClipCount > 1) { // Apply clip settings first, atlases will be generated only after // (Atlases can be shared accross clips, so prevent them to be uselessly regenerated several times) HashSet <Uni2DTextureAtlas> oAtlases = new HashSet <Uni2DTextureAtlas>( ); for (int iClipIndex = 0; iClipIndex < iClipCount; ++iClipIndex) { Uni2DAnimationClip rAnimationClip = a_rAnimationClips[iClipIndex]; Uni2DTextureAtlas rGlobalAtlas = rAnimationClip.globalAtlas; if (rGlobalAtlas != null) { // Add the atlas if not already added if (a_eRegenerate == AnimationClipRegeneration.RegenerateAll || (a_eRegenerate == AnimationClipRegeneration.RegenerateAlsoAtlasIfNeeded && (rGlobalAtlas.UnappliedSettings || rGlobalAtlas.Contains(rAnimationClip.GetAllFramesTextureGUIDs( )) == false))) { oAtlases.Add(rGlobalAtlas); } } else // Null => atlas per frame { for (int iFrameIndex = 0, iFrameCount = rAnimationClip.FrameCount; iFrameIndex < iFrameCount; ++iFrameIndex) { Uni2DAnimationFrame rFrame = rAnimationClip.frames[iFrameIndex]; Uni2DTextureAtlas rFrameAtlas = rFrame.atlas; if (rFrameAtlas != null && (a_eRegenerate == AnimationClipRegeneration.RegenerateAll || (a_eRegenerate == AnimationClipRegeneration.RegenerateAlsoAtlasIfNeeded && (rFrameAtlas.UnappliedSettings || rFrameAtlas.Contains(rFrame.textureContainer.GUID) == false)))) { oAtlases.Add(rFrameAtlas); } } } // Regenerate clips only rAnimationClip.ApplySettings(AnimationClipRegeneration.RegenerateAnimationClipOnly); } // Then, regenerate atlases foreach (Uni2DTextureAtlas rAtlas in oAtlases) { rAtlas.ApplySettings( ); } } }
public static Uni2DAnimationClip CreateAnimationClip( List<Texture2D> a_rTexturesList, string a_rAnimationClipName = null, string a_rAnimationClipPath = null ) { // Create a new animation clip prefab GameObject oModel = new GameObject( ); Uni2DAnimationClip oAnimationClipModel = oModel.AddComponent<Uni2DAnimationClip>( ); // Path to save prefab string oPrefabPath; if( a_rTexturesList != null && a_rTexturesList.Count > 0 ) { // Sort by name IOrderedEnumerable<Texture2D> rOrderedTexturesEnumerable = a_rTexturesList.OrderBy( x => x.name ); Texture2D rFirstTexture = rOrderedTexturesEnumerable.First( ); // Create frames foreach( Texture2D rTexture in rOrderedTexturesEnumerable ) { Uni2DAnimationFrame oAnimationFrame = new Uni2DAnimationFrame( ); oAnimationFrame.textureContainer = new Texture2DContainer( rTexture, true ); oAnimationClipModel.frames.Add( oAnimationFrame ); } // Apply oAnimationClipModel.ApplySettings( Uni2DAnimationClip.AnimationClipRegeneration.RegenerateAnimationClipOnly ); oPrefabPath = ( a_rAnimationClipPath == null ? Uni2DEditorUtils.GetLocalAssetFolderPath( rFirstTexture ) : a_rAnimationClipPath ) + ( a_rAnimationClipName == null ? ( "AnimationClip_" + rFirstTexture.name ) : a_rAnimationClipName ) + ".prefab"; // Make prefab path unique oPrefabPath = AssetDatabase.GenerateUniqueAssetPath( oPrefabPath ); } else { // Unique prefab path string oClipName = ( a_rAnimationClipName == null ? mc_oAnimationClipDefaultName : a_rAnimationClipName ); oPrefabPath = ( a_rAnimationClipPath == null ? Uni2DEditorUtils.GenerateNewPrefabLocalPath( oClipName ) : AssetDatabase.GenerateUniqueAssetPath( a_rAnimationClipPath + oClipName ) ); } // Save it as a prefab GameObject oPrefab = PrefabUtility.CreatePrefab( oPrefabPath, oModel ); // Destroy model GameObject.DestroyImmediate( oModel ); // Return prefab animation clip component return oPrefab.GetComponent<Uni2DAnimationClip>( ); }
public static Uni2DAnimationClip CreateAnimationClip(List <Texture2D> a_rTexturesList, string a_rAnimationClipName = null, string a_rAnimationClipPath = null) { // Create a new animation clip prefab GameObject oModel = new GameObject( ); Uni2DAnimationClip oAnimationClipModel = oModel.AddComponent <Uni2DAnimationClip>( ); // Path to save prefab string oPrefabPath; if (a_rTexturesList != null && a_rTexturesList.Count > 0) { // Sort by name IOrderedEnumerable <Texture2D> rOrderedTexturesEnumerable = a_rTexturesList.OrderBy(x => x.name); Texture2D rFirstTexture = rOrderedTexturesEnumerable.First( ); // Create frames foreach (Texture2D rTexture in rOrderedTexturesEnumerable) { Uni2DAnimationFrame oAnimationFrame = new Uni2DAnimationFrame( ); oAnimationFrame.textureContainer = new Texture2DContainer(rTexture, true); oAnimationClipModel.frames.Add(oAnimationFrame); } // Apply oAnimationClipModel.ApplySettings(Uni2DAnimationClip.AnimationClipRegeneration.RegenerateAnimationClipOnly); oPrefabPath = (a_rAnimationClipPath == null ? Uni2DEditorUtils.GetLocalAssetFolderPath(rFirstTexture) : a_rAnimationClipPath) + (a_rAnimationClipName == null ? ("AnimationClip_" + rFirstTexture.name) : a_rAnimationClipName) + ".prefab"; // Make prefab path unique oPrefabPath = AssetDatabase.GenerateUniqueAssetPath(oPrefabPath); } else { // Unique prefab path string oClipName = (a_rAnimationClipName == null ? mc_oAnimationClipDefaultName : a_rAnimationClipName); oPrefabPath = (a_rAnimationClipPath == null ? Uni2DEditorUtils.GenerateNewPrefabLocalPath(oClipName) : AssetDatabase.GenerateUniqueAssetPath(a_rAnimationClipPath + oClipName)); } // Save it as a prefab GameObject oPrefab = PrefabUtility.CreatePrefab(oPrefabPath, oModel); // Destroy model GameObject.DestroyImmediate(oModel); // Return prefab animation clip component return(oPrefab.GetComponent <Uni2DAnimationClip>( )); }
public void SwapFrames(int a_iFrameIndexA, int a_iFrameIndexB) { int iFrameCount = frames.Count; if (a_iFrameIndexA != a_iFrameIndexB && 0 <= a_iFrameIndexA && 0 <= a_iFrameIndexB && a_iFrameIndexA < iFrameCount && a_iFrameIndexB < iFrameCount) { // Swap frames Uni2DAnimationFrame rTmp = frames[a_iFrameIndexA]; frames[a_iFrameIndexA] = frames[a_iFrameIndexB]; frames[a_iFrameIndexB] = rTmp; } }
// Generate atlas private void GenerateAtlas(AnimationClipRegeneration a_eRegeneration) { int iFrameCount = this.FrameCount; if (globalAtlas != null) // global atlas { string[] oTextureGUIDs = this.GetAllFramesTextureGUIDs( ); if (a_eRegeneration == AnimationClipRegeneration.RegenerateAll || (a_eRegeneration == AnimationClipRegeneration.RegenerateAlsoAtlasIfNeeded && (globalAtlas.UnappliedSettings || globalAtlas.Contains(oTextureGUIDs) == false))) { globalAtlas.ApplySettings( ); } globalAtlas.AddTextures(oTextureGUIDs); } else // Atlas per frame { HashSet <Uni2DTextureAtlas> oFrameAtlases = new HashSet <Uni2DTextureAtlas>( ); for (int iFrameIndex = 0; iFrameIndex < iFrameCount; ++iFrameIndex) { Uni2DAnimationFrame rFrame = frames[iFrameIndex]; Uni2DTextureAtlas rFrameAtlas = rFrame.atlas; if (rFrameAtlas != null) { string oFrameTextureGUID = rFrame.textureContainer != null ? rFrame.textureContainer.GUID : null; if (a_eRegeneration == AnimationClipRegeneration.RegenerateAll || (a_eRegeneration == AnimationClipRegeneration.RegenerateAlsoAtlasIfNeeded && (rFrameAtlas.UnappliedSettings || rFrameAtlas.Contains(oFrameTextureGUID) == false))) { oFrameAtlases.Add(rFrameAtlas); } rFrameAtlas.AddTextures(new string[1] { oFrameTextureGUID }); } } // Regenerate atlases foreach (Uni2DTextureAtlas rFrameAtlas in oFrameAtlases) { rFrameAtlas.ApplySettings( ); } } }
public override string GetInfoString( ) { Uni2DAnimationFrame rAnimationFrame = m_oAnimationPlayerClipPreview.Frame; if (rAnimationFrame != null) { string oTextureInfo; if (rAnimationFrame.textureContainer == null || rAnimationFrame.textureContainer.Texture == null) { oTextureInfo = "(None)"; } else { oTextureInfo = rAnimationFrame.textureContainer.Texture.name; } return("Wrap mode: " + m_oAnimationPlayerClipPreview.WrapMode + " - Frame texture: " + oTextureInfo); } return("(None)"); }
////////// Animation clip utils ////////// // Handles texture drop over inspector private void CheckTextureDragAndDrop( Rect a_rDropAreaRect ) { // Handle drag only if not multi selecting if( targets.Length == 1 ) { // Current Event Event rCurrentEvent = Event.current; EventType rCurrentEventType = rCurrentEvent.type; Vector2 f2MousePos = rCurrentEvent.mousePosition; // Dragging over clip inspector area if( a_rDropAreaRect.Contains( f2MousePos ) ) { bool bShouldAccept = false; // Does contain at least one texture2D? foreach( Object rObject in DragAndDrop.objectReferences ) { if( rObject is Texture2D ) { bShouldAccept = true; break; } } if( bShouldAccept ) { // Accept if( rCurrentEventType == EventType.DragPerform ) { DragAndDrop.AcceptDrag( ); rCurrentEvent.Use( ); DragAndDrop.activeControlID = 0; Uni2DTextureAtlas rGlobalAtlas = ( (Uni2DAnimationClip) target ).globalAtlas; List<Uni2DAnimationFrame> rAnimationFrames = ( (Uni2DAnimationClip) target ).frames; // Sort the dropped elements IOrderedEnumerable<Object> rSortedObjects = DragAndDrop.objectReferences.OrderBy( x => x.name ); // Add the textures foreach( Object rObject in rSortedObjects ) { if( rObject is Texture2D ) { Texture2D rTexture = (Texture2D) rObject; // TODO: refactor animation frame insert // Create a new frame Uni2DAnimationFrame oNewAnimationFrame = new Uni2DAnimationFrame( ); oNewAnimationFrame.atlas = rGlobalAtlas; // Keep texture reference if no atlas oNewAnimationFrame.textureContainer = new Texture2DContainer( rTexture, rGlobalAtlas == null ); // Add frame to clip rAnimationFrames.Add( oNewAnimationFrame ); } } EditorUtility.SetDirty( target ); } else if( rCurrentEventType == EventType.DragUpdated ) // Hint drop is possible { DragAndDrop.visualMode = DragAndDropVisualMode.Copy; } } else // Reject { DragAndDrop.visualMode = DragAndDropVisualMode.Rejected; } } } }
// Copy Constructor public Uni2DAnimationFrame(Uni2DAnimationFrame a_rFrameSource) { name = a_rFrameSource.name; atlas = a_rFrameSource.atlas; triggerEvent = a_rFrameSource.triggerEvent; a_rFrameSource.frameInfos.CopyTo( frameInfos ); textureContainer = new Texture2DContainer( a_rFrameSource.textureContainer.GUID, atlas == null ); }
public override void OnInspectorGUI( ) { // Update animation player used in clip header m_oAnimationPlayerClipHeader.Update(this.ComputeDeltaTime(ref m_lLastTimeTicks)); // Atlas bool bHasMultipleDifferentGlobalAtlasValues; Uni2DTextureAtlas rGlobalAtlas; this.GetGlobalAtlas(out rGlobalAtlas, out bHasMultipleDifferentGlobalAtlasValues); // Atlas size AtlasSize eMaximumAtlasSize = AtlasSize._2048; //SerializedSetting<EAtlasSize> oSerializedSetting_MaximumAtlasSize; // Selected object count int iTargetObjectCount = targets.Length; bool bDisplayFrames = (iTargetObjectCount == 1); EditorGUI.BeginDisabledGroup(Application.isPlaying); { EditorGUILayout.BeginVertical( ); { if (bDisplayFrames == false) { EditorGUILayout.HelpBox("Animation Clip edition is restricted when inspecting multiple clips, but you can change the atlas settings to pack the clips together.", MessageType.Info, true); } if (m_bAreClipsAndAtlasSynced == false) { EditorGUILayout.HelpBox("At least one animation frame is referencing an atlas which does not contain its texture.\nPlease regenerate the clip or manually add the frame texture to the atlas.", MessageType.Error, true); } ///// Atlas section ///// ms_bAtlasFoldout = EditorGUILayout.Foldout(ms_bAtlasFoldout, "Atlas"); if (ms_bAtlasFoldout) { bool bHasAtlasSettingsChanged; bool bHasAtlasChanged; ++EditorGUI.indentLevel; { EditorGUILayout.BeginVertical( ); { EditorGUILayout.BeginHorizontal( ); { EditorGUILayout.PrefixLabel("Use Atlas"); // Atlas popup EditorGUI.BeginChangeCheck( ); { EditorGUI.showMixedValue = bHasMultipleDifferentGlobalAtlasValues; { rGlobalAtlas = Uni2DEditorGUIUtils.AtlasPopup(rGlobalAtlas, m_oTextureGUIDs); } EditorGUI.showMixedValue = false; } bHasAtlasChanged = EditorGUI.EndChangeCheck( ); // Atlas select button EditorGUI.BeginDisabledGroup(rGlobalAtlas == null); { if (GUILayout.Button("Select", GUILayout.Width(80.0f))) { EditorGUIUtility.PingObject(rGlobalAtlas.gameObject); } } EditorGUI.EndDisabledGroup( ); } EditorGUILayout.EndHorizontal( ); // Atlas max size EditorGUI.BeginChangeCheck( ); { EditorGUI.BeginDisabledGroup((bHasAtlasChanged == false && bHasMultipleDifferentGlobalAtlasValues) || rGlobalAtlas == null); { eMaximumAtlasSize = (AtlasSize)EditorGUILayout.EnumPopup("Maximum Atlas Size", rGlobalAtlas != null ? rGlobalAtlas.maximumAtlasSize : eMaximumAtlasSize); } EditorGUI.EndDisabledGroup( ); } bHasAtlasSettingsChanged = EditorGUI.EndChangeCheck( ); } EditorGUILayout.EndVertical( ); } --EditorGUI.indentLevel; if (rGlobalAtlas != null && bHasAtlasSettingsChanged) { rGlobalAtlas.maximumAtlasSize = eMaximumAtlasSize; EditorUtility.SetDirty(rGlobalAtlas); } if (bHasAtlasChanged) { this.ApplyAnimationClipGlobalAtlas(rGlobalAtlas); } } EditorGUILayout.Space( ); ///// Animation Clip Header ///// for (int iClipIndex = 0, iClipCount = iTargetObjectCount; iClipIndex < iClipCount; ++iClipIndex) { Uni2DAnimationClip rAnimationClip = (Uni2DAnimationClip)this.targets[iClipIndex]; int iFrameCount = rAnimationClip.FrameCount; this.UpdateClipsFoldouts(iClipIndex, iFrameCount); bool bClipHeaderFoldout = this.GetClipFoldout(iClipIndex); EditorGUI.BeginDisabledGroup(bDisplayFrames == false); { EditorGUI.BeginChangeCheck( ); { bClipHeaderFoldout = Uni2DEditorGUIUtils.DisplayAnimationClipHeader(rAnimationClip, m_oAnimationPlayerClipHeader, bClipHeaderFoldout); } if (EditorGUI.EndChangeCheck( ) && bDisplayFrames) { // Update animation preview player settings m_oAnimationPlayerClipPreview.FrameRate = rAnimationClip.frameRate; m_oAnimationPlayerClipPreview.WrapMode = rAnimationClip.wrapMode; } } EditorGUI.EndDisabledGroup( ); this.SetClipFoldout(bClipHeaderFoldout, iClipIndex); ///// Clip frames section ///// if (bDisplayFrames && bClipHeaderFoldout) { EditorGUILayout.BeginHorizontal( ); { // Dummy space GUILayout.Space(32.0f); EditorGUILayout.BeginVertical( ); { // Display all frames for (int iFrameIndex = 0; iFrameIndex < iFrameCount; ++iFrameIndex) { // Display animation frame AnimationGUIAction eAction; // = AnimationGUIAction.None; bool bFrameFoldout = this.GetClipFoldout(iClipIndex, iFrameIndex); EditorGUI.BeginChangeCheck( ); { eAction = Uni2DEditorGUIUtils.DisplayAnimationFrame(rAnimationClip.frames[iFrameIndex], rGlobalAtlas, ref bFrameFoldout); } if (EditorGUI.EndChangeCheck( )) { EditorUtility.SetDirty(rAnimationClip); } this.SetClipFoldout(bFrameFoldout, iClipIndex, iFrameIndex); // Handle returned action (if any) switch (eAction) { // No action case AnimationGUIAction.None: default: break; case AnimationGUIAction.AddUp: { Uni2DAnimationFrame oNewFrame = new Uni2DAnimationFrame( ); oNewFrame.atlas = rGlobalAtlas; rAnimationClip.frames.Insert(iFrameIndex, oNewFrame); ++iFrameCount; ++iFrameIndex; this.UpdateClipsFoldouts(iClipIndex, iFrameCount); EditorUtility.SetDirty(rAnimationClip); } break; case AnimationGUIAction.AddDown: { Uni2DAnimationFrame oNewFrame = new Uni2DAnimationFrame( ); oNewFrame.atlas = rGlobalAtlas; rAnimationClip.frames.Insert(iFrameIndex + 1, oNewFrame); ++iFrameCount; this.UpdateClipsFoldouts(iClipIndex, iFrameCount); EditorUtility.SetDirty(rAnimationClip); } break; case AnimationGUIAction.MoveUp: { if (iFrameIndex != 0) { rAnimationClip.SwapFrames(iFrameIndex, iFrameIndex - 1); EditorUtility.SetDirty(rAnimationClip); } } break; case AnimationGUIAction.MoveDown: { if (iFrameIndex != iFrameCount - 1) { rAnimationClip.SwapFrames(iFrameIndex, iFrameIndex + 1); EditorUtility.SetDirty(rAnimationClip); } } break; case AnimationGUIAction.Close: { rAnimationClip.frames.RemoveAt(iFrameIndex); UpdateTextureGUIDsList( ); --iFrameCount; --iFrameIndex; EditorUtility.SetDirty(rAnimationClip); } break; } } EditorGUILayout.Space( ); } EditorGUILayout.EndVertical( ); } EditorGUILayout.EndHorizontal( ); EditorGUILayout.BeginHorizontal( ); { GUILayout.FlexibleSpace( ); if (GUILayout.Button("Add Frame", GUILayout.Width(225.0f))) { Uni2DAnimationFrame oNewFrame = new Uni2DAnimationFrame( ); oNewFrame.atlas = rGlobalAtlas; rAnimationClip.frames.Add(oNewFrame); EditorUtility.SetDirty(rAnimationClip); } GUILayout.FlexibleSpace( ); } EditorGUILayout.EndHorizontal( ); } // End of clip header foldout EditorGUILayout.Space( ); } ///// Apply / Revert / Force regeneration buttons ///// EditorGUILayout.BeginVertical( ); { EditorGUILayout.BeginHorizontal( ); { EditorGUI.BeginDisabledGroup(this.DoTargetsHaveUnappliedSettings( ) == false); { if (GUILayout.Button("Apply")) { this.ApplySettings(AnimationClipRegeneration.RegenerateAlsoAtlasIfNeeded); } if (GUILayout.Button("Revert")) { this.RevertSettings( ); } } EditorGUI.EndDisabledGroup( ); } EditorGUILayout.EndHorizontal( ); if (GUILayout.Button("Force Clip Regeneration")) { this.ApplySettings(AnimationClipRegeneration.RegenerateAll); } } EditorGUILayout.EndVertical( ); } EditorGUILayout.EndVertical( ); } EditorGUI.EndDisabledGroup( ); if (Application.isPlaying == false) { this.CheckTextureDragAndDrop(GUILayoutUtility.GetLastRect( )); } // Force repaint if needed (== animation players enabled) if (m_oAnimationPlayerClipHeader.Enabled || m_oAnimationPlayerClipPreview.Enabled) { this.Repaint( ); } }
// Set the frame draw by the sprite public void SetFrame(Uni2DAnimationFrame a_rFrame) { SetSpriteFrame(a_rFrame.textureContainer, a_rFrame.atlas, a_rFrame.TextureWidth, a_rFrame.TextureHeight); }
////////// Animation clip utils ////////// // Handles texture drop over inspector private void CheckTextureDragAndDrop(Rect a_rDropAreaRect) { // Handle drag only if not multi selecting if (targets.Length == 1) { // Current Event Event rCurrentEvent = Event.current; EventType rCurrentEventType = rCurrentEvent.type; Vector2 f2MousePos = rCurrentEvent.mousePosition; // Dragging over clip inspector area if (a_rDropAreaRect.Contains(f2MousePos)) { bool bShouldAccept = false; // Does contain at least one texture2D? foreach (Object rObject in DragAndDrop.objectReferences) { if (rObject is Texture2D) { bShouldAccept = true; break; } } if (bShouldAccept) { // Accept if (rCurrentEventType == EventType.DragPerform) { DragAndDrop.AcceptDrag( ); rCurrentEvent.Use( ); DragAndDrop.activeControlID = 0; Uni2DTextureAtlas rGlobalAtlas = ((Uni2DAnimationClip)target).globalAtlas; List <Uni2DAnimationFrame> rAnimationFrames = ((Uni2DAnimationClip)target).frames; // Sort the dropped elements IOrderedEnumerable <Object> rSortedObjects = DragAndDrop.objectReferences.OrderBy(x => x.name); // Add the textures foreach (Object rObject in rSortedObjects) { if (rObject is Texture2D) { Texture2D rTexture = (Texture2D)rObject; // TODO: refactor animation frame insert // Create a new frame Uni2DAnimationFrame oNewAnimationFrame = new Uni2DAnimationFrame( ); oNewAnimationFrame.atlas = rGlobalAtlas; // Keep texture reference if no atlas oNewAnimationFrame.textureContainer = new Texture2DContainer(rTexture, rGlobalAtlas == null); // Add frame to clip rAnimationFrames.Add(oNewAnimationFrame); } } EditorUtility.SetDirty(target); } else if (rCurrentEventType == EventType.DragUpdated) // Hint drop is possible { DragAndDrop.visualMode = DragAndDropVisualMode.Copy; } } else // Reject { DragAndDrop.visualMode = DragAndDropVisualMode.Rejected; } } } }
// On new frame private void OnNewFrame() { if( m_rCurrentClip != null) { int iFrameCount = m_rCurrentClip.FrameCount; int iFrame; if(iFrameCount > 0) { if(iFrameCount == 1) { iFrame = 0; } else { iFrame = (int)Mathf.PingPong(m_iCurrentFrameIndex, iFrameCount - 1); } m_rCurrentFrame = m_rCurrentClip.frames[iFrame]; //m_rSprite.SetFrame(m_rCurrentFrame); RaiseAnimationNewFrameEvent(); RaiseAnimationFrameEvent(); } else { m_rCurrentFrame = null; } } }
// Set the frame draw by the sprite public void SetFrame(Uni2DAnimationFrame a_rFrame) { SetSpriteFrame(a_rFrame.textureContainer, a_rFrame.atlas, a_rFrame.TextureWidth, a_rFrame.TextureHeight); }
public override void OnInspectorGUI( ) { // Update animation player used in clip header m_oAnimationPlayerClipHeader.Update( this.ComputeDeltaTime( ref m_lLastTimeTicks ) ); // Atlas bool bHasMultipleDifferentGlobalAtlasValues; Uni2DTextureAtlas rGlobalAtlas; this.GetGlobalAtlas( out rGlobalAtlas, out bHasMultipleDifferentGlobalAtlasValues ); // Atlas size AtlasSize eMaximumAtlasSize = AtlasSize._2048; //SerializedSetting<EAtlasSize> oSerializedSetting_MaximumAtlasSize; // Selected object count int iTargetObjectCount = targets.Length; bool bDisplayFrames = ( iTargetObjectCount == 1 ); EditorGUI.BeginDisabledGroup( Application.isPlaying ); { EditorGUILayout.BeginVertical( ); { if( bDisplayFrames == false ) { EditorGUILayout.HelpBox( "Animation Clip edition is restricted when inspecting multiple clips, but you can change the atlas settings to pack the clips together.", MessageType.Info, true ); } if( m_bAreClipsAndAtlasSynced == false ) { EditorGUILayout.HelpBox( "At least one animation frame is referencing an atlas which does not contain its texture.\nPlease regenerate the clip or manually add the frame texture to the atlas.", MessageType.Error, true ); } ///// Atlas section ///// ms_bAtlasFoldout = EditorGUILayout.Foldout( ms_bAtlasFoldout, "Atlas" ); if( ms_bAtlasFoldout ) { bool bHasAtlasSettingsChanged; bool bHasAtlasChanged; ++EditorGUI.indentLevel; { EditorGUILayout.BeginVertical( ); { EditorGUILayout.BeginHorizontal( ); { EditorGUILayout.PrefixLabel( "Use Atlas" ); // Atlas popup EditorGUI.BeginChangeCheck( ); { EditorGUI.showMixedValue = bHasMultipleDifferentGlobalAtlasValues; { rGlobalAtlas = Uni2DEditorGUIUtils.AtlasPopup( rGlobalAtlas, m_oTextureGUIDs ); } EditorGUI.showMixedValue = false; } bHasAtlasChanged = EditorGUI.EndChangeCheck( ); // Atlas select button EditorGUI.BeginDisabledGroup( rGlobalAtlas == null ); { if( GUILayout.Button( "Select", GUILayout.Width( 80.0f ) ) ) { EditorGUIUtility.PingObject( rGlobalAtlas.gameObject ); } } EditorGUI.EndDisabledGroup( ); } EditorGUILayout.EndHorizontal( ); // Atlas max size EditorGUI.BeginChangeCheck( ); { EditorGUI.BeginDisabledGroup( ( bHasAtlasChanged == false && bHasMultipleDifferentGlobalAtlasValues ) || rGlobalAtlas == null ); { eMaximumAtlasSize = (AtlasSize) EditorGUILayout.EnumPopup( "Maximum Atlas Size", rGlobalAtlas != null ? rGlobalAtlas.maximumAtlasSize : eMaximumAtlasSize ); } EditorGUI.EndDisabledGroup( ); } bHasAtlasSettingsChanged = EditorGUI.EndChangeCheck( ); } EditorGUILayout.EndVertical( ); } --EditorGUI.indentLevel; if( rGlobalAtlas != null && bHasAtlasSettingsChanged ) { rGlobalAtlas.maximumAtlasSize = eMaximumAtlasSize; EditorUtility.SetDirty( rGlobalAtlas ); } if( bHasAtlasChanged ) { this.ApplyAnimationClipGlobalAtlas( rGlobalAtlas ); } } EditorGUILayout.Space( ); ///// Animation Clip Header ///// for( int iClipIndex = 0, iClipCount = iTargetObjectCount; iClipIndex < iClipCount; ++iClipIndex ) { Uni2DAnimationClip rAnimationClip = (Uni2DAnimationClip) this.targets[ iClipIndex ]; int iFrameCount = rAnimationClip.FrameCount; this.UpdateClipsFoldouts( iClipIndex, iFrameCount ); bool bClipHeaderFoldout = this.GetClipFoldout( iClipIndex ); EditorGUI.BeginDisabledGroup( bDisplayFrames == false ); { EditorGUI.BeginChangeCheck( ); { bClipHeaderFoldout = Uni2DEditorGUIUtils.DisplayAnimationClipHeader( rAnimationClip, m_oAnimationPlayerClipHeader, bClipHeaderFoldout ); } if( EditorGUI.EndChangeCheck( ) && bDisplayFrames ) { // Update animation preview player settings m_oAnimationPlayerClipPreview.FrameRate = rAnimationClip.frameRate; m_oAnimationPlayerClipPreview.WrapMode = rAnimationClip.wrapMode; } } EditorGUI.EndDisabledGroup( ); this.SetClipFoldout( bClipHeaderFoldout, iClipIndex ); ///// Clip frames section ///// if( bDisplayFrames && bClipHeaderFoldout ) { EditorGUILayout.BeginHorizontal( ); { // Dummy space GUILayout.Space( 32.0f ); EditorGUILayout.BeginVertical( ); { // Display all frames for( int iFrameIndex = 0; iFrameIndex < iFrameCount; ++iFrameIndex ) { // Display animation frame AnimationGUIAction eAction; // = AnimationGUIAction.None; bool bFrameFoldout = this.GetClipFoldout( iClipIndex, iFrameIndex ); EditorGUI.BeginChangeCheck( ); { eAction = Uni2DEditorGUIUtils.DisplayAnimationFrame( rAnimationClip.frames[ iFrameIndex ], rGlobalAtlas, ref bFrameFoldout ); } if( EditorGUI.EndChangeCheck( ) ) { EditorUtility.SetDirty( rAnimationClip ); } this.SetClipFoldout( bFrameFoldout, iClipIndex, iFrameIndex ); // Handle returned action (if any) switch( eAction ) { // No action case AnimationGUIAction.None: default: break; case AnimationGUIAction.AddUp: { Uni2DAnimationFrame oNewFrame = new Uni2DAnimationFrame( ); oNewFrame.atlas = rGlobalAtlas; rAnimationClip.frames.Insert( iFrameIndex, oNewFrame ); ++iFrameCount; ++iFrameIndex; this.UpdateClipsFoldouts( iClipIndex, iFrameCount ); EditorUtility.SetDirty( rAnimationClip ); } break; case AnimationGUIAction.AddDown: { Uni2DAnimationFrame oNewFrame = new Uni2DAnimationFrame( ); oNewFrame.atlas = rGlobalAtlas; rAnimationClip.frames.Insert( iFrameIndex + 1, oNewFrame ); ++iFrameCount; this.UpdateClipsFoldouts( iClipIndex, iFrameCount ); EditorUtility.SetDirty( rAnimationClip ); } break; case AnimationGUIAction.MoveUp: { if( iFrameIndex != 0 ) { rAnimationClip.SwapFrames( iFrameIndex, iFrameIndex - 1 ); EditorUtility.SetDirty( rAnimationClip ); } } break; case AnimationGUIAction.MoveDown: { if( iFrameIndex != iFrameCount - 1 ) { rAnimationClip.SwapFrames( iFrameIndex, iFrameIndex + 1 ); EditorUtility.SetDirty( rAnimationClip ); } } break; case AnimationGUIAction.Close: { rAnimationClip.frames.RemoveAt( iFrameIndex ); UpdateTextureGUIDsList( ); --iFrameCount; --iFrameIndex; EditorUtility.SetDirty( rAnimationClip ); } break; } } EditorGUILayout.Space( ); } EditorGUILayout.EndVertical( ); } EditorGUILayout.EndHorizontal( ); EditorGUILayout.BeginHorizontal( ); { GUILayout.FlexibleSpace( ); if( GUILayout.Button( "Add Frame", GUILayout.Width( 225.0f ) ) ) { Uni2DAnimationFrame oNewFrame = new Uni2DAnimationFrame( ); oNewFrame.atlas = rGlobalAtlas; rAnimationClip.frames.Add( oNewFrame ); EditorUtility.SetDirty( rAnimationClip ); } GUILayout.FlexibleSpace( ); } EditorGUILayout.EndHorizontal( ); } // End of clip header foldout EditorGUILayout.Space( ); } ///// Apply / Revert / Force regeneration buttons ///// EditorGUILayout.BeginVertical( ); { EditorGUILayout.BeginHorizontal( ); { EditorGUI.BeginDisabledGroup( this.DoTargetsHaveUnappliedSettings( ) == false ); { if( GUILayout.Button( "Apply" ) ) { this.ApplySettings( AnimationClipRegeneration.RegenerateAlsoAtlasIfNeeded ); } if( GUILayout.Button( "Revert" ) ) { this.RevertSettings( ); } } EditorGUI.EndDisabledGroup( ); } EditorGUILayout.EndHorizontal( ); if( GUILayout.Button( "Force Clip Regeneration" ) ) { this.ApplySettings( AnimationClipRegeneration.RegenerateAll ); } } EditorGUILayout.EndVertical( ); } EditorGUILayout.EndVertical( ); } EditorGUI.EndDisabledGroup( ); if( Application.isPlaying == false ) { this.CheckTextureDragAndDrop( GUILayoutUtility.GetLastRect( ) ); } // Force repaint if needed (== animation players enabled) if( m_oAnimationPlayerClipHeader.Enabled || m_oAnimationPlayerClipPreview.Enabled ) { this.Repaint( ); } }
// Displays the animation frame GUI // Returns the performed user action public static AnimationGUIAction DisplayAnimationFrame(Uni2DAnimationFrame a_rAnimationFrame, Uni2DTextureAtlas a_rGlobalAtlas, ref bool a_bEventFoldout) { AnimationGUIAction eAction = AnimationGUIAction.None; // Box EditorGUILayout.BeginVertical(EditorStyles.textField); { ///// Top toolbar ///// EditorGUILayout.BeginHorizontal(EditorStyles.toolbar, GUILayout.ExpandWidth(true)); { // ^ if (GUILayout.Button("\u25B2" /*"\u2191"*/, EditorStyles.toolbarButton, GUILayout.ExpandWidth(false))) { eAction = AnimationGUIAction.MoveUp; } // v if (GUILayout.Button("\u25BC" /*"\u2193"*/, EditorStyles.toolbarButton, GUILayout.ExpandWidth(false))) { eAction = AnimationGUIAction.MoveDown; } // + ^ if (GUILayout.Button("+ \u25B2" /*"+ \u2191"*/, EditorStyles.toolbarButton, GUILayout.ExpandWidth(true))) { eAction = AnimationGUIAction.AddUp; } // X if (GUILayout.Button("X", EditorStyles.toolbarButton, GUILayout.ExpandWidth(false))) { eAction = AnimationGUIAction.Close; } } EditorGUILayout.EndHorizontal( ); /////////////// EditorGUILayout.Space( ); ///// Animation Frame box ///// EditorGUILayout.BeginHorizontal( ); { Texture2D rFrameTexture = a_rAnimationFrame.textureContainer; string rFrameTextureGUID = a_rAnimationFrame.textureContainer.GUID; bool bHasFrameTextureChanged; // Display frame texture on the left Rect oClipTextureRect = GUILayoutUtility.GetRect(64.0f, 64.0f, 64.0f, 64.0f, GUILayout.ExpandWidth(false)); EditorGUI.BeginChangeCheck( ); { rFrameTexture = (Texture2D)EditorGUI.ObjectField(oClipTextureRect, GUIContent.none, rFrameTexture, typeof(Texture2D), false); } bHasFrameTextureChanged = EditorGUI.EndChangeCheck( ); EditorGUILayout.BeginVertical(GUILayout.ExpandWidth(true)); { // Frame texture name GUILayout.Label(rFrameTexture != null ? rFrameTexture.name : "(No Texture)", EditorStyles.boldLabel, GUILayout.ExpandWidth(false)); // Frame Name a_rAnimationFrame.name = EditorGUILayout.TextField("Frame Name", a_rAnimationFrame.name); // Frame atlas EditorGUILayout.BeginHorizontal( ); { // Disable popup menu if global atlas is set EditorGUI.BeginDisabledGroup(a_rGlobalAtlas != null); { // Atlas popup string[] oTextureGUID = (rFrameTexture != null) ? new string[1] { rFrameTextureGUID } : new string[0]; EditorGUILayout.PrefixLabel("Use Atlas"); a_rAnimationFrame.atlas = Uni2DEditorGUIUtils.AtlasPopup(a_rAnimationFrame.atlas, oTextureGUID); } EditorGUI.EndDisabledGroup( ); // Atlas select button EditorGUI.BeginDisabledGroup(a_rAnimationFrame.atlas == null); { if (GUILayout.Button("Select", GUILayout.Width(80.0f))) { EditorGUIUtility.PingObject(a_rAnimationFrame.atlas.gameObject); } } EditorGUI.EndDisabledGroup( ); } EditorGUILayout.EndHorizontal( ); // Trigger? a_rAnimationFrame.triggerEvent = EditorGUILayout.Toggle("Trigger Event", a_rAnimationFrame.triggerEvent); // Event param a_bEventFoldout = EditorGUILayout.Foldout(a_bEventFoldout, "Frame Infos"); if (a_bEventFoldout) { Uni2DAnimationFrameInfos rFrameInfos = a_rAnimationFrame.frameInfos; ++EditorGUI.indentLevel; { rFrameInfos.stringInfo = EditorGUILayout.TextField("String Info", rFrameInfos.stringInfo); rFrameInfos.intInfo = EditorGUILayout.IntField("Int Info", rFrameInfos.intInfo); rFrameInfos.floatInfo = EditorGUILayout.FloatField("Float Info", rFrameInfos.floatInfo); rFrameInfos.objectInfo = EditorGUILayout.ObjectField("Object Info", rFrameInfos.objectInfo, typeof(Object), true); } --EditorGUI.indentLevel; } EditorGUILayout.Space( ); } EditorGUILayout.EndVertical( ); if (bHasFrameTextureChanged) { // Save texture in texture container, keep reference to the asset if not using an atlas a_rAnimationFrame.textureContainer = new Texture2DContainer(rFrameTexture, a_rGlobalAtlas == null); } } EditorGUILayout.EndHorizontal( ); /////////////// EditorGUILayout.Space( ); ///// Bottom toolbar ///// EditorGUILayout.BeginHorizontal(EditorStyles.toolbar, GUILayout.ExpandWidth(true)); { // + v if (GUILayout.Button("+ \u25BC" /*"+ \u2193"*/, EditorStyles.toolbarButton, GUILayout.ExpandWidth(true))) { eAction = AnimationGUIAction.AddDown; } } EditorGUILayout.EndHorizontal( ); } EditorGUILayout.EndVertical( ); return(eAction); }