标签:animation broadcast delegate methods visual studio
所谓流利语法的实现是成员函数 返回值是 类的实例this
出处:http://blog.csdn.net/u010019717
author:孙广东
1、Camera Shake
一个脚本,这个动画涉及到两个动画,一个是Cube自由落体使用Easing函数类型就行了。另一个是抖动使用类TweenShake成员。
在Start()函数中初始化了以上两个动画成员。然后在 Update()中按键触发自由落体完事紧接着抖动动画。fallTween. .OnCompleted( ( sender ) => { shake.Play(); } ) 将两个动画进行串联。
代码如下:
using UnityEngine; using System.Collections; using DaikonForge.Tween; public class TestShakeObject : MonoBehaviour { public Transform Camera; private TweenShake shake; private TweenBase fallTween; void Start() { shake = TweenShake.Obtain() .SetStartValue( Camera.position ) .SetDuration( 1f ) .SetShakeMagnitude( 0.25f ) .SetShakeSpeed( 13f ) .SetTimeScaleIndependent( true ) .OnExecute( ( result ) => { Camera.position = new Vector3( result.x, result.y, Camera.position.z ); } ); fallTween = this.TweenPosition() .SetStartValue( transform.position + Vector3.up * 5f ) .SetEasing( TweenEasingFunctions.EaseInExpo ) // 从StartValue运动到当前editor的位置 .SetDuration( 1f ) .SetDelay( 0.25f ) .SetTimeScaleIndependent( true ) .OnCompleted( ( sender ) => { shake.Play(); } ) // 接着开始 抖动动画 .Play(); } void OnGUI() { GUILayout.Label( " Press SPACE to restart " ); } void Update() { if( Input.GetKeyDown( KeyCode.LeftArrow ) ) { Debug.Log( "Time scale: SLOW" ); Time.timeScale = 0.15f; } else if( Input.GetKeyDown( KeyCode.RightArrow ) ) { Debug.Log( "Time scale: NORMAL" ); Time.timeScale = 1f; } if( Input.GetKeyDown( KeyCode.Space ) ) { fallTween.Stop().Rewind().Play(); } } }
2、Doge
一个脚本 这个例子就很帅了在Start()方法中定义了所有的动画。运用了TweenGroup的两种模式Sequential和Concurrent将各个动画和动画组进行串联起来。
最后执行是通过语句:
part1
.AppendDelay(1f )
.AppendTween(part2 )
.Play();
所以part1是最大的Group了,这个组的定义是内的成员序列执行,他首先添加了part1.AppendTween( dogeScale ); dogeScale动画是大小变化Easing.Spring。
然后又添加了part1.AppendTween( textPopup ); 这是在for循环内的代码,所以是多个textPopup 顺序执行, textPopup组内又做了什么操作呢?alphaTween显示渐入和旋转rotTween的Easing.Spring风格。
然后就要开始执行part2了。part2 组内cameraSlide是让当前对象就是摄像机有位置变化! logoSlide是让指定的对象有位置变化, logoAlphaTween是让指定的对象有alpha变化
所以程序执行的效果动画的执行顺序是这样的:
dogeScale →
textPopup { alphaTween , rotTween } →
textPopup { alphaTween , rotTween } →
textPopup { alphaTween , rotTween } →
part2 { cameraSlide, logoSlide, logoAlphaTween}
开开代码吧
using UnityEngine; using System.Collections; using DaikonForge.Tween; using DaikonForge.Tween.Interpolation; public class MuchTweenSoWow : MonoBehaviour { public Transform doge; public TextMesh[] text; public TextMesh logo; void Start() { TweenGroup part1 = new TweenGroup() .SetAutoCleanup( true ) .SetMode( TweenGroupMode.Sequential ); // NOTE: This could be more efficiently done with Transform.TweenScale(), // but we wanted to show an example of using Reflection to tween any // property by name. Tween<Vector3> dogeScale = doge.transform .TweenProperty<Vector3>( "localScale" ) .SetStartValue( Vector3.zero ) .SetDuration( 0.5f ) .SetDelay( 0.5f ) .SetInterpolator( EulerInterpolator.Default ) .SetEasing( TweenEasingFunctions.Spring ); part1.AppendTween( dogeScale ); for( int i = 0; i < text.Length; i++ ) { text[ i ].color = new Color( 1, 1, 1, 0 ); var alphaTween = text[ i ].TweenAlpha() .SetAutoCleanup( true ) .SetStartValue( 0f ) .SetEndValue( 1f ) .SetDuration( 0.25f ) .SetDelay( 0.25f ); var rotTween = text[ i ].TweenRotation() .SetAutoCleanup( true ) .SetEndValue( Vector3.zero ) .SetDuration( 0.5f ) .SetDelay( 0.25f ) .SetEasing( TweenEasingFunctions.Spring ); var textPopup = new TweenGroup() .SetAutoCleanup( true ) .SetMode( TweenGroupMode.Concurrent ) .AppendTween( alphaTween, rotTween ); part1.AppendTween( textPopup ); } Tween<Vector3> cameraSlide = this.TweenPosition() .SetEndValue( transform.position + new Vector3( 0f, -1f, 0f ) ) .SetDuration( 0.5f ) .SetEasing( TweenEasingFunctions.EaseInOutQuad ); Tween<Vector3> logoSlide = logo.TweenPosition() .SetStartValue( logo.transform.position - ( Vector3.up * 5 ) ) .SetDuration( 1f ) .SetEasing( TweenEasingFunctions.Bounce ); Tween<float> logoAlphaTween = Tween<float>.Obtain() .SetStartValue( 0f ) .SetEndValue( 1f ) .SetDuration( 0.5f ) .SetEasing( TweenEasingFunctions.Linear ) .OnExecute( ( result ) => { logo.color = new Color( 1f, 1f, 1f, result ); } ); logo.color = Color.clear; TweenGroup part2 = new TweenGroup() .SetAutoCleanup( true ) .SetMode( TweenGroupMode.Concurrent ) .AppendTween( cameraSlide, logoSlide, logoAlphaTween ); part1 .AppendDelay( 1f ) .AppendTween( part2 ) .Play(); } }
3、Easing Functions
程序演示了 10个Easing Functions函数(当然了肯定不止10个)
一个脚本 代码页很简单, 主要是在编辑器上的Inspector面板上赋值。
然后TweenEasingCallback func = TweenEasingFunctions.GetFunction(this.EaseType );
在.SetEasing( func ) 执行:
代码如下:
using UnityEngine; using System.Collections; using DaikonForge.Tween; public class TestEasingFunctions : MonoBehaviour { public EasingType EaseType; void Start() { TweenEasingCallback func = TweenEasingFunctions.GetFunction( this.EaseType ); transform.TweenPosition() .SetEndValue( transform.position + ( Vector3.right * 9f ) ) .SetDelay( 0.5f, false ) .SetDuration( 1.33f ) .SetEasing( func ) .SetLoopType( TweenLoopType.Loop ) .Play(); } }
一个脚本TestSlinky.cs文件
OnEnable() 函数中。 得到所有SpriteRenderer 然后进行排序, 同时为每一个定义了动画tween。
Update() 函数中。当我们单击鼠标左键,会启动所有的动画!
代码如下:
using UnityEngine; using System; using System.Collections; using System.Collections.Generic; using DaikonForge.Tween; public class TestSlinky : MonoBehaviour { private List<Tween<Vector3>> tweens = new List<Tween<Vector3>>(); void OnEnable() { var rings = GameObject.FindObjectsOfType<SpriteRenderer>() as SpriteRenderer[]; Array.Sort( rings, ( lhs, rhs ) => lhs.sortingOrder.CompareTo( rhs.sortingOrder ) ); for( int i = 0; i < rings.Length; i++ ) { var obj = rings[ i ]; var tween = obj.TweenPosition() .SetDelay( i * 0.02f ) .SetDuration( 0.5f ) .SetEasing( TweenEasingFunctions.Spring ); // If we don‘t call Play(), then tween.CurrentValue may not contain // a valid value when Update detects the first mouse click tween.Play(); tweens.Add( tween ); } } void OnGUI() { var rect = new Rect( 10, 10, 600, 25 ); GUI.Label( rect, "Click anywhere with the mouse to move rings. SPACE: Slow, ENTER: Fast" ); } void Update() { if( Input.GetKeyDown( KeyCode.Space ) ) { Debug.Log( "Time scale: SLOW" ); Time.timeScale = 0.15f; } else if( Input.GetKeyDown( KeyCode.Return ) ) { Debug.Log( "Time scale: NORMAL" ); Time.timeScale = 1f; } if( !Input.GetMouseButtonDown( 0 ) ) return; var plane = new Plane( Vector3.back, Vector3.zero ); var ray = Camera.main.ScreenPointToRay( Input.mousePosition ); // Find the 3D world position corresponding to the mouse click position float distance = 0; plane.Raycast( ray, out distance ); var endPosition = ray.GetPoint( distance ); // Retarget all tweens to arrive at the new position for( int i = 0; i < tweens.Count; i++ ) { var tween = tweens[ i ]; tween.SetStartValue( tween.CurrentValue ).SetEndValue( endPosition ).Play(); } } }
一个脚本TestHighConcurrency.cs文件,每个cube都挂着。
有三个动画tweenPosition、tweenRotation、tweenPunchScale
OnEnable()函数中 通过Chain函数进行级联。内部构成了一种循环。
代码如下:
using UnityEngine; using System.Collections; using DaikonForge.Tween; public class TestHighConcurrency : MonoBehaviour { public float BounceRange = 9f; private Tween<Vector3> tweenRotation; private Tween<Vector3> tweenPosition; private Tween<Vector3> tweenPunchScale; void OnEnable() { tweenPosition = this.TweenPosition() .SetStartValue( transform.position ) .SetEndValue( transform.position - ( Vector3.up * BounceRange ) ) .SetDuration( 1f ) .SetEasing( TweenEasingFunctions.EaseInOutBack ) .SetDelay( Random.Range( 0.1f, 0.5f ) ); tweenRotation = this.TweenRotation( false ) .SetEndValue( new Vector3( 0, 360, 0 ) ) .SetDuration( 0.25f ) .SetDelay( Random.Range( 0f, 0.5f ) ); tweenPunchScale = this.TweenScale() .SetStartValue( transform.localScale ) .SetEndValue( transform.localScale * 2f ) .SetDelay( Random.Range( 0.25f, 0.75f ) ) .SetEasing( TweenEasingFunctions.Punch ); tweenPosition .Play() .Chain( tweenRotation ) .Wait( 0.5f ) .Chain( tweenPunchScale ) .Wait( 0.5f ) .Chain( tweenPosition, () => { tweenPosition .SetLoopType( TweenLoopType.Pingpong ) .SetDelay( 1.33f ) .SetDuration( 1.25f ) .ReversePlayDirection() .Play(); } ); } }
6、Stress Test (Group)
一个脚本TestHighConcurrencyGroup.cs文件。
游戏场景OnEnable()中会产生1000个精灵。他们都是从远点,运动到园上的随机位置。
运动过程有一组动画concurrentGroup构成(Concurrent模式),包括concurrentGroup、concurrentGroup、animatePosition。 又有一个组sequentialGroup的模式是sequentialGroup,内部包装sequentialGroup,让其循环。
还有一个控制摄像机的动画animatePivot
剩下就是提供了:重新开始,暂停,恢复,停止等支持。主要是全局的List<TweenBase>存储着1000个sequentialGroup。
代码如下:
using System.Collections; using System.Collections.Generic; using UnityEngine; using DaikonForge.Tween; public class TestHighConcurrencyGroup : MonoBehaviour { public GameObject pivot; public GameObject spriteTemplate; private List<TweenBase> tweens = new List<TweenBase>(); public void Start() { DebugMessages.Add( "This sample animates the position, opacity, and scale of 1000 sprites simultaneously." ); DebugMessages.Add( "Due to the high number of simultaneous animations, it may run slowly in the browser or on mobile devices." ); } public void OnEnable() { if( spriteTemplate == null ) return; var radius = Camera.main.orthographicSize * 0.95f; var duration = 0.5f; TweenEasingCallback easingFunc = TweenEasingFunctions.EaseOutSine; var count = 1000; for( int i = 0; i < count; i++ ) { var angle = Random.Range( 0.0f, Mathf.PI * 2f ); var endPosition = new Vector3 // 随机产生圆上的位置 ( Mathf.Cos( angle ) * radius, Mathf.Sin( angle ) * radius ); var sprite = (GameObject)GameObject.Instantiate( spriteTemplate ); sprite.hideFlags = HideFlags.HideInHierarchy; var animateOpacity = sprite.renderer .TweenAlpha() .SetDuration( duration ) .SetEasing( easingFunc ) .SetStartValue( 0f ) .SetEndValue( 0.8f ); var animateScale = sprite.transform .TweenScale() .SetDuration( duration ) .SetEasing( easingFunc ) .SetStartValue( Vector3.one * 0.25f ) .SetEndValue( Vector3.one ); var animatePosition = sprite.transform .TweenPosition() .SetDuration( duration ) .SetEasing( easingFunc ) .SetStartValue( Vector3.zero ) .SetEndValue( endPosition ); var concurrentGroup = new TweenGroup() .SetMode( TweenGroupMode.Concurrent ) .AppendTween( animateOpacity, animateScale, animatePosition ); var sequentialGroup = new TweenGroup() .SetMode( TweenGroupMode.Sequential ) .AppendDelay( 255f / i ) .AppendTween( concurrentGroup ) .SetLoopType( TweenLoopType.Loop ); tweens.Add( sequentialGroup ); sequentialGroup.Play(); } if( pivot != null ) { var animatePivot = pivot.transform // pivot摄像机的父对象,相当于控制摄像机旋转 .TweenRotation() .SetDuration( 10 ) .SetStartValue( new Vector3( 0, -45, 0 ) ) .SetEndValue( new Vector3( 0, 45, 0 ) ) .SetLoopType( TweenLoopType.Pingpong ); tweens.Add( animatePivot ); animatePivot.Play(); } DebugMessages.Add( count + " sprite animations created..." ); } public void OnGUI() { var rect = new Rect( 10, 30, 200, Screen.height - 100 ); GUI.Box( rect, GUIContent.none ); rect.xMin += 5; rect.yMin += 5; rect.xMax -= 10; GUILayout.BeginArea( rect ); GUILayout.BeginVertical(); { var tweenState = tweens[ 0 ].State; GUI.enabled = tweenState == TweenState.Stopped; if( GUILayout.Button( "Play" ) ) { DebugMessages.Add( "Playing..." ); for( int i = 0; i < tweens.Count; i++ ) { tweens[ i ].Rewind(); tweens[ i ].Play(); } } if( tweenState == TweenState.Playing ) { GUI.enabled = true; if( GUILayout.Button( "Pause" ) ) { DebugMessages.Add( "Pausing..." ); for( int i = 0; i < tweens.Count; i++ ) { if( tweens[ i ].State != TweenState.Playing ) { Debug.LogWarning( string.Format( "Not playing ({0}) - {1}", tweens[ i ].State, tweens[ i ] ) ); } tweens[ i ].Pause(); } } } else if( tweenState == TweenState.Paused ) { GUI.enabled = true; if( GUILayout.Button( "Resume" ) ) { DebugMessages.Add( "Resuming..." ); for( int i = 0; i < tweens.Count; i++ ) { tweens[ i ].Resume(); } } } else { // Placeholder GUI.enabled = false; GUILayout.Button( "Pause" ); } GUI.enabled = tweenState != TweenState.Stopped; if( GUILayout.Button( "Stop" ) ) { DebugMessages.Add( "Stopped all tweens" ); for( int i = 0; i < tweens.Count; i++ ) { tweens[ i ].Stop(); } } GUILayout.Space( 25 ); if( tweenState != TweenState.Stopped ) { var timeScaleSetting = tweens[ 0 ].IsTimeScaleIndependent; var userSetting = GUILayout.Toggle( timeScaleSetting, "Time scale independent" ); if( userSetting != timeScaleSetting ) { DebugMessages.Add( "Toggled time scale independence" ); for( int i = 0; i < tweens.Count; i++ ) { tweens[ i ].SetIsTimeScaleIndependent( userSetting ); } } GUILayout.Space( 5 ); GUILayout.Label( "Time scale: " + Time.timeScale ); Time.timeScale = GUILayout.HorizontalSlider( Time.timeScale, 0f, 2f ); } } GUILayout.EndVertical(); GUILayout.EndArea(); GUI.enabled = true; } }
标签:animation broadcast delegate methods visual studio
原文地址:http://blog.csdn.net/u010019717/article/details/44699991