标签: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