<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
為了更方便地為UI檢視新增動畫,將動畫的編輯功能封裝在了UI View類中,可以通過編輯器快速的為檢視編輯動畫。動畫分為兩種型別,一種是Unity中的Animator動畫,該型別直接通過一個字串型別變數記錄動畫State狀態的名稱即可,播放時呼叫Animator類中的Play方法傳入該名稱。另一種是DoTween動畫,支援檢視的移動、旋轉、縮放、淡入淡出動畫的編輯:
首先看一下動畫相關的幾個類的資料結構:
using System; using UnityEngine; using DG.Tweening; namespace SK.Framework { /// <summary> /// UI移動動畫 /// </summary> [Serializable] public class UIMoveAnimation { public enum MoveMode { MoveIn, MoveOut } /// <summary> /// UI移動動畫方向 /// </summary> public enum UIMoveAnimationDirection { Left, Right, Top, Bottom, TopLeft, TopRight, MiddleCenter, BottomLeft, BottomRight, } public float duration = 1f; public float delay; public Ease ease = Ease.Linear; public UIMoveAnimationDirection direction = UIMoveAnimationDirection.Left; public bool isCustom; public Vector3 startValue; public Vector3 endValue; public MoveMode moveMode = MoveMode.MoveIn; public Tween Play(RectTransform target, bool instant = false) { Vector3 pos = Vector3.zero; float xOffset = target.rect.width / 2 + target.rect.width * target.pivot.x; float yOffset = target.rect.height / 2 + target.rect.height * target.pivot.y; switch (direction) { case UIMoveAnimationDirection.Left: pos = new Vector3(-xOffset, 0f, 0f); break; case UIMoveAnimationDirection.Right: pos = new Vector3(xOffset, 0f, 0f); break; case UIMoveAnimationDirection.Top: pos = new Vector3(0f, yOffset, 0f); break; case UIMoveAnimationDirection.Bottom: pos = new Vector3(0f, -yOffset, 0f); break; case UIMoveAnimationDirection.TopLeft: pos = new Vector3(-xOffset, yOffset, 0f); break; case UIMoveAnimationDirection.TopRight: pos = new Vector3(xOffset, yOffset, 0f); break; case UIMoveAnimationDirection.MiddleCenter: pos = Vector3.zero; break; case UIMoveAnimationDirection.BottomLeft: pos = new Vector3(-xOffset, -yOffset, 0f); break; case UIMoveAnimationDirection.BottomRight: pos = new Vector3(xOffset, -yOffset, 0f); break; } switch (moveMode) { case MoveMode.MoveIn: target.anchoredPosition3D = isCustom ? startValue : pos; return target.DOAnchorPos3D(endValue, instant ? 0f : duration).SetDelay(instant ? 0f : delay).SetEase(ease); case MoveMode.MoveOut: target.anchoredPosition3D = startValue; return target.DOAnchorPos3D(isCustom ? endValue : pos, instant ? 0f : duration).SetDelay(instant ? 0f : delay).SetEase(ease); default: return null; } } } }
using System; using UnityEngine; using DG.Tweening; namespace SK.Framework { /// <summary> /// UI旋轉動畫 /// </summary> [Serializable] public class UIRotateAnimation { public float duration = 1f; public float delay; public Ease ease = Ease.Linear; public Vector3 startValue; public Vector3 endValue; public RotateMode rotateMode = RotateMode.Fast; public bool isCustom; public Tween Play(RectTransform target, bool instant = false) { if (isCustom) { target.localRotation = Quaternion.Euler(startValue); } return target.DORotate(endValue, instant ? 0f : duration, rotateMode).SetDelay(instant ? 0f : delay).SetEase(ease); } } }
using System; using UnityEngine; using DG.Tweening; namespace SK.Framework { /// <summary> /// UI縮放動畫 /// </summary> [Serializable] public class UIScaleAnimation { public float duration = 1f; public float delay; public Ease ease = Ease.Linear; public Vector3 startValue = Vector3.zero; public Vector3 endValue = Vector3.one; public bool isCustom; public Tween Play(RectTransform target, bool instant = false) { if (isCustom) { target.localScale = startValue; } return target.DOScale(endValue, instant ? 0f : duration).SetDelay(instant ? 0f : delay).SetEase(ease); } } }
using System; using DG.Tweening; using UnityEngine; namespace SK.Framework { /// <summary> /// UI淡入淡出動畫 /// </summary> [Serializable] public class UIFadeAnimation { public float duration = 1f; public float delay; public Ease ease = Ease.Linear; public float startValue; public float endValue = 1f; public bool isCustom; public Tween Play(CanvasGroup target, bool instant = false) { if (isCustom) { target.alpha = startValue; } return target.DOFade(endValue, instant ? 0f : duration).SetDelay(instant ? 0f : delay).SetEase(ease); } } }
namespace SK.Framework { /// <summary> /// UI動畫型別 /// </summary> public enum UIAnimationType { /// <summary> /// DoTween動畫 /// </summary> Tween, /// <summary> /// Animator動畫 /// </summary> Animator, } }
using System; using UnityEngine; namespace SK.Framework { /// <summary> /// UI動畫 /// </summary> [Serializable] public class UIAnimation { public UIAnimationType animationType = UIAnimationType.Tween; public string stateName; public bool moveToggle; public UIMoveAnimation moveAnimation; public bool rotateToggle; public UIRotateAnimation rotateAnimation; public bool scaleToggle; public UIScaleAnimation scaleAnimation; public bool fadeToggle; public UIFadeAnimation fadeAnimation; public bool HasTweenAnimation { get { return moveToggle || rotateToggle || scaleToggle || fadeToggle; } } public IChain Play(UIView view, bool instant = false, Action callback = null) { switch (animationType) { case UIAnimationType.Tween: if (HasTweenAnimation) { var chain = view.Sequence(); var cc = new ConcurrentChain(); if (moveToggle) cc.Tween(() => moveAnimation.Play(view.RectTransform, instant)); if (rotateToggle) cc.Tween(() => rotateAnimation.Play(view.RectTransform, instant)); if (scaleToggle) cc.Tween(() => scaleAnimation.Play(view.RectTransform, instant)); if (fadeToggle) cc.Tween(() => fadeAnimation.Play(view.CanvasGroup, instant)); chain.Append(cc).Event(() => callback?.Invoke()).Begin(); return chain; } else { callback?.Invoke(); return null; } case UIAnimationType.Animator: return view.Sequence() .Animation(view.GetComponent<Animator>(), stateName) .Event(() => callback?.Invoke()) .Begin(); default: return null; } } } }
在UI View類中的相關變數如下:
using System; using UnityEngine.Events; namespace SK.Framework { [Serializable] public class ViewVisibilityChangedEvent { public UIAnimation animation = new UIAnimation(); public UnityEvent onBeginEvent; public UnityEvent onEndEvent; } }
為UI View建立Custom Editor:
using System; using UnityEngine; using UnityEditor; using DG.Tweening; using System.Reflection; using UnityEditor.Animations; using UnityEditor.AnimatedValues; namespace SK.Framework { [CustomEditor(typeof(UIView), true)] public class UIViewInspector : Editor { private enum Menu { Animation, UnityEvent, } private UIView Target; private SerializedProperty variables; private ViewVisibilityChangedEvent onShow; private ViewVisibilityChangedEvent onHide; private static string uiViewOnShowFoldout = "UIView OnShow Foldout"; private static string uiViewOnHideFoldout = "UIView OnHide Foldout"; private bool onShowFoldout; private bool onHideFoldout; private Menu onShowMenu = Menu.Animation; private Menu onHideMenu = Menu.Animation; private SerializedProperty onShowBeginEvent; private SerializedProperty onShowEndEvent; private SerializedProperty onHideBeginEvent; private SerializedProperty onHideEndEvent; private AnimBool onShowMoveAnimBool; private AnimBool onShowRotateAnimBool; private AnimBool onShowScaleAnimBool; private AnimBool onShowFadeAnimBool; private AnimBool onHideMoveAnimBool; private AnimBool onHideRotateAnimBool; private AnimBool onHideScaleAnimBool; private AnimBool onHideFadeAnimBool; private const float titleWidth = 80f; private const float labelWidth = 60f; public override void OnInspectorGUI() { if (Target == null) { Target = target as UIView; onShow = typeof(UIView).GetField("onVisible", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(Target) as ViewVisibilityChangedEvent; onHide = typeof(UIView).GetField("onInvisible", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(Target) as ViewVisibilityChangedEvent; variables = serializedObject.FindProperty("variables"); onShowFoldout = EditorPrefs.GetBool(uiViewOnShowFoldout); onHideFoldout = EditorPrefs.GetBool(uiViewOnHideFoldout); onShowBeginEvent = serializedObject.FindProperty("onVisible").FindPropertyRelative("onBeginEvent"); onShowEndEvent = serializedObject.FindProperty("onVisible").FindPropertyRelative("onEndEvent"); onHideBeginEvent = serializedObject.FindProperty("onInvisible").FindPropertyRelative("onBeginEvent"); onHideEndEvent = serializedObject.FindProperty("onInvisible").FindPropertyRelative("onEndEvent"); onShowMoveAnimBool = new AnimBool(onShow.animation.moveToggle, Repaint); onShowRotateAnimBool = new AnimBool(onShow.animation.rotateToggle, Repaint); onShowScaleAnimBool = new AnimBool(onShow.animation.scaleToggle, Repaint); onShowFadeAnimBool = new AnimBool(onShow.animation.fadeToggle, Repaint); onHideMoveAnimBool = new AnimBool(onHide.animation.moveToggle, Repaint); onHideRotateAnimBool = new AnimBool(onHide.animation.rotateToggle, Repaint); onHideScaleAnimBool = new AnimBool(onHide.animation.scaleToggle, Repaint); onHideFadeAnimBool = new AnimBool(onHide.animation.fadeToggle, Repaint); } EditorGUILayout.PropertyField(variables); //On Show 摺疊欄 var newOnShowFoldout = EditorGUILayout.Foldout(onShowFoldout, "On Visible", true); if (newOnShowFoldout != onShowFoldout) { onShowFoldout = newOnShowFoldout; EditorPrefs.SetBool(uiViewOnShowFoldout, onShowFoldout); } //Show if (onShowFoldout) { GUILayout.BeginHorizontal(); Color color = GUI.color; GUI.color = onShowMenu == Menu.Animation ? Color.cyan : color; if (GUILayout.Button("Animation", "ButtonLeft")) { onShowMenu = Menu.Animation; } GUI.color = onShowMenu == Menu.UnityEvent ? Color.cyan : color; if (GUILayout.Button("Event", "ButtonRight")) { onShowMenu = Menu.UnityEvent; } GUI.color = color; GUILayout.EndHorizontal(); switch (onShowMenu) { case Menu.Animation: //Animation Type GUILayout.BeginHorizontal(); GUILayout.Label("Mode", GUILayout.Width(titleWidth)); var newOnShowAnimationType = (UIAnimationType)EditorGUILayout.EnumPopup(onShow.animation.animationType); if (newOnShowAnimationType != onShow.animation.animationType) { Undo.RecordObject(Target, "On Show Animation Type"); onShow.animation.animationType = newOnShowAnimationType; EditorUtility.SetDirty(Target); } GUILayout.EndHorizontal(); UIAnimation animation = onShow.animation; switch (animation.animationType) { case UIAnimationType.Tween: //Move、Rotate、Scale、Fade GUILayout.BeginHorizontal(); { GUI.color = animation.moveToggle ? color : Color.gray; if (GUILayout.Button(EditorGUIUtility.IconContent("MoveTool"), "ButtonLeft", GUILayout.Width(25f))) { Undo.RecordObject(Target, "On Show Animation Move Toggle"); animation.moveToggle = !animation.moveToggle; onShowMoveAnimBool.target = animation.moveToggle; EditorUtility.SetDirty(Target); } GUI.color = animation.rotateToggle ? color : Color.gray; if (GUILayout.Button(EditorGUIUtility.IconContent("RotateTool"), "ButtonMid", GUILayout.Width(25f))) { Undo.RecordObject(Target, "On Show Animation Rotate Toggle"); animation.rotateToggle = !animation.rotateToggle; onShowRotateAnimBool.target = animation.rotateToggle; EditorUtility.SetDirty(Target); } GUI.color = animation.scaleToggle ? color : Color.gray; if (GUILayout.Button(EditorGUIUtility.IconContent("ScaleTool"), "ButtonMid", GUILayout.Width(25f))) { Undo.RecordObject(Target, "On Show Animation Scale Toggle"); animation.scaleToggle = !animation.scaleToggle; onShowScaleAnimBool.target = animation.scaleToggle; EditorUtility.SetDirty(Target); } GUI.color = animation.fadeToggle ? color : Color.gray; if (GUILayout.Button(EditorGUIUtility.IconContent("ViewToolOrbit"), "ButtonRight", GUILayout.Width(25f))) { Undo.RecordObject(Target, "On Show Animation Fade Toggle"); animation.fadeToggle = !animation.fadeToggle; onShowFadeAnimBool.target = animation.fadeToggle; EditorUtility.SetDirty(Target); } GUI.color = color; } GUILayout.EndHorizontal(); //MoveAnimation var moveAnimation = animation.moveAnimation; if (EditorGUILayout.BeginFadeGroup(onShowMoveAnimBool.faded)) { GUILayout.BeginHorizontal("Badge"); { GUILayout.BeginVertical(); { GUILayout.Space(40f); GUILayout.Label(EditorGUIUtility.IconContent("MoveTool")); } GUILayout.EndVertical(); GUILayout.BeginVertical(); { //Duration、Delay GUILayout.BeginHorizontal(); { GUILayout.Label("Duration", GUILayout.Width(labelWidth)); var newDuration = EditorGUILayout.FloatField(moveAnimation.duration); if (newDuration != moveAnimation.duration) { Undo.RecordObject(Target, "On Show Animation Move Duration"); moveAnimation.duration = newDuration; EditorUtility.SetDirty(Target); } GUILayout.Label("Delay", GUILayout.Width(labelWidth - 20f)); var newDelay = EditorGUILayout.FloatField(moveAnimation.delay); if (newDelay != moveAnimation.delay) { Undo.RecordObject(Target, "On Show Animation Move Delay"); moveAnimation.delay = newDelay; EditorUtility.SetDirty(Target); } } GUILayout.EndHorizontal(); //Is Custom GUILayout.BeginHorizontal(); { GUILayout.Label("From", GUILayout.Width(labelWidth - 2f)); if (GUILayout.Button(moveAnimation.isCustom ? "Custom Position" : "Direction", "DropDownButton")) { GenericMenu gm = new GenericMenu(); gm.AddItem(new GUIContent("Direction"), !moveAnimation.isCustom, () => { moveAnimation.isCustom = false; EditorUtility.SetDirty(Target); }); gm.AddItem(new GUIContent("Custom Position"), moveAnimation.isCustom, () => { moveAnimation.isCustom = true; EditorUtility.SetDirty(Target); }); gm.ShowAsContext(); } } GUILayout.EndHorizontal(); //From GUILayout.BeginHorizontal(); { GUILayout.Label(GUIContent.none, GUILayout.Width(labelWidth)); if (moveAnimation.isCustom) { Vector3 newStartValue = EditorGUILayout.Vector3Field(GUIContent.none, moveAnimation.startValue); if (newStartValue != moveAnimation.startValue) { Undo.RecordObject(Target, "On Show Animation Move From"); moveAnimation.startValue = newStartValue; EditorUtility.SetDirty(Target); } } else { var newMoveDirection = (UIMoveAnimationDirection)EditorGUILayout.EnumPopup(moveAnimation.direction); if (newMoveDirection != moveAnimation.direction) { Undo.RecordObject(Target, "On Show Animation Move Direction"); moveAnimation.direction = newMoveDirection; EditorUtility.SetDirty(Target); } } } GUILayout.EndHorizontal(); //To GUILayout.BeginHorizontal(); { GUILayout.Label("To", GUILayout.Width(labelWidth)); Vector3 newEndValue = EditorGUILayout.Vector3Field(GUIContent.none, moveAnimation.endValue); if (newEndValue != moveAnimation.endValue) { Undo.RecordObject(Target, "On Show Animation Move To"); moveAnimation.endValue = newEndValue; EditorUtility.SetDirty(Target); } } GUILayout.EndHorizontal(); //Ease GUILayout.BeginHorizontal(); { GUILayout.Label("Ease", GUILayout.Width(labelWidth)); var newEase = (Ease)EditorGUILayout.EnumPopup(moveAnimation.ease); if (newEase != moveAnimation.ease) { Undo.RecordObject(Target, "On Show Animation Move Ease"); moveAnimation.ease = newEase; EditorUtility.SetDirty(Target); } } GUILayout.EndHorizontal(); } GUILayout.EndVertical(); } GUILayout.EndHorizontal(); } EditorGUILayout.EndFadeGroup(); //RotateAnimation var rotateAnimation = animation.rotateAnimation; if (EditorGUILayout.BeginFadeGroup(onShowRotateAnimBool.faded)) { GUILayout.BeginHorizontal("Badge"); { GUILayout.BeginVertical(); { GUILayout.Space(rotateAnimation.isCustom ? 50f : 40f); GUILayout.Label(EditorGUIUtility.IconContent("RotateTool")); } GUILayout.EndVertical(); GUILayout.BeginVertical(); { //Duration、Delay GUILayout.BeginHorizontal(); { GUILayout.Label("Duration", GUILayout.Width(labelWidth)); var newDuration = EditorGUILayout.FloatField(rotateAnimation.duration); if (newDuration != rotateAnimation.duration) { Undo.RecordObject(Target, "On Show Animation Rotate Duration"); rotateAnimation.duration = newDuration; EditorUtility.SetDirty(Target); } GUILayout.Label("Delay", GUILayout.Width(labelWidth - 20f)); var newDelay = EditorGUILayout.FloatField(rotateAnimation.delay); if (newDelay != rotateAnimation.delay) { Undo.RecordObject(Target, "On Show Animation Rotate Delay"); rotateAnimation.delay = newDelay; EditorUtility.SetDirty(Target); } } GUILayout.EndHorizontal(); //Is Custom GUILayout.BeginHorizontal(); { GUILayout.Label("From", GUILayout.Width(labelWidth - 2f)); if (GUILayout.Button(rotateAnimation.isCustom ? "Fixed Rotation" : "Current Rotation", "DropDownButton")) { GenericMenu gm = new GenericMenu(); gm.AddItem(new GUIContent("Current Rotation"), !rotateAnimation.isCustom, () => { rotateAnimation.isCustom = false; EditorUtility.SetDirty(Target); }); gm.AddItem(new GUIContent("Fixed Rotation"), rotateAnimation.isCustom, () => { rotateAnimation.isCustom = true; EditorUtility.SetDirty(Target); }); gm.ShowAsContext(); } } GUILayout.EndHorizontal(); if (rotateAnimation.isCustom) { //From GUILayout.BeginHorizontal(); { GUILayout.Label(GUIContent.none, GUILayout.Width(labelWidth)); Vector3 newStartValue = EditorGUILayout.Vector3Field(GUIContent.none, rotateAnimation.startValue); if (newStartValue != rotateAnimation.startValue) { Undo.RecordObject(Target, "On Show Animation Rotate From"); rotateAnimation.startValue = newStartValue; EditorUtility.SetDirty(Target); } } GUILayout.EndHorizontal(); } //To GUILayout.BeginHorizontal(); { GUILayout.Label("To", GUILayout.Width(labelWidth)); Vector3 newEndValue = EditorGUILayout.Vector3Field(GUIContent.none, rotateAnimation.endValue); if (newEndValue != rotateAnimation.endValue) { Undo.RecordObject(Target, "On Show Animation Rotate To"); rotateAnimation.endValue = newEndValue; EditorUtility.SetDirty(Target); } } GUILayout.EndHorizontal(); //Rotate Mode GUILayout.BeginHorizontal(); { GUILayout.Label("Mode", GUILayout.Width(labelWidth)); var newRotateMode = (RotateMode)EditorGUILayout.EnumPopup(rotateAnimation.rotateMode); if (newRotateMode != rotateAnimation.rotateMode) { Undo.RecordObject(Target, "On Show Animation Rotate Mode"); rotateAnimation.rotateMode = newRotateMode; EditorUtility.SetDirty(Target); } } GUILayout.EndHorizontal(); //Ease GUILayout.BeginHorizontal(); { GUILayout.Label("Ease", GUILayout.Width(labelWidth)); var newEase = (Ease)EditorGUILayout.EnumPopup(rotateAnimation.ease); if (newEase != rotateAnimation.ease) { Undo.RecordObject(Target, "On Show Animation Rotate Ease"); rotateAnimation.ease = newEase; EditorUtility.SetDirty(Target); } } GUILayout.EndHorizontal(); } GUILayout.EndVertical(); } GUILayout.EndHorizontal(); } EditorGUILayout.EndFadeGroup(); //ScaleAnimation var scaleAnimation = animation.scaleAnimation; if (EditorGUILayout.BeginFadeGroup(onShowScaleAnimBool.faded)) { GUILayout.BeginHorizontal("Badge"); { GUILayout.BeginVertical(); { GUILayout.Space(scaleAnimation.isCustom ? 40f : 30f); GUILayout.Label(EditorGUIUtility.IconContent("ScaleTool")); } GUILayout.EndVertical(); GUILayout.BeginVertical(); { //Duration、Delay GUILayout.BeginHorizontal(); { GUILayout.Label("Duration", GUILayout.Width(labelWidth)); var newDuration = EditorGUILayout.FloatField(scaleAnimation.duration); if (newDuration != scaleAnimation.duration) { Undo.RecordObject(Target, "On Show Animation Scale Duration"); scaleAnimation.duration = newDuration; EditorUtility.SetDirty(Target); } GUILayout.Label("Delay", GUILayout.Width(labelWidth - 20f)); var newDelay = EditorGUILayout.FloatField(scaleAnimation.delay); if (newDelay != scaleAnimation.delay) { Undo.RecordObject(Target, "On Show Animation Scale Delay"); scaleAnimation.delay = newDelay; EditorUtility.SetDirty(Target); } } GUILayout.EndHorizontal(); //Is Custom GUILayout.BeginHorizontal(); { GUILayout.Label("From", GUILayout.Width(labelWidth - 2f)); if (GUILayout.Button(scaleAnimation.isCustom ? "Fixed Scale" : "Current Scale", "DropDownButton")) { GenericMenu gm = new GenericMenu(); gm.AddItem(new GUIContent("Current Scale"), !scaleAnimation.isCustom, () => { scaleAnimation.isCustom = false; EditorUtility.SetDirty(Target); }); gm.AddItem(new GUIContent("Fixed Scale"), scaleAnimation.isCustom, () => { scaleAnimation.isCustom = true; EditorUtility.SetDirty(Target); }); gm.ShowAsContext(); } } GUILayout.EndHorizontal(); if (scaleAnimation.isCustom) { //From GUILayout.BeginHorizontal(); { GUILayout.Label(GUIContent.none, GUILayout.Width(labelWidth)); Vector3 newStartValue = EditorGUILayout.Vector3Field(GUIContent.none, scaleAnimation.startValue); if (newStartValue != scaleAnimation.startValue) { Undo.RecordObject(Target, "On Show Animation Scale From"); scaleAnimation.startValue = newStartValue; EditorUtility.SetDirty(Target); } } GUILayout.EndHorizontal(); } //To GUILayout.BeginHorizontal(); { GUILayout.Label("To", GUILayout.Width(labelWidth)); Vector3 newEndValue = EditorGUILayout.Vector3Field(GUIContent.none, scaleAnimation.endValue); if (newEndValue != scaleAnimation.endValue) { Undo.RecordObject(Target, "On Show Animation Scale To"); scaleAnimation.endValue = newEndValue; EditorUtility.SetDirty(Target); } } GUILayout.EndHorizontal(); //Ease GUILayout.BeginHorizontal(); { GUILayout.Label("Ease", GUILayout.Width(labelWidth)); var newEase = (Ease)EditorGUILayout.EnumPopup(scaleAnimation.ease); if (newEase != scaleAnimation.ease) { Undo.RecordObject(Target, "On Show Animation Scale Ease"); scaleAnimation.ease = newEase; EditorUtility.SetDirty(Target); } } GUILayout.EndHorizontal(); } GUILayout.EndVertical(); } GUILayout.EndHorizontal(); } EditorGUILayout.EndFadeGroup(); //FadeAnimation var fadeAnimation = animation.fadeAnimation; if (EditorGUILayout.BeginFadeGroup(onShowFadeAnimBool.faded)) { GUILayout.BeginHorizontal("Badge"); { GUILayout.BeginVertical(); { GUILayout.Space(fadeAnimation.isCustom ? 40f : 30f); GUILayout.Label(EditorGUIUtility.IconContent("ViewToolOrbit")); } GUILayout.EndVertical(); GUILayout.BeginVertical(); { //Duration、Delay GUILayout.BeginHorizontal(); { GUILayout.Label("Duration", GUILayout.Width(labelWidth)); var newDuration = EditorGUILayout.FloatField(fadeAnimation.duration); if (newDuration != fadeAnimation.duration) { Undo.RecordObject(Target, "On Show Animation Fade Duration"); fadeAnimation.duration = newDuration; EditorUtility.SetDirty(Target); } GUILayout.Label("Delay", GUILayout.Width(labelWidth - 20f)); var newDelay = EditorGUILayout.FloatField(fadeAnimation.delay); if (newDelay != fadeAnimation.delay) { Undo.RecordObject(Target, "On Show Animation Fade Delay"); fadeAnimation.delay = newDelay; EditorUtility.SetDirty(Target); } } GUILayout.EndHorizontal(); //Is Custom GUILayout.BeginHorizontal(); { GUILayout.Label("From", GUILayout.Width(labelWidth - 2f)); if (GUILayout.Button(fadeAnimation.isCustom ? "Fixed Alpha" : "Current Alpha", "DropDownButton")) { GenericMenu gm = new GenericMenu(); gm.AddItem(new GUIContent("Current Alpha"), !fadeAnimation.isCustom, () => { fadeAnimation.isCustom = false; EditorUtility.SetDirty(Target); }); gm.AddItem(new GUIContent("Fixed Alpha"), fadeAnimation.isCustom, () => { fadeAnimation.isCustom = true; EditorUtility.SetDirty(Target); }); gm.ShowAsContext(); } } GUILayout.EndHorizontal(); if (fadeAnimation.isCustom) { //From GUILayout.BeginHorizontal(); { GUILayout.Label(GUIContent.none, GUILayout.Width(labelWidth)); float newStartValue = EditorGUILayout.FloatField(GUIContent.none, fadeAnimation.startValue); if (newStartValue != fadeAnimation.startValue) { Undo.RecordObject(Target, "On Show Animation Fade From"); fadeAnimation.startValue = newStartValue; EditorUtility.SetDirty(Target); } } GUILayout.EndHorizontal(); } //To GUILayout.BeginHorizontal(); { GUILayout.Label("To", GUILayout.Width(labelWidth)); float newEndValue = EditorGUILayout.FloatField(GUIContent.none, fadeAnimation.endValue); if (newEndValue != fadeAnimation.endValue) { Undo.RecordObject(Target, "On Show Animation Fade To"); fadeAnimation.endValue = newEndValue; EditorUtility.SetDirty(Target); } } GUILayout.EndHorizontal(); //Ease GUILayout.BeginHorizontal(); { GUILayout.Label("Ease", GUILayout.Width(labelWidth)); var newEase = (Ease)EditorGUILayout.EnumPopup(fadeAnimation.ease); if (newEase != fadeAnimation.ease) { Undo.RecordObject(Target, "On Show Animation Fade Ease"); fadeAnimation.ease = newEase; EditorUtility.SetDirty(Target); } } GUILayout.EndHorizontal(); } GUILayout.EndVertical(); } GUILayout.EndHorizontal(); } EditorGUILayout.EndFadeGroup(); break; case UIAnimationType.Animator: var animator = Target.GetComponent<Animator>(); if (animator != null) { var animatorController = animator.runtimeAnimatorController as AnimatorController; var stateMachine = animatorController.layers[0].stateMachine; if (stateMachine.states.Length == 0) { EditorGUILayout.HelpBox("no animator state was found.", MessageType.Info); } else { string[] stateNames = new string[stateMachine.states.Length]; for (int i = 0; i < stateNames.Length; i++) { stateNames[i] = stateMachine.states[i].state.name; } var index = Array.FindIndex(stateNames, m => m == animation.stateName); GUILayout.BeginHorizontal(); GUILayout.Label("State Name", GUILayout.Width(titleWidth)); var newIndex = EditorGUILayout.Popup(index, stateNames); if (newIndex != index) { Undo.RecordObject(Target, "Show Animation State Name"); animation.stateName = stateNames[newIndex]; EditorUtility.SetDirty(Target); } GUILayout.EndHorizontal(); } } else { EditorGUILayout.HelpBox("no animator component on this view.", MessageType.Error); } break; default: break; } break; case Menu.UnityEvent: //OnBeginEvent、OnEndEvent EditorGUILayout.PropertyField(onShowBeginEvent); EditorGUILayout.PropertyField(onShowEndEvent); break; default: break; } } //On Hide 摺疊欄 var newOnHideFoldout = EditorGUILayout.Foldout(onHideFoldout, "On Invisible", true); if (newOnHideFoldout != onHideFoldout) { onHideFoldout = newOnHideFoldout; EditorPrefs.SetBool(uiViewOnHideFoldout, onHideFoldout); } //Hide if (onHideFoldout) { GUILayout.BeginHorizontal(); Color color = GUI.color; GUI.color = onHideMenu == Menu.Animation ? Color.cyan : color; if (GUILayout.Button("Animation", "ButtonLeft")) { onHideMenu = Menu.Animation; } GUI.color = onHideMenu == Menu.UnityEvent ? Color.cyan : color; if (GUILayout.Button("Event", "ButtonRight")) { onHideMenu = Menu.UnityEvent; } GUI.color = color; GUILayout.EndHorizontal(); switch (onHideMenu) { case Menu.Animation: //Animation Type GUILayout.BeginHorizontal(); GUILayout.Label("Mode", GUILayout.Width(titleWidth)); var newOnHideAnimationType = (UIAnimationType)EditorGUILayout.EnumPopup(onHide.animation.animationType); if (newOnHideAnimationType != onHide.animation.animationType) { Undo.RecordObject(Target, "On Hide Animation Type"); onHide.animation.animationType = newOnHideAnimationType; } GUILayout.EndHorizontal(); UIAnimation animation = onHide.animation; switch (animation.animationType) { case UIAnimationType.Tween: //Move、Rotate、Scale、Fade GUILayout.BeginHorizontal(); { GUI.color = animation.moveToggle ? color : Color.gray; if (GUILayout.Button(EditorGUIUtility.IconContent("MoveTool"), "ButtonLeft", GUILayout.Width(25f))) { Undo.RecordObject(Target, "On Hide Animation Move Toggle"); animation.moveToggle = !animation.moveToggle; onHideMoveAnimBool.target = animation.moveToggle; EditorUtility.SetDirty(Target); } GUI.color = animation.rotateToggle ? color : Color.gray; if (GUILayout.Button(EditorGUIUtility.IconContent("RotateTool"), "ButtonMid", GUILayout.Width(25f))) { Undo.RecordObject(Target, "On Hide Animation Rotate Toggle"); animation.rotateToggle = !animation.rotateToggle; onHideRotateAnimBool.target = animation.rotateToggle; EditorUtility.SetDirty(Target); } GUI.color = animation.scaleToggle ? color : Color.gray; if (GUILayout.Button(EditorGUIUtility.IconContent("ScaleTool"), "ButtonMid", GUILayout.Width(25f))) { Undo.RecordObject(Target, "On Hide Animation Scale Toggle"); animation.scaleToggle = !animation.scaleToggle; onHideScaleAnimBool.target = animation.scaleToggle; EditorUtility.SetDirty(Target); } GUI.color = animation.fadeToggle ? color : Color.gray; if (GUILayout.Button(EditorGUIUtility.IconContent("ViewToolOrbit"), "ButtonRight", GUILayout.Width(25f))) { Undo.RecordObject(Target, "On Hide Animation Fade Toggle"); animation.fadeToggle = !animation.fadeToggle; onHideFadeAnimBool.target = animation.fadeToggle; EditorUtility.SetDirty(Target); } GUI.color = color; } GUILayout.EndHorizontal(); //MoveAnimation var moveAnimation = animation.moveAnimation; if (EditorGUILayout.BeginFadeGroup(onHideMoveAnimBool.faded)) { GUILayout.BeginHorizontal("Badge"); { GUILayout.BeginVertical(); { GUILayout.Space(40f); GUILayout.Label(EditorGUIUtility.IconContent("MoveTool")); } GUILayout.EndVertical(); GUILayout.BeginVertical(); { //Duration、Delay GUILayout.BeginHorizontal(); { GUILayout.Label("Duration", GUILayout.Width(labelWidth)); var newDuration = EditorGUILayout.FloatField(moveAnimation.duration); if (newDuration != moveAnimation.duration) { Undo.RecordObject(Target, "On Hide Animation Move Duration"); moveAnimation.duration = newDuration; EditorUtility.SetDirty(Target); } GUILayout.Label("Delay", GUILayout.Width(labelWidth - 20f)); var newDelay = EditorGUILayout.FloatField(moveAnimation.delay); if (newDelay != moveAnimation.delay) { Undo.RecordObject(Target, "On Hide Animation Move Delay"); moveAnimation.delay = newDelay; EditorUtility.SetDirty(Target); } } GUILayout.EndHorizontal(); //From GUILayout.BeginHorizontal(); { GUILayout.Label("From", GUILayout.Width(labelWidth)); Vector3 newStartValue = EditorGUILayout.Vector3Field(GUIContent.none, moveAnimation.startValue); if (newStartValue != moveAnimation.startValue) { Undo.RecordObject(Target, "On Hide Animation Move From"); moveAnimation.startValue = newStartValue; EditorUtility.SetDirty(Target); } } GUILayout.EndHorizontal(); //Is Custom GUILayout.BeginHorizontal(); { GUILayout.Label("To", GUILayout.Width(labelWidth - 2f)); if (GUILayout.Button(moveAnimation.isCustom ? "Custom Position" : "Direction", "DropDownButton")) { GenericMenu gm = new GenericMenu(); gm.AddItem(new GUIContent("Direction"), !moveAnimation.isCustom, () => { moveAnimation.isCustom = false; EditorUtility.SetDirty(Target); }); gm.AddItem(new GUIContent("Custom Position"), moveAnimation.isCustom, () => { moveAnimation.isCustom = true; EditorUtility.SetDirty(Target); }); gm.ShowAsContext(); } } GUILayout.EndHorizontal(); //To GUILayout.BeginHorizontal(); { GUILayout.Label(GUIContent.none, GUILayout.Width(labelWidth)); if (moveAnimation.isCustom) { Vector3 newEndValue = EditorGUILayout.Vector3Field(GUIContent.none, moveAnimation.endValue); if (newEndValue != moveAnimation.endValue) { Undo.RecordObject(Target, "On Hide Animation Move End"); moveAnimation.endValue = newEndValue; EditorUtility.SetDirty(Target); } } else { var newMoveDirection = (UIMoveAnimationDirection)EditorGUILayout.EnumPopup(moveAnimation.direction); if (newMoveDirection != moveAnimation.direction) { Undo.RecordObject(Target, "On Hide Animation Move Direction"); moveAnimation.direction = newMoveDirection; EditorUtility.SetDirty(Target); } } } GUILayout.EndHorizontal(); //Ease GUILayout.BeginHorizontal(); { GUILayout.Label("Ease", GUILayout.Width(labelWidth)); var newEase = (Ease)EditorGUILayout.EnumPopup(moveAnimation.ease); if (newEase != moveAnimation.ease) { Undo.RecordObject(Target, "On Hide Animation Move Ease"); moveAnimation.ease = newEase; EditorUtility.SetDirty(Target); } } GUILayout.EndHorizontal(); } GUILayout.EndVertical(); } GUILayout.EndHorizontal(); } EditorGUILayout.EndFadeGroup(); //RotateAnimation var rotateAnimation = animation.rotateAnimation; if (EditorGUILayout.BeginFadeGroup(onHideRotateAnimBool.faded)) { GUILayout.BeginHorizontal("Badge"); { GUILayout.BeginVertical(); { GUILayout.Space(rotateAnimation.isCustom ? 50f : 40f); GUILayout.Label(EditorGUIUtility.IconContent("RotateTool")); } GUILayout.EndVertical(); GUILayout.BeginVertical(); { //Duration、Delay GUILayout.BeginHorizontal(); { GUILayout.Label("Duration", GUILayout.Width(labelWidth)); var newDuration = EditorGUILayout.FloatField(rotateAnimation.duration); if (newDuration != rotateAnimation.duration) { Undo.RecordObject(Target, "On Hide Animation Rotate Duration"); rotateAnimation.duration = newDuration; EditorUtility.SetDirty(Target); } GUILayout.Label("Delay", GUILayout.Width(labelWidth - 20f)); var newDelay = EditorGUILayout.FloatField(rotateAnimation.delay); if (newDelay != rotateAnimation.delay) { Undo.RecordObject(Target, "On Hide Animation Rotate Delay"); rotateAnimation.delay = newDelay; EditorUtility.SetDirty(Target); } } GUILayout.EndHorizontal(); //Is Custom GUILayout.BeginHorizontal(); { GUILayout.Label("From", GUILayout.Width(labelWidth - 2f)); if (GUILayout.Button(rotateAnimation.isCustom ? "Fixed Rotation" : "Current Rotation", "DropDownButton")) { GenericMenu gm = new GenericMenu(); gm.AddItem(new GUIContent("Current Rotation"), !rotateAnimation.isCustom, () => { rotateAnimation.isCustom = false; EditorUtility.SetDirty(Target); }); gm.AddItem(new GUIContent("Fixed Rotation"), rotateAnimation.isCustom, () => { rotateAnimation.isCustom = true; EditorUtility.SetDirty(Target); }); gm.ShowAsContext(); } } GUILayout.EndHorizontal(); if (rotateAnimation.isCustom) { //From GUILayout.BeginHorizontal(); { GUILayout.Label(GUIContent.none, GUILayout.Width(labelWidth)); Vector3 newStartValue = EditorGUILayout.Vector3Field(GUIContent.none, rotateAnimation.startValue); if (newStartValue != rotateAnimation.startValue) { Undo.RecordObject(Target, "On Hide Animation Rotate From"); rotateAnimation.startValue = newStartValue; EditorUtility.SetDirty(Target); } } GUILayout.EndHorizontal(); } //To GUILayout.BeginHorizontal(); { GUILayout.Label("To", GUILayout.Width(labelWidth)); Vector3 newEndValue = EditorGUILayout.Vector3Field(GUIContent.none, rotateAnimation.endValue); if (newEndValue != rotateAnimation.endValue) { Undo.RecordObject(Target, "On Hide Animation Rotate To"); rotateAnimation.endValue = newEndValue; EditorUtility.SetDirty(Target); } } GUILayout.EndHorizontal(); //Rotate Mode GUILayout.BeginHorizontal(); { GUILayout.Label("Mode", GUILayout.Width(labelWidth)); var newRotateMode = (RotateMode)EditorGUILayout.EnumPopup(rotateAnimation.rotateMode); if (newRotateMode != rotateAnimation.rotateMode) { Undo.RecordObject(Target, "On Hide Animation Rotate Mode"); rotateAnimation.rotateMode = newRotateMode; EditorUtility.SetDirty(Target); } } GUILayout.EndHorizontal(); //Ease GUILayout.BeginHorizontal(); { GUILayout.Label("Ease", GUILayout.Width(labelWidth)); var newEase = (Ease)EditorGUILayout.EnumPopup(rotateAnimation.ease); if (newEase != rotateAnimation.ease) { Undo.RecordObject(Target, "On Hide Animation Rotate Ease"); rotateAnimation.ease = newEase; EditorUtility.SetDirty(Target); } } GUILayout.EndHorizontal(); } GUILayout.EndVertical(); } GUILayout.EndHorizontal(); } EditorGUILayout.EndFadeGroup(); //ScaleAnimation var scaleAnimation = animation.scaleAnimation; if (EditorGUILayout.BeginFadeGroup(onHideScaleAnimBool.faded)) { GUILayout.BeginHorizontal("Badge"); { GUILayout.BeginVertical(); { GUILayout.Space(scaleAnimation.isCustom ? 40f : 30f); GUILayout.Label(EditorGUIUtility.IconContent("ScaleTool")); } GUILayout.EndVertical(); GUILayout.BeginVertical(); { //Duration、Delay GUILayout.BeginHorizontal(); { GUILayout.Label("Duration", GUILayout.Width(labelWidth)); var newDuration = EditorGUILayout.FloatField(scaleAnimation.duration); if (newDuration != scaleAnimation.duration) { Undo.RecordObject(Target, "On Hide Animation Scale Duration"); scaleAnimation.duration = newDuration; EditorUtility.SetDirty(Target); } GUILayout.Label("Delay", GUILayout.Width(labelWidth - 20f)); var newDelay = EditorGUILayout.FloatField(scaleAnimation.delay); if (newDelay != scaleAnimation.delay) { Undo.RecordObject(Target, "On Hide Animation Scale Delay"); scaleAnimation.delay = newDelay; EditorUtility.SetDirty(Target); } } GUILayout.EndHorizontal(); //Is Custom GUILayout.BeginHorizontal(); { GUILayout.Label("From", GUILayout.Width(labelWidth - 2f)); if (GUILayout.Button(scaleAnimation.isCustom ? "Fixed Scale" : "Current Scale", "DropDownButton")) { GenericMenu gm = new GenericMenu(); gm.AddItem(new GUIContent("Current Scale"), !scaleAnimation.isCustom, () => { scaleAnimation.isCustom = false; EditorUtility.SetDirty(Target); }); gm.AddItem(new GUIContent("Fixed Scale"), scaleAnimation.isCustom, () => { scaleAnimation.isCustom = true; EditorUtility.SetDirty(Target); }); gm.ShowAsContext(); } } GUILayout.EndHorizontal(); if (scaleAnimation.isCustom) { //From GUILayout.BeginHorizontal(); { GUILayout.Label(GUIContent.none, GUILayout.Width(labelWidth)); Vector3 newStartValue = EditorGUILayout.Vector3Field(GUIContent.none, scaleAnimation.startValue); if (newStartValue != scaleAnimation.startValue) { Undo.RecordObject(Target, "On Hide Animation Scale From"); scaleAnimation.startValue = newStartValue; EditorUtility.SetDirty(Target); } } GUILayout.EndHorizontal(); } //To GUILayout.BeginHorizontal(); { GUILayout.Label("To", GUILayout.Width(labelWidth)); Vector3 newEndValue = EditorGUILayout.Vector3Field(GUIContent.none, scaleAnimation.endValue); if (newEndValue != scaleAnimation.endValue) { Undo.RecordObject(Target, "On Hide Animation Scale To"); scaleAnimation.endValue = newEndValue; EditorUtility.SetDirty(Target); } } GUILayout.EndHorizontal(); //Ease GUILayout.BeginHorizontal(); { GUILayout.Label("Ease", GUILayout.Width(labelWidth)); var newEase = (Ease)EditorGUILayout.EnumPopup(scaleAnimation.ease); if (newEase != scaleAnimation.ease) { Undo.RecordObject(Target, "On Hide Animation Scale Ease"); scaleAnimation.ease = newEase; EditorUtility.SetDirty(Target); } } GUILayout.EndHorizontal(); } GUILayout.EndVertical(); } GUILayout.EndHorizontal(); } EditorGUILayout.EndFadeGroup(); //FadeAnimation var fadeAnimation = animation.fadeAnimation; if (EditorGUILayout.BeginFadeGroup(onHideFadeAnimBool.faded)) { GUILayout.BeginHorizontal("Badge"); { GUILayout.BeginVertical(); { GUILayout.Space(fadeAnimation.isCustom ? 40f : 30f); GUILayout.Label(EditorGUIUtility.IconContent("ViewToolOrbit")); } GUILayout.EndVertical(); GUILayout.BeginVertical(); { //Duration、Delay GUILayout.BeginHorizontal(); { GUILayout.Label("Duration", GUILayout.Width(labelWidth)); var newDuration = EditorGUILayout.FloatField(fadeAnimation.duration); if (newDuration != fadeAnimation.duration) { Undo.RecordObject(Target, "On Hide Animation Fade Duration"); fadeAnimation.duration = newDuration; EditorUtility.SetDirty(Target); } GUILayout.Label("Delay", GUILayout.Width(labelWidth - 20f)); var newDelay = EditorGUILayout.FloatField(fadeAnimation.delay); if (newDelay != fadeAnimation.delay) { Undo.RecordObject(Target, "On Hide Animation Fade Delay"); fadeAnimation.delay = newDelay; EditorUtility.SetDirty(Target); } } GUILayout.EndHorizontal(); //Is Custom GUILayout.BeginHorizontal(); { GUILayout.Label("From", GUILayout.Width(labelWidth - 2f)); if (GUILayout.Button(fadeAnimation.isCustom ? "Fixed Alpha" : "Current Alpha", "DropDownButton")) { GenericMenu gm = new GenericMenu(); gm.AddItem(new GUIContent("Current Alpha"), !fadeAnimation.isCustom, () => { fadeAnimation.isCustom = false; EditorUtility.SetDirty(Target); }); gm.AddItem(new GUIContent("Fixed Alpha"), fadeAnimation.isCustom, () => { fadeAnimation.isCustom = true; EditorUtility.SetDirty(Target); }); gm.ShowAsContext(); } } GUILayout.EndHorizontal(); if (fadeAnimation.isCustom) { //From GUILayout.BeginHorizontal(); { GUILayout.Label(GUIContent.none, GUILayout.Width(labelWidth)); float newStartValue = EditorGUILayout.FloatField(GUIContent.none, fadeAnimation.startValue); if (newStartValue != fadeAnimation.startValue) { Undo.RecordObject(Target, "On Hide Animation Fade From"); fadeAnimation.startValue = newStartValue; EditorUtility.SetDirty(Target); } } GUILayout.EndHorizontal(); } //To GUILayout.BeginHorizontal(); { GUILayout.Label("To", GUILayout.Width(labelWidth)); float newEndValue = EditorGUILayout.FloatField(GUIContent.none, fadeAnimation.endValue); if (newEndValue != fadeAnimation.endValue) { Undo.RecordObject(Target, "On Hide Animation Fade To"); fadeAnimation.endValue = newEndValue; EditorUtility.SetDirty(Target); } } GUILayout.EndHorizontal(); //Ease GUILayout.BeginHorizontal(); { GUILayout.Label("Ease", GUILayout.Width(labelWidth)); var newEase = (Ease)EditorGUILayout.EnumPopup(fadeAnimation.ease); if (newEase != fadeAnimation.ease) { Undo.RecordObject(Target, "On Hide Animation Fade Ease"); fadeAnimation.ease = newEase; EditorUtility.SetDirty(Target); } } GUILayout.EndHorizontal(); } GUILayout.EndVertical(); } GUILayout.EndHorizontal(); } EditorGUILayout.EndFadeGroup(); break; case UIAnimationType.Animator: var animator = Target.GetComponent<Animator>(); if (animator != null) { var animatorController = animator.runtimeAnimatorController as AnimatorController; var stateMachine = animatorController.layers[0].stateMachine; if (stateMachine.states.Length == 0) { EditorGUILayout.HelpBox("no animator state was found.", MessageType.Info); } else { string[] stateNames = new string[stateMachine.states.Length]; for (int i = 0; i < stateNames.Length; i++) { stateNames[i] = stateMachine.states[i].state.name; } var index = Array.FindIndex(stateNames, m => m == animation.stateName); GUILayout.BeginHorizontal(); GUILayout.Label("State Name", GUILayout.Width(titleWidth)); var newIndex = EditorGUILayout.Popup(index, stateNames); if (newIndex != index) { Undo.RecordObject(Target, "Show Animation State Name"); animation.stateName = stateNames[newIndex]; EditorUtility.SetDirty(Target); } GUILayout.EndHorizontal(); } } else { EditorGUILayout.HelpBox("no animator component on this view.", MessageType.Error); } break; default: break; } break; case Menu.UnityEvent: //OnBeginEvent、OnEndEvent EditorGUILayout.PropertyField(onHideBeginEvent); EditorGUILayout.PropertyField(onHideEndEvent); break; default: break; } } serializedObject.ApplyModifiedProperties(); } } }
以上就是Unity實戰之製作動畫編輯器的詳細內容,更多關於Unity動畫編輯器的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45