Unity如何制作动画编辑器
发表于:2025-01-16 作者:千家信息网编辑
千家信息网最后更新 2025年01月16日,这篇文章主要介绍了Unity如何制作动画编辑器,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。为了更方便地为UI视图添加动画,将动画的编
千家信息网最后更新 2025年01月16日Unity如何制作动画编辑器
这篇文章主要介绍了Unity如何制作动画编辑器,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。
为了更方便地为UI视图添加动画,将动画的编辑功能封装在了UI View类中,可以通过编辑器快速的为视图编辑动画。动画分为两种类型,一种是Unity中的Animator动画,该类型直接通过一个字符串类型变量记录动画State状态的名称即可,播放时调用Animator类中的Play方法传入该名称。另一种是DoTween动画,支持视图的移动、旋转、缩放、淡入淡出动画的编辑:
首先看一下动画相关的几个类的数据结构:
using System;using UnityEngine;using DG.Tweening; namespace SK.Framework{ ////// UI移动动画 /// [Serializable] public class UIMoveAnimation { public enum MoveMode { MoveIn, MoveOut } ////// UI移动动画方向 /// 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{ ////// UI旋转动画 /// [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{ ////// UI缩放动画 /// [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{ ////// UI淡入淡出动画 /// [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{ ////// UI动画类型 /// public enum UIAnimationType { ////// DoTween动画 /// Tween, ////// Animator动画 /// Animator, }}
using System;using UnityEngine; namespace SK.Framework{ ////// UI动画 /// [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(), 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(); 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 (); 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如何制作动画编辑器"这篇文章对大家有帮助,同时也希望大家多多支持,关注行业资讯频道,更多相关知识等着你来学习!
动画
篇文章
类型
编辑器
视图
移动
制作
变量
名称
支持
价值
兴趣
功能
可以通过
同时
字符
字符串
数据
数据结构
方向
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
学生网络安全怎么预防
丹阳网络安全案例
手机软件开发要源码吗
关于网络安全内容的板报
游戏外挂是什么软件开发的
南昌查克软件开发有限公司
科迪计算机网络技术
网络安全等级划分几级
wow nga数据库
mc连接服务器登录失败
数据库管理系统产生于二十世纪多少年代
安徽网络安全管理需要体测吗
伦敦服务器登录方法
高速公路服务器设置的必要性
消费级基因组变异数据库
宝塔数据库被删除怎么恢复
中国的网络技术事业
上海管理网络技术服务哪家好
中小学开展网络安全活动方案
小健人互联网科技有限公司融资
地图展示数据库
网络安全案例内容学习
洛阳安卓软件开发
青岛直播软件开发公司有哪些
学软件开发从哪方面学
佛山二八网络技术有限公司
智能led 软件开发
我的世界服务器怎么防刷东西
dbc数据库有但是刷不出来
软件开发实施服务方案