public void PlayFrame(X2DAnimationClip anima, int frameIndex) { //Debug.Log(index + ", " + timer); X2DAnimationFrame frame = anima.frameList[frameIndex]; string shaderName = anima.renderShaderName; if (myMaterial.shader == null) { myMaterial.shader = Shader.Find(shaderName); } else if (myMaterial.shader.name != shaderName) { myMaterial.shader = Shader.Find(shaderName); } myMaterial.mainTexture = frame.tex; myRenderer.transform.localScale = new Vector3(frame.size.x, frame.size.y, 1); Vector3 pos = anima.transform.localPosition; pos.x += frame.pos.x; //pos是相对于frameRegion左上角的偏移量 pos.y += frame.pos.y; //pos是相对于frameRegion左上角的偏移量(y轴竖直向下) if (!isFaceRight) { pos.x = -pos.x; //关于y轴对称 } myRenderer.transform.localPosition = pos; curFrameTopLeft.x = pos.x - frame.size.x * 0.5f; curFrameTopLeft.y = pos.y - frame.size.y * 0.5f; curFrameBottomRight = curFrameTopLeft - frame.size; }
void PreviewAllUpdate() { X2DAnimationClip[] clipArray = anima.clipArray; if (clipArray.Length == 0) { return; } timer += Time.deltaTime; X2DAnimationClip clip = clipArray[curClipIndex]; if (timer >= clip.frameList[curFrame].duration) { curFrame++; if (curFrame >= clip.frameList.Count) { curFrame = 0; curClipIndex++; if (curClipIndex >= clipArray.Length) { curClipIndex = 0; } } timer = 0; anima.PlayFrame(clipArray[curClipIndex], curFrame); } }
public void StopPreview() { anima.EditorStopPreview(this); anima = null; previewClip = null; isPreviewingOne = false; isPreviewingAll = false; }
public void PlayClip(X2DAnimationClip clip, float acc = 1) { isPlaying = true; curClip = clip; playMode = curClip.playMode; curFrame = isForward ? 0 : curClip.frameList.Count - 1; PlayFrame(curClip, curFrame); timer = isForward ? 0f : curClip.duration; accelerate = acc; }
public void PreviewOne(X2DAnimationClip clip) { if (anima == null) { anima = GetComponent <X2DAnimation>(); } previewClip = clip; isPreviewingAll = false; isPreviewingOne = true; anima.EditorStartPreview(this, clip, false, null); }
//待优化:使用目录名作为信息文件名 //待优化:数值读取方式 //待完善:异常处理 public static void LoadTextureInfo(X2DAnimationClip clip) { const string fileName = "info.txt"; string texturePath = AssetDatabase.GetAssetPath(clip.frameList[0].tex); string textureDir = Application.dataPath.Replace("/Assets", "") + "/" + Path.GetDirectoryName(texturePath) + "/"; Debug.Log(textureDir + fileName); //FileInfo fi = new FileInfo(fileName + fileName); StreamReader sr = new StreamReader(textureDir + fileName); if (sr == null) { return; } List <FrameTextureInfo> infoList = new List <FrameTextureInfo>(); while (!sr.EndOfStream) { string line = sr.ReadLine(); FrameTextureInfo fti = new FrameTextureInfo(); ReadInt(line, "[", out fti.i); ReadInt(line, " x=", out fti.x); ReadInt(line, " y=", out fti.y); ReadInt(line, " width=", out fti.width); ReadInt(line, " height=", out fti.height); ReadInt(line, " max_width=", out fti.frameWidth); ReadInt(line, " max_height=", out fti.frameHeight); infoList.Add(fti); } sr.Close(); for (int i = 0; i < clip.frameList.Count; i++) { X2DAnimationFrame frame = clip.frameList[i]; for (int j = 0; j < infoList.Count; j++) { FrameTextureInfo fti = infoList[j]; if (GetIntInString(frame.tex.name) == fti.i) { frame.pos.x = (fti.width - fti.frameWidth) * 0.5f + fti.x; //pos是相对于frameRegion左上角的偏移量 frame.pos.y = (fti.frameHeight - fti.height) * 0.5f - fti.y; //pos是相对于frameRegion左上角的偏移量(y轴竖直向下) frame.size.x = fti.width; frame.size.y = fti.height; frame.region.x = fti.frameWidth; frame.region.y = fti.frameHeight; break; } } } }
//继续刷新帧,回复当前播放状态 public void EditorStopPreview(X2DAnimationPreviewer previewer) { curClip = previewer.playingClip; playMode = previewer.playMode; curFrame = previewer.curFrame; timer = previewer.timer; isForward = previewer.isForward; actorContainer = previewer.actorContainer; normalContainer = previewer.normalContainer; isPreviewing = false; isPlaying = true; previewClipPlayEndCallbabck = null; }
//做下标记,不再刷新帧,保存当前播放状态 public void EditorStartPreview(X2DAnimationPreviewer previewer, X2DAnimationClip clip, bool previewAll, VoidDelegate callback) { previewer.playingClip = curClip; previewer.playMode = playMode; previewer.curFrame = curFrame; previewer.timer = timer; previewer.isForward = isForward; previewer.actorContainer = null; previewer.normalContainer = normalContainer; previewClipPlayEndCallbabck = callback; normalContainer = transform; isPreviewing = true; PlayClip(clip, 1); }
//编辑器中刷新clip数组 public void UpdateClipArrayInEditor(X2DAnimation anima) { X2DAnimationClip[] clipArray = anima.GetComponentsInChildren <X2DAnimationClip>(true); anima.clipArray = clipArray; //剪辑名字排列 for (int i = 0; i < clipArray.Length - 1; i++) { for (int j = 0; j < clipArray.Length - 1 - i; j++) { if (clipArray[j].clipName.CompareTo(clipArray[j + 1].clipName) > 0) { X2DAnimationClip t = clipArray[j]; clipArray[j] = clipArray[j + 1]; clipArray[j + 1] = t; } } } }
///clipName剪辑名称,如果是null或"",则播放默认剪辑 ///acc加速值,大于1表示加速,等于1表示不加速,小于1表示减速 public void Play(string clipName, float acc = 1) { myRenderer.gameObject.SetActive(true); if (string.IsNullOrEmpty(clipName)) { PlayClip(defaultClip, acc); return; } isPlaying = false; for (int i = 0; i < clipArray.Length; i++) { X2DAnimationClip clip = clipArray[i]; if (clip.clipName == clipName) { PlayClip(clip, acc); return; } } Debug.LogErrorFormat("clip is not found: {0}/{1}", name, clipName); }
void OnGUI() { X2DAnimationClip clip = null; if (Selection.activeGameObject != null) { clip = Selection.activeGameObject.GetComponent <X2DAnimationClip>(); } if (clip != null) { curSelectedClip = clip; } else { clip = curSelectedClip; //如果当前没选中动画剪辑,则继续显示当前的动画剪辑 } if (clip == null) { return; } GUI.color = new Color(255 / 255f, 204 / 255f, 255 / 255f); GUILayout.Label("[" + clip.name + "]"); GUI.color = Color.white; if (clip.frameList == null) { GUI.color = Color.red; GUILayout.Label("剪辑列未创建"); GUI.color = Color.white; return; } //分左右两组 GUILayout.BeginHorizontal(); //第一组 GUILayout.BeginVertical(GUILayout.Width(300)); //OneKeyFrameTime GUILayout.BeginHorizontal(); if (GUILayout.Button("OneKeyFrameTime", GUILayout.Width(132))) { for (int i = 0; i < clip.frameList.Count; i++) { clip.frameList[i].duration = oneKeyFrameTime; } } oneKeyFrameTime = EditorGUILayout.FloatField(oneKeyFrameTime, GUILayout.Width(150)); GUILayout.EndHorizontal(); //OneKeyFrameSize GUILayout.BeginHorizontal(); if (GUILayout.Button("OneKeyFrameSize", GUILayout.Width(132))) { for (int i = 0; i < clip.frameList.Count; i++) { clip.frameList[i].size = oneKeyFrameSize; } } oneKeyFrameSize = TqmGUILayoutUtility.SimpleVector2(oneKeyFrameSize, 60); GUILayout.EndHorizontal(); //OneKeyFrameRegion GUILayout.BeginHorizontal(); if (GUILayout.Button("OneKeyFrameRegion", GUILayout.Width(132))) { for (int i = 0; i < clip.frameList.Count; i++) { clip.frameList[i].region = oneKeyFrameRegion; } } oneKeyFrameRegion = TqmGUILayoutUtility.SimpleVector2(oneKeyFrameRegion, 60); GUILayout.EndHorizontal(); GUILayout.EndVertical(); //第二组 GUILayout.BeginVertical(); //clip name GUILayout.BeginHorizontal(); GUILayout.Label("ClipName", GUILayout.Width(100)); clip.clipName = GUILayout.TextField(clip.clipName, GUILayout.Width(100)); GUILayout.EndHorizontal(); //duration clip.duration = 0; for (int i = 0; i < clip.frameList.Count; i++) { clip.duration += clip.frameList[i].duration; } GUILayout.BeginHorizontal(); GUILayout.Label("Duration", GUILayout.Width(100)); clip.duration = EditorGUILayout.FloatField(clip.duration, GUILayout.Width(100)); GUILayout.EndHorizontal(); //play mode GUILayout.BeginHorizontal(); GUILayout.Label("PlayMode", GUILayout.Width(100)); clip.playMode = (EmX2DAnimationPlayMode)EditorGUILayout.EnumPopup(clip.playMode, GUILayout.Width(100)); GUILayout.EndHorizontal(); GUILayout.EndVertical(); GUILayout.EndHorizontal(); //pos correct GUILayout.BeginHorizontal(); if (clip.posCorrecting) { GUI.color = Color.red; if (GUILayout.Button("StopCorrecting", GUILayout.Width(100))) { GameObject animaGO = clip.transform.parent.gameObject; X2DAnimation anima = animaGO.GetComponent <X2DAnimation>(); if (anima != null) { anima.EditorShowRenderer(); } clip.posCorrecting = false; } GUI.color = Color.white; } else { if (GUILayout.Button("StartCorrecting", GUILayout.Width(100))) { GameObject animaGO = clip.transform.parent.gameObject; X2DAnimation anima = animaGO.GetComponent <X2DAnimation>(); if (anima != null) { anima.EditorHideRenderer(); } clip.posCorrecting = true; } } clip.Update_PosCorrecting(); //fill with seleced textures if (GUILayout.Button("fill with selected textures", GUILayout.Width(160))) { if (Selection.objects.Length == 0) { Debug.LogError("no object selected"); } else { Object[] array = Selection.objects; SortByName(array); for (int i = 0; i < array.Length && i < clip.frameList.Count; i++) { clip.frameList[i].tex = array[i] as Texture2D; } } } //load frame info if (GUILayout.Button("load frame info", GUILayout.Width(100))) { LoadTextureInfo(clip); } //load org tex size useTexutreSize = GUILayout.Button("load org tex size", GUILayout.Width(120)); GUILayout.EndHorizontal(); //list length GUILayout.BeginHorizontal(); GUILayout.Label("FrameList", GUILayout.Width(100)); GUILayout.Label(clip.frameList.Count.ToString(), GUILayout.Width(10)); frameListSize = EditorGUILayout.IntField(frameListSize, GUILayout.Width(86)); bool resize = GUILayout.Button("Resize", GUILayout.Width(50)); GUILayout.EndHorizontal(); if (resize) { if (frameListSize > clip.frameList.Count) { for (int i = clip.frameList.Count; i < frameListSize; i++) { X2DAnimationFrame f = new X2DAnimationFrame(); clip.frameList.Add(f); } } else if (frameListSize < clip.frameList.Count) { for (int i = clip.frameList.Count; i > frameListSize; i--) { clip.frameList.RemoveAt(clip.frameList.Count - 1); } } } //list成员 int insertAt = -1; int removeAt = -1; mScroll = GUILayout.BeginScrollView(mScroll); float frameStartTime = 0f; for (int i = 0; i < clip.frameList.Count; i++) { X2DAnimationFrame frame = clip.frameList[i]; GUILayout.BeginHorizontal(); GUILayout.Space(20); //order GUILayout.Label(i.ToString(), GUILayout.Width(10)); //Duration TqmGUILayoutUtility.ColorLable(Color.blue, "duration", GUILayout.Width(60)); clip.frameList[i].duration = EditorGUILayout.FloatField(frame.duration, GUILayout.Width(40)); //startTime frame.startTime = frameStartTime; frameStartTime += frame.duration; GUILayout.Label(frame.startTime.ToString("f2"), GUILayout.Width(30)); //size TqmGUILayoutUtility.ColorLable(Color.blue, " size", GUILayout.Width(30)); frame.size.x = EditorGUILayout.FloatField(frame.size.x, GUILayout.Width(40)); frame.size.y = EditorGUILayout.FloatField(frame.size.y, GUILayout.Width(40)); if (useTexutreSize) { frame.size = new Vector2(frame.tex.width, frame.tex.height); } //pos TqmGUILayoutUtility.ColorLable(Color.blue, " pos", GUILayout.Width(28)); frame.pos.x = EditorGUILayout.FloatField(frame.pos.x, GUILayout.Width(40)); frame.pos.y = EditorGUILayout.FloatField(frame.pos.y, GUILayout.Width(40)); //frameRegion TqmGUILayoutUtility.ColorLable(Color.blue, " region", GUILayout.Width(44)); frame.region.x = EditorGUILayout.FloatField(frame.region.x, GUILayout.Width(40)); frame.region.y = EditorGUILayout.FloatField(frame.region.y, GUILayout.Width(40)); //texture TqmGUILayoutUtility.ColorLable(Color.blue, " tex", GUILayout.Width(26)); frame.tex = EditorGUILayout.ObjectField(frame.tex, typeof(Object), true) as Texture2D; //insert remove if (GUILayout.Button("-")) { removeAt = i; } if (GUILayout.Button("+")) { insertAt = i; } GUILayout.EndHorizontal(); } if (GUILayout.Button("+")) { insertAt = clip.frameList.Count; } //进行插入删除 if (removeAt > -1) { clip.frameList.RemoveAt(removeAt); } if (insertAt > -1) { clip.frameList.Insert(insertAt, new X2DAnimationFrame()); } GUILayout.EndScrollView(); useTexutreSize = false; }
//private int frameListSize = 0; //private bool useTexutreSize = false; public override void OnInspectorGUI() { X2DAnimationClip clip = target as X2DAnimationClip; //使用的shader,需要手动刷新下GameView(比如deactive,enactive),gameview就会update从而显示新的shader GUILayout.BeginHorizontal(); GUILayout.Label("Shader", GUILayout.Width(100)); Object shaderObj = EditorGUILayout.ObjectField(Shader.Find(clip.renderShaderName), typeof(Shader), true); Shader shader = shaderObj as Shader; if (shader != null) { clip.renderShaderName = shader.name; } GUILayout.EndHorizontal(); //默认视图 base.OnInspectorGUI(); //将gameobject的名字锁定为和剪辑名一样 if (clip.name != clip.clipName) { clip.name = clip.clipName; } //增加预览按钮 GUI.enabled = Application.isPlaying; if (GUILayout.Button("StartPreview", GUILayout.Width(100))) { GameObject animaGO = clip.transform.parent.gameObject; X2DAnimationPreviewer previewer = animaGO.GetComponent <X2DAnimationPreviewer>(); if (previewer == null) { previewer = animaGO.AddComponent <X2DAnimationPreviewer>(); } previewer.PreviewOne(clip); } if (GUILayout.Button("StopPreview", GUILayout.Width(100))) { GameObject animaGO = clip.transform.parent.gameObject; X2DAnimationPreviewer previewer = animaGO.GetComponent <X2DAnimationPreviewer>(); if (previewer != null) { previewer.StopPreview(); } } GUI.enabled = true; return; /* * X2DAnimationClip clip = target as X2DAnimationClip; * if(clip == null) return; * * //default time * GUILayout.BeginHorizontal(); * GUILayout.Label("DefaultTime", GUILayout.Width(100)); * clip.defaultTime= EditorGUILayout.FloatField(clip.defaultTime, GUILayout.Width(150)); * if(GUILayout.Button("SetAll", GUILayout.Width(48))) * { * for(int i=0; i<clip.frameList.Count; i++) * clip.frameList[i].time = clip.defaultTime; * } * GUILayout.EndHorizontal(); * * //default size * GUILayout.BeginHorizontal(); * GUILayout.Label("DefaultSize", GUILayout.Width(100)); * clip.defaultSize= EditorGUILayout.Vector2Field("", clip.defaultSize, GUILayout.Width(150)); * if(GUILayout.Button("SetAll", GUILayout.Width(48))) * { * for(int i=0; i<clip.frameList.Count; i++) * clip.frameList[i].size = clip.defaultSize; * } * GUILayout.EndHorizontal(); * * //clip name * GUILayout.BeginHorizontal(); * GUILayout.Label("ClipName", GUILayout.Width(100)); * clip.clipName = GUILayout.TextField(clip.clipName, GUILayout.Width(100)); * GUILayout.EndHorizontal(); * * //duration * clip.duration = 0; * for(int i=0; i<clip.frameList.Count; i++) * clip.duration += clip.frameList[i].time; * GUILayout.BeginHorizontal(); * GUILayout.Label("Duration", GUILayout.Width(100)); * clip.duration = EditorGUILayout.FloatField(clip.duration, GUILayout.Width(100)); * GUILayout.EndHorizontal(); * * //play mode * GUILayout.BeginHorizontal(); * GUILayout.Label("PlayMode",GUILayout.Width(100)); * clip.playMode = (EmX2DAnimationPlayMode)EditorGUILayout.EnumPopup(clip.playMode, GUILayout.Width(100)); * GUILayout.EndHorizontal(); * * //list length * GUILayout.BeginHorizontal(); * GUILayout.Label("FrameList", GUILayout.Width(100)); * GUILayout.Label(clip.frameList.Count.ToString(), GUILayout.Width(10)); * frameListSize = EditorGUILayout.IntField(frameListSize, GUILayout.Width(86)); * bool resize = GUILayout.Button("Resize", GUILayout.Width(50)); * GUILayout.EndHorizontal(); * if(resize) * { * if(frameListSize > clip.frameList.Count) * { * for(int i=clip.frameList.Count; i<frameListSize; i++){ * X2DAnimationFrame f = new X2DAnimationFrame(); * clip.frameList.Add(f); * } * } * else if(frameListSize < clip.frameList.Count) * { * for(int i=clip.frameList.Count; i>frameListSize; i--) * clip.frameList.RemoveAt(clip.frameList.Count-1); * } * } * * //list成员 * for(int i=0; i<clip.frameList.Count; i++) * { * X2DAnimationFrame frame = clip.frameList[i]; * GUILayout.BeginHorizontal(); * GUILayout.Space(20); * //order * GUILayout.Label(i.ToString(), GUILayout.Width(10)); * //time * GUILayout.Label("Time", GUILayout.Width(34)); * clip.frameList[i].time = EditorGUILayout.FloatField(frame.time, GUILayout.Width(40)); * //size * GUILayout.Label(" size x", GUILayout.Width(40)); * frame.size.x = EditorGUILayout.FloatField(frame.size.x,GUILayout.Width(40)); * GUILayout.Label("y", GUILayout.Width(10)); * frame.size.y = EditorGUILayout.FloatField(frame.size.y, GUILayout.Width(40)); * //texture * GUILayout.Label(" tex", GUILayout.Width(26)); * frame.tex = EditorGUILayout.ObjectField(frame.tex, typeof(Object), true) as Texture2D; * * useTexutreSize = GUILayout.Toggle(useTexutreSize, "auto"); * if(useTexutreSize) frame.size = new Vector2(frame.tex.width, frame.tex.height); * * GUILayout.EndHorizontal(); * } */ }