This commit is contained in:
Tamas Pal 2023-04-06 15:40:55 +00:00 committed by GitHub
commit e3bb157813
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5616 changed files with 22416 additions and 459366 deletions

22
.gitattributes vendored Normal file
View File

@ -0,0 +1,22 @@
# Auto detect text files and perform LF normalization
* text=auto
# Custom for Visual Studio
*.cs diff=csharp
*.sln merge=union
*.csproj merge=union
*.vbproj merge=union
*.fsproj merge=union
*.dbproj merge=union
# Standard to msysgit
*.doc diff=astextplain
*.DOC diff=astextplain
*.docx diff=astextplain
*.DOCX diff=astextplain
*.dot diff=astextplain
*.DOT diff=astextplain
*.pdf diff=astextplain
*.PDF diff=astextplain
*.rtf diff=astextplain
*.RTF diff=astextplain

54
.gitignore vendored
View File

@ -1,2 +1,56 @@
.DS_Store
[Ll]ibrary/
[Tt]emp/
[Oo]bj/
# Autogenerated VS/MD solution and project files
/*.csproj
/*.unityproj
/*.sln
/*.suo
/*.user
/*.userprefs
/*.pidb
/*.booproj
# =========================
# Operating System Files
# =========================
# OSX
# =========================
.DS_Store
.AppleDouble
.LSOverride
# Icon must ends with two \r.
Icon
# Thumbnails
._*
# Files that might appear on external disk
.Spotlight-V100
.Trashes
# Windows
# =========================
# Windows image file caches
Thumbs.db
ehthumbs.db
# Folder config file
Desktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msm
*.msp
*.lock

Binary file not shown.

Binary file not shown.

7
Assets/Editor.meta Normal file
View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 805cdb447a0a94f85a92205ddec8d72e
folderAsset: yes
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,504 @@
using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Linq;
using System.Collections.Generic;
using System.IO;
[CustomEditor( typeof( GoDummyPath ) )]
public class GoDummyPathEditor : Editor
{
private GoDummyPath _target;
private GUIStyle _labelStyle;
private GUIStyle _indexStyle;
private int _insertIndex = 0;
private float _snapDistance = 5f;
private bool _showNodeDetails;
private bool _fileLoadSaveDetails;
private int _selectedNodeIndex = -1;
#region Monobehaviour and Editor
void OnEnable()
{
// setup the font for the 'begin' 'end' text
_labelStyle = new GUIStyle();
_labelStyle.fontStyle = FontStyle.Bold;
_labelStyle.normal.textColor = Color.white;
_labelStyle.fontSize = 16;
_indexStyle = new GUIStyle();
_indexStyle.fontStyle = FontStyle.Bold;
_indexStyle.normal.textColor = Color.white;
_indexStyle.fontSize = 12;
_target = (GoDummyPath)target;
}
public override void OnInspectorGUI()
{
// what kind of handles shall we use?
EditorGUILayout.BeginHorizontal();
EditorGUILayout.PrefixLabel( "Use Standard Handles" );
_target.useStandardHandles = EditorGUILayout.Toggle( _target.useStandardHandles );
EditorGUILayout.EndHorizontal();
// path name:
EditorGUILayout.BeginHorizontal();
EditorGUILayout.PrefixLabel( "Route Name" );
_target.pathName = EditorGUILayout.TextField( _target.pathName );
EditorGUILayout.EndHorizontal();
if( _target.pathName == string.Empty )
_target.pathName = "route" + Random.Range( 1, 100000 );
// path color:
EditorGUILayout.BeginHorizontal();
EditorGUILayout.PrefixLabel( "Route Color" );
_target.pathColor = EditorGUILayout.ColorField( _target.pathColor );
EditorGUILayout.EndHorizontal();
// force straight lines:
EditorGUILayout.BeginHorizontal();
EditorGUILayout.PrefixLabel( "Force Straight Line Path" );
_target.forceStraightLinePath = EditorGUILayout.Toggle( _target.forceStraightLinePath );
EditorGUILayout.EndHorizontal();
// resolution
EditorGUILayout.BeginHorizontal();
EditorGUILayout.PrefixLabel( "Editor Drawing Resolution" );
_target.pathResolution = EditorGUILayout.IntSlider( _target.pathResolution, 2, 100 );
EditorGUILayout.EndHorizontal();
EditorGUILayout.Separator();
// insert node - we need 3 or more nodes for insert to make sense
if( _target.nodes.Count > 2 )
{
EditorGUILayout.BeginHorizontal();
EditorGUILayout.PrefixLabel( "Insert Node" );
_insertIndex = EditorGUILayout.IntField( _insertIndex );
if( GUILayout.Button( "Insert" ) )
{
// validate the index
if( _insertIndex >= 0 && _insertIndex < _target.nodes.Count )
{
// insert the node offsetting it a bit from the previous node
var copyNodeIndex = _insertIndex == 0 ? 0 : _insertIndex;
var copyNode = _target.nodes[copyNodeIndex];
copyNode.x += 10;
copyNode.z += 10;
insertNodeAtIndex( copyNode, _insertIndex );
}
}
EditorGUILayout.EndHorizontal();
}
// close route?
if( GUILayout.Button( "Close Path" ) )
{
Undo.RecordObject( _target, "Path Vector Changed" );
closeRoute();
GUI.changed = true;
}
// shift the start point to the origin
if( GUILayout.Button( "Shift Path to Start at Origin" ) )
{
Undo.RecordObject( _target, "Path Vector Changed" );
var offset = Vector3.zero;
// see what kind of path we are. the simplest case is just a straight line
var path = new GoSpline( _target.nodes, _target.forceStraightLinePath );
if( path.splineType == GoSplineType.StraightLine || _target.nodes.Count < 5 )
offset = Vector3.zero - _target.nodes[0];
else
offset = Vector3.zero - _target.nodes[1];
for( var i = 0; i < _target.nodes.Count; i++ )
_target.nodes[i] += offset;
GUI.changed = true;
}
// reverse
if( GUILayout.Button( "Reverse Path" ) )
{
Undo.RecordObject( _target, "Path Vector Changed" );
_target.nodes.Reverse();
GUI.changed = true;
}
// persist to disk
EditorGUILayout.Space();
EditorGUILayout.LabelField( "Save to/Read from Disk" );
EditorGUILayout.Space();
EditorGUILayout.BeginHorizontal();
EditorGUILayout.PrefixLabel( "Serialize and Save Path" );
if( GUILayout.Button( "Save" ) )
{
var path = EditorUtility.SaveFilePanel( "Save path", Application.dataPath + "/StreamingAssets", _target.pathName + ".asset", "asset" );
if( path != string.Empty )
{
persistRouteToDisk( path );
// fetch the filename and set it as the routeName
_target.pathName = Path.GetFileName( path ).Replace( ".asset", string.Empty );
GUI.changed = true;
}
}
EditorGUILayout.EndHorizontal();
// load from disk
EditorGUILayout.BeginHorizontal();
EditorGUILayout.PrefixLabel( "Load saved path" );
if( GUILayout.Button( "Load" ) )
{
var path = EditorUtility.OpenFilePanel( "Choose path to load", Path.Combine( Application.dataPath, "StreamingAssets" ), "asset" );
if( path != string.Empty )
{
if( !File.Exists( path ) )
{
EditorUtility.DisplayDialog( "File does not exist", "Path couldn't find the file you specified", "Close" );
}
else
{
_target.nodes = GoSpline.bytesToVector3List( File.ReadAllBytes( path ) );
_target.pathName = Path.GetFileName( path ).Replace( ".asset", string.Empty );
GUI.changed = true;
}
}
}
EditorGUILayout.EndHorizontal();
// node display
EditorGUILayout.Space();
_showNodeDetails = EditorGUILayout.Foldout( _showNodeDetails, "Show Node Values" );
if( _showNodeDetails )
{
EditorGUI.indentLevel++;
for( int i = 0; i < _target.nodes.Count; i++ )
_target.nodes[i] = EditorGUILayout.Vector3Field( "Node " + ( i + 1 ), _target.nodes[i] );
EditorGUI.indentLevel--;
}
// instructions
EditorGUILayout.Space();
EditorGUILayout.HelpBox( "While dragging a node, hold down Ctrl and slowly move the cursor to snap to a nearby point\n\n" +
"Click the 'Close Path' button to add a new node that will close out the current path.\n\n" +
"Hold Command while dragging a node to snap in 5 point increments\n\n" +
"Double click to add a new node at the end of the path\n\n" +
"Hold down alt while adding a node to prepend the new node at the front of the route\n\n" +
"Press delete or backspace to delete the selected node\n\n" +
"NOTE: make sure you have the pan tool selected while editing paths", MessageType.None );
// update and redraw:
if( GUI.changed )
{
EditorUtility.SetDirty( _target );
Repaint();
}
}
void OnSceneGUI()
{
if( !_target.gameObject.activeSelf )
return;
// handle current selection and node addition via double click or ctrl click
if( Event.current.type == EventType.MouseDown )
{
var nearestIndex = getNearestNodeForMousePosition( Event.current.mousePosition );
_selectedNodeIndex = nearestIndex;
// double click to add
if( Event.current.clickCount > 1 )
{
var translatedPoint = HandleUtility.GUIPointToWorldRay( Event.current.mousePosition )
.GetPoint( ( _target.transform.position - Camera.current.transform.position ).magnitude );
Undo.RecordObject( _target, "Path Node Added" );
// if alt is down then prepend the node to the beginning
if( Event.current.alt )
insertNodeAtIndex( translatedPoint, 0 );
else
appendNodeAtPoint( translatedPoint );
}
}
if( _selectedNodeIndex >= 0 )
{
// shall we delete the selected node?
if( Event.current.keyCode == KeyCode.Delete || Event.current.keyCode == KeyCode.Backspace )
{
if (_target.nodes.Count > 2) {
Undo.RecordObject( _target, "Path Node Deleted" );
Event.current.Use();
removeNodeAtIndex( _selectedNodeIndex );
_selectedNodeIndex = -1;
}
}
}
if( _target.nodes.Count > 1 )
{
// allow path adjustment undo:
Undo.RecordObject( _target, "Path Vector Changed" );
// path begin and end labels or just one if the path is closed
if( Vector3.Distance( _target.nodes[0], _target.nodes[_target.nodes.Count - 1] ) == 0 )
{
Handles.Label( _target.nodes[0], " Begin and End", _labelStyle );
}
else
{
Handles.Label( _target.nodes[0], " Begin", _labelStyle );
Handles.Label( _target.nodes[_target.nodes.Count - 1], " End", _labelStyle );
}
// draw the handles, arrows and lines
drawRoute();
for( var i = 0; i < _target.nodes.Count; i++ )
{
Handles.color = _target.pathColor;
// dont label the first and last nodes
if( i > 0 && i < _target.nodes.Count - 1 )
Handles.Label( _target.nodes[i] + new Vector3( 3f, 0, 1.5f ), i.ToString(), _indexStyle );
Handles.color = Color.white;
if( _target.useStandardHandles )
{
_target.nodes[i] = Handles.PositionHandle( _target.nodes[i], Quaternion.identity );
}
else
{
// how big shall we draw the handles?
var distanceToTarget = Vector3.Distance( SceneView.lastActiveSceneView.camera.transform.position, _target.transform.position );
distanceToTarget = Mathf.Abs( distanceToTarget );
var handleSize = Mathf.Ceil( distanceToTarget / 75 );
_target.nodes[i] = Handles.FreeMoveHandle( _target.nodes[i],
Quaternion.identity,
handleSize,
new Vector3( 5, 0, 5 ),
Handles.SphereCap );
}
// should we snap? we need at least 4 nodes because we dont snap to the previous and next nodes
if( Event.current.control && _target.nodes.Count > 3 )
{
// dont even bother checking for snapping to the previous/next nodes
var index = getNearestNode( _target.nodes[i], i, i + 1, i - 1 );
var nearest = _target.nodes[index];
var distanceToNearestNode = Vector3.Distance( nearest, _target.nodes[i] );
// is it close enough to snap?
if( distanceToNearestNode <= _snapDistance )
{
GUI.changed = true;
_target.nodes[i] = nearest;
}
else if( distanceToNearestNode <= _snapDistance * 2 )
{
// show which nodes are getting close enough to snap to
var color = Color.red;
color.a = 0.3f;
Handles.color = color;
Handles.SphereCap( 0, _target.nodes[i], Quaternion.identity, _snapDistance * 2 );
//Handles.DrawWireDisc( _target.nodes[i], Vector3.up, _snapDistance );
Handles.color = Color.white;
}
}
} // end for
if( GUI.changed )
{
Repaint();
EditorUtility.SetDirty( _target );
}
} // end if
}
#endregion
#region Private methods
private void appendNodeAtPoint( Vector3 node )
{
_target.nodes.Add( node );
GUI.changed = true;
}
private void removeNodeAtIndex( int index )
{
if( index >= _target.nodes.Count || index < 0 )
return;
_target.nodes.RemoveAt( index );
GUI.changed = true;
}
private void insertNodeAtIndex( Vector3 node, int index )
{
// validate the index
if( index >= 0 && index < _target.nodes.Count )
{
_target.nodes.Insert( index, node );
GUI.changed = true;
}
}
private void drawArrowBetweenPoints( Vector3 point1, Vector3 point2 )
{
// no need to draw arrows for tiny segments
var distance = Vector3.Distance( point1, point2 );
if( distance < 40 )
return;
// we dont want to be exactly in the middle so we offset the length of the arrow
var lerpModifier = ( distance * 0.5f - 25 ) / distance;
Handles.color = _target.pathColor;
// get the midpoint between the 2 points
var dir = Vector3.Lerp( point1, point2, lerpModifier );
var quat = Quaternion.LookRotation( point2 - point1 );
Handles.ArrowCap( 0, dir, quat, 25 );
Handles.color = Color.white;
}
private int getNearestNode( Vector3 pos, params int[] excludeNodes )
{
var excludeNodesList = new System.Collections.Generic.List<int>( excludeNodes );
var bestDistance = float.MaxValue;
var index = -1;
var distance = float.MaxValue;
for( var i = _target.nodes.Count - 1; i >= 0; i-- )
{
if( excludeNodesList.Contains( i ) )
continue;
distance = Vector3.Distance( pos, _target.nodes[i] );
if( distance < bestDistance )
{
bestDistance = distance;
index = i;
}
}
return index;
}
private int getNearestNodeForMousePosition( Vector3 mousePos )
{
var bestDistance = float.MaxValue;
var index = -1;
var distance = float.MaxValue;
for( var i = _target.nodes.Count - 1; i >= 0; i-- )
{
var nodeToGui = HandleUtility.WorldToGUIPoint( _target.nodes[i] );
distance = Vector2.Distance( nodeToGui, mousePos );
if( distance < bestDistance )
{
bestDistance = distance;
index = i;
}
}
// make sure we are close enough to a node
if( bestDistance < 10 )
return index;
return -1;
}
private void closeRoute()
{
// we will use the GoSpline class to handle the dirtywork of closing the path
var path = new GoSpline( _target.nodes, _target.forceStraightLinePath );
path.closePath();
_target.nodes = path.nodes;
GUI.changed = true;
}
private void persistRouteToDisk( string path )
{
var bytes = new List<byte>();
foreach( var vec in _target.nodes )
{
bytes.AddRange( System.BitConverter.GetBytes( vec.x ) );
bytes.AddRange( System.BitConverter.GetBytes( vec.y ) );
bytes.AddRange( System.BitConverter.GetBytes( vec.z ) );
}
File.WriteAllBytes( path, bytes.ToArray() );
}
private void drawRoute()
{
// if we are forcing straight lines just use this setup
if( _target.forceStraightLinePath )
{
// draw just the route here and optional arrows
for( var i = 0; i < _target.nodes.Count; i++ )
{
Handles.color = _target.pathColor;
if( i < _target.nodes.Count - 1 )
{
Handles.DrawLine( _target.nodes[i], _target.nodes[i + 1] );
drawArrowBetweenPoints( _target.nodes[i], _target.nodes[i + 1] );
}
}
}
}
#endregion
}

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 14be03d8aa8eb4defb30eb2e964df151
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

7
Assets/Materials.meta Normal file
View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: ccdbeba8ee88b15498c6dbfa2acf3d5a
folderAsset: yes
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,10 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!62 &6200000
PhysicsMaterial2D:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_Name: Floor
friction: 5
bounciness: 0

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: dd6a97cc93bb7af48b69c503bcbcf1cd
NativeFormatImporter:
mainObjectFileID: -1
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,27 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 6
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_Name: LineRendererMaterial
m_Shader: {fileID: 7, guid: 0000000000000000f000000000000000, type: 0}
m_ShaderKeywords:
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _MainTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Floats: []
m_Colors:
- _Color: {r: 0, g: 0, b: 0, a: 1}

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: c8054517d5dd81f438a7ca239b5d7461
NativeFormatImporter:
mainObjectFileID: -1
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,32 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 6
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_Name: Smoke
m_Shader: {fileID: 203, guid: 0000000000000000f000000000000000, type: 0}
m_ShaderKeywords:
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _MainTex:
m_Texture: {fileID: 2800000, guid: 08f28e42a647e2a4cbd32e793359aa3c, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Floats:
- _InvFade: 1
m_Colors:
- _Color: {r: 1, g: 1, b: 1, a: 1}
- _TintColor: {r: 0.53731346, g: 0.53731346, b: 0.53731346, a: 0.8117647}
--- !u!1002 &2100001
EditorExtensionImpl:
serializedVersion: 6

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 96558d9af5ccba84da0a06dc9afa072d
NativeFormatImporter:
mainObjectFileID: -1
userData:
assetBundleName:
assetBundleVariant:

7
Assets/Plugins.meta Normal file
View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 6e97a8686757f4a41b97c319f6ca7071
folderAsset: yes
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 8c5cefa129e0c4945acf6eb49a983eae
folderAsset: yes
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

406
Assets/Plugins/GoKit/Go.cs Normal file
View File

@ -0,0 +1,406 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class Go : MonoBehaviour
{
// defaults used for all tweens/properties that are not explicitly set
public static GoEaseType defaultEaseType = GoEaseType.Linear;
public static GoLoopType defaultLoopType = GoLoopType.RestartFromBeginning;
public static GoUpdateType defaultUpdateType = GoUpdateType.Update;
// defines what we should do in the event that a TweenProperty is added and an already existing tween has the same
// property and target
public static GoDuplicatePropertyRuleType duplicatePropertyRule = GoDuplicatePropertyRuleType.None;
public static GoLogLevel logLevel = GoLogLevel.Warn;
// validates that the target object still exists each tick of the tween. NOTE: it is recommended
// that you just properly remove your tweens before destroying any objects even though this might destroy them for you
public static bool validateTargetObjectsEachTick = true;
// Used to stop instances being created while the application is quitting
private static bool _applicationIsQuitting = false;
private static List<AbstractGoTween> _tweens = new List<AbstractGoTween>(); // contains Tweens, TweenChains and TweenFlows
private bool _timeScaleIndependentUpdateIsRunning;
// only one Go can exist
static Go _instance = null;
public static Go instance
{
get
{
// Don't allow new instances to be created when the application is quitting to avoid the GOKit object never being destroyed.
// These dangling instances can't be found with FindObjectOfType and so you'd get multiple instances in a scene.
if( !_instance && !_applicationIsQuitting )
{
// check if there is a GO instance already available in the scene graph
_instance = FindObjectOfType( typeof( Go ) ) as Go;
// possible Unity bug with FindObjectOfType workaround
//_instance = FindObjectOfType( typeof( Go ) ) ?? GameObject.Find( "GoKit" ).GetComponent<Go>() as Go;
// nope, create a new one
if( !_instance )
{
var obj = new GameObject( "GoKit" );
_instance = obj.AddComponent<Go>();
DontDestroyOnLoad( obj );
}
}
return _instance;
}
}
/// <summary>
/// loops through all the Tweens and updates any that are of updateType. If any Tweens are complete
/// (the update call will return true) they are removed.
/// </summary>
private void handleUpdateOfType( GoUpdateType updateType, float deltaTime )
{
// loop backwards so we can remove completed tweens
for( var i = _tweens.Count - 1; i >= 0; --i )
{
var t = _tweens[i];
if( t.state == GoTweenState.Destroyed )
{
// destroy method has been called
removeTween( t );
}
else
{
// only process tweens with our update type that are running
if( t.updateType == updateType && t.state == GoTweenState.Running && t.update( deltaTime * t.timeScale ) )
{
// tween is complete if we get here. if destroyed or set to auto remove kill it
if( t.state == GoTweenState.Destroyed || t.autoRemoveOnComplete )
{
removeTween( t );
t.destroy();
}
}
}
}
}
#region Monobehaviour
private void Update()
{
if( _tweens.Count == 0 )
return;
handleUpdateOfType( GoUpdateType.Update, Time.deltaTime );
}
private void LateUpdate()
{
if( _tweens.Count == 0 )
return;
handleUpdateOfType( GoUpdateType.LateUpdate, Time.deltaTime );
}
private void FixedUpdate()
{
if( _tweens.Count == 0 )
return;
handleUpdateOfType( GoUpdateType.FixedUpdate, Time.deltaTime );
}
private void OnApplicationQuit()
{
_instance = null;
Destroy( gameObject );
_applicationIsQuitting = true;
}
#endregion
/// <summary>
/// this only runs as needed and handles time scale independent Tweens
/// </summary>
private IEnumerator timeScaleIndependentUpdate()
{
_timeScaleIndependentUpdateIsRunning = true;
var time = Time.realtimeSinceStartup;
while( _tweens.Count > 0 )
{
var elapsed = Time.realtimeSinceStartup - time;
time = Time.realtimeSinceStartup;
// update tweens
handleUpdateOfType( GoUpdateType.TimeScaleIndependentUpdate, elapsed );
yield return null;
}
_timeScaleIndependentUpdateIsRunning = false;
}
/// <summary>
/// checks for duplicate properties. if one is found and the DuplicatePropertyRuleType is set to
/// DontAddCurrentProperty it will return true indicating that the tween should not be added.
/// this only checks tweens that are not part of an AbstractTweenCollection
/// </summary>
private static bool handleDuplicatePropertiesInTween( GoTween tween )
{
// first fetch all the current tweens with the same target object as this one
var allTweensWithTarget = tweensWithTarget( tween.target );
// store a list of all the properties in the tween
var allProperties = tween.allTweenProperties();
// TODO: perhaps only perform the check on running Tweens?
// loop through all the tweens with the same target
foreach( var tweenWithTarget in allTweensWithTarget )
{
// loop through all the properties in the tween and see if there are any dupes
foreach( var tweenProp in allProperties )
{
warn( "found duplicate TweenProperty {0} in tween {1}", tweenProp, tween );
// check for a matched property
if( tweenWithTarget.containsTweenProperty( tweenProp ) )
{
// handle the different duplicate property rules
if( duplicatePropertyRule == GoDuplicatePropertyRuleType.DontAddCurrentProperty )
{
return true;
}
else if( duplicatePropertyRule == GoDuplicatePropertyRuleType.RemoveRunningProperty )
{
// TODO: perhaps check if the Tween has any properties left and remove it if it doesnt?
tweenWithTarget.removeTweenProperty( tweenProp );
}
return false;
}
}
}
return false;
}
#region Logging
/// <summary>
/// logging should only occur in the editor so we use a conditional
/// </summary>
[System.Diagnostics.Conditional( "UNITY_EDITOR" )]
private static void log( object format, params object[] paramList )
{
if( format is string )
Debug.Log( string.Format( format as string, paramList ) );
else
Debug.Log( format );
}
[System.Diagnostics.Conditional( "UNITY_EDITOR" )]
public static void warn( object format, params object[] paramList )
{
if( logLevel == GoLogLevel.None || logLevel == GoLogLevel.Info )
return;
if( format is string )
Debug.LogWarning( string.Format( format as string, paramList ) );
else
Debug.LogWarning( format );
}
[System.Diagnostics.Conditional( "UNITY_EDITOR" )]
public static void error( object format, params object[] paramList )
{
if( logLevel == GoLogLevel.None || logLevel == GoLogLevel.Info || logLevel == GoLogLevel.Warn )
return;
if( format is string )
Debug.LogError( string.Format( format as string, paramList ) );
else
Debug.LogError( format );
}
#endregion
#region public API
/// <summary>
/// helper function that creates a "to" Tween and adds it to the pool
/// </summary>
public static GoTween to( object target, float duration, GoTweenConfig config )
{
config.setIsTo();
var tween = new GoTween( target, duration, config );
addTween( tween );
return tween;
}
/// <summary>
/// helper function that creates a "from" Tween and adds it to the pool
/// </summary>
public static GoTween from( object target, float duration, GoTweenConfig config )
{
config.setIsFrom();
var tween = new GoTween( target, duration, config );
addTween( tween );
return tween;
}
/// <summary>
/// adds an AbstractTween (Tween, TweenChain or TweenFlow) to the current list of running Tweens
/// </summary>
public static void addTween( AbstractGoTween tween )
{
// early out for invalid items
if( !tween.isValid() )
return;
// dont add the same tween twice
if( _tweens.Contains( tween ) )
return;
// check for dupes and handle them before adding the tween. we only need to check for Tweens
if( duplicatePropertyRule != GoDuplicatePropertyRuleType.None && tween is GoTween )
{
// if handleDuplicatePropertiesInTween returns true it indicates we should not add this tween
if( handleDuplicatePropertiesInTween( tween as GoTween ) )
return;
// if we became invalid after handling dupes dont add the tween
if( !tween.isValid() )
return;
}
_tweens.Add( tween );
// enable ourself if we are not enabled
if( !instance.enabled ) // purposely using the static instace property just once for initialization
_instance.enabled = true;
// if the Tween isn't paused and it is a "from" tween jump directly to the start position
if( tween is GoTween && ((GoTween)tween).isFrom && tween.state != GoTweenState.Paused )
tween.update( 0 );
// should we start up the time scale independent update?
if( !_instance._timeScaleIndependentUpdateIsRunning && tween.updateType == GoUpdateType.TimeScaleIndependentUpdate )
_instance.StartCoroutine( _instance.timeScaleIndependentUpdate() );
#if UNITY_EDITOR
_instance.gameObject.name = string.Format( "GoKit ({0} tweens)", _tweens.Count );
#endif
}
/// <summary>
/// removes the Tween returning true if it was removed or false if it was not found
/// </summary>
public static bool removeTween( AbstractGoTween tween )
{
if( _tweens.Contains( tween ) )
{
_tweens.Remove( tween );
#if UNITY_EDITOR
if( _instance != null && _tweens != null )
_instance.gameObject.name = string.Format( "GoKit ({0} tweens)", _tweens.Count );
#endif
if( _instance != null && _tweens.Count == 0 )
{
// disable ourself if we have no more tweens
_instance.enabled = false;
}
return true;
}
return false;
}
/// <summary>
/// returns a list of all Tweens, TweenChains and TweenFlows with the given id
/// </summary>
public static List<AbstractGoTween> tweensWithId( int id )
{
List<AbstractGoTween> list = null;
foreach( var tween in _tweens )
{
if( tween.id == id )
{
if( list == null )
list = new List<AbstractGoTween>();
list.Add( tween );
}
}
return list;
}
/// <summary>
/// returns a list of all Tweens with the given target. TweenChains and TweenFlows can optionally
/// be traversed and matching Tweens returned as well.
/// </summary>
public static List<GoTween> tweensWithTarget( object target, bool traverseCollections = false )
{
List<GoTween> list = new List<GoTween>();
foreach( var item in _tweens )
{
// we always check Tweens so handle them first
var tween = item as GoTween;
if( tween != null && tween.target == target )
list.Add( tween );
// optionally check TweenChains and TweenFlows. if tween is null we have a collection
if( traverseCollections && tween == null )
{
var tweenCollection = item as AbstractGoTweenCollection;
if( tweenCollection != null )
{
var tweensInCollection = tweenCollection.tweensWithTarget( target );
if( tweensInCollection.Count > 0 )
list.AddRange( tweensInCollection );
}
}
}
return list;
}
/// <summary>
/// kills all tweens with the given target by calling the destroy method on each one
/// </summary>
public static void killAllTweensWithTarget( object target )
{
foreach( var tween in tweensWithTarget( target, true ) )
tween.destroy();
}
#endregion
}

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: aabcf1780fb4540bbb12fde714c3f88a
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,31 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
/// <summary>
/// place this script on any GameObject to enable route editing. note that it is not required at runtime! it is
/// only required to be in your scene while editing a path
/// </summary>
public class GoDummyPath : MonoBehaviour
{
public string pathName = string.Empty;
public Color pathColor = Color.magenta; // color of the path if visible in the editor
public List<Vector3> nodes = new List<Vector3>() { Vector3.zero, Vector3.zero };
public bool useStandardHandles = false;
public bool forceStraightLinePath = false;
public int pathResolution = 50;
public void OnDrawGizmos()
{
// the editor will draw paths when force straight line is on
if( !forceStraightLinePath )
{
var spline = new GoSpline( nodes );
Gizmos.color = pathColor;
spline.drawGizmos( pathResolution );
}
}
}

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 25af92ea012eb4667a9c36cc4a72a725
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,341 @@
using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
public class GoTween : AbstractGoTween
{
// Tween specific properties
public object target { get; private set; } // the target of the tweens
public float delay { get; private set; } // delay before starting the actual animations
private float _elapsedDelay; // total time delayed
private bool _delayComplete; // once we complete the delay this gets set so we can reverse and play properly for the future
public bool isFrom { get; private set; } // a value of true will make this a "from" tween
private List<AbstractTweenProperty> _tweenPropertyList = new List<AbstractTweenProperty>();
private string targetTypeString;
/// <summary>
/// sets the ease type for all Tweens. this will overwrite the ease types for each Tween!
/// </summary>
private GoEaseType _easeType;
public GoEaseType easeType
{
get
{
return _easeType;
}
set
{
_easeType = value;
// change ease type of all existing tweens.
foreach( var tween in _tweenPropertyList )
tween.setEaseType( value );
}
}
/// <summary>
/// initializes a new instance and sets up the details according to the config parameter
/// </summary>
public GoTween( object target, float duration, GoTweenConfig config, Action<AbstractGoTween> onComplete = null )
{
// default to removing on complete
autoRemoveOnComplete = true;
// allow events by default
allowEvents = true;
// setup callback bools
_didInit = false;
_didBegin = false;
// flag the onIterationStart event to fire.
// as long as goTo is not called on this tween, the onIterationStart event will fire
// as soon as the delay, if any, is completed.
_fireIterationStart = true;
this.target = target;
this.targetTypeString = target.GetType().ToString();
this.duration = duration;
// copy the TweenConfig info over
id = config.id;
delay = config.delay;
loopType = config.loopType;
iterations = config.iterations;
_easeType = config.easeType;
updateType = config.propertyUpdateType;
isFrom = config.isFrom;
timeScale = config.timeScale;
_onInit = config.onInitHandler;
_onBegin = config.onBeginHandler;
_onIterationStart = config.onIterationStartHandler;
_onUpdate = config.onUpdateHandler;
_onIterationEnd = config.onIterationEndHandler;
_onComplete = config.onCompleteHandler;
if( config.isPaused )
state = GoTweenState.Paused;
// if onComplete is passed to the constructor it wins. it is left as the final param to allow an inline Action to be
// set and maintain clean code (Actions always try to be the last param of a method)
if( onComplete != null )
_onComplete = onComplete;
// add all our properties
for( var i = 0; i < config.tweenProperties.Count; ++i )
{
var tweenProp = config.tweenProperties[i];
// if the tween property is initialized already it means it is being reused so we need to clone it
if( tweenProp.isInitialized )
tweenProp = tweenProp.clone();
addTweenProperty( tweenProp );
}
// calculate total duration
if( iterations < 0 )
totalDuration = float.PositiveInfinity;
else
totalDuration = iterations * duration;
}
/// <summary>
/// tick method. if it returns true it indicates the tween is complete
/// </summary>
public override bool update( float deltaTime )
{
// properties are prepared only once on the first update of the tween.
if ( !_didInit )
onInit();
// should we validate the target?
if( Go.validateTargetObjectsEachTick )
{
// This might seem to be overkill, but on the case of Transforms that
// have been destroyed, target == null will return false, whereas
// target.Equals(null) will return true. Otherwise we don't really
// get the benefits of the nanny.
if( target == null || target.Equals(null) )
{
// if the target doesn't pass validation
Debug.LogWarning( "target validation failed. destroying the tween to avoid errors. Target type: " + this.targetTypeString );
autoRemoveOnComplete = true;
return true;
}
}
// we only fire the begin callback once per run.
if ( !_didBegin )
onBegin();
// handle delay and return if we are still delaying
if( !_delayComplete && _elapsedDelay < delay )
{
// if we have a timeScale set we need to remove its influence so that delays are always in seconds
if( timeScale != 0 )
_elapsedDelay += deltaTime / timeScale;
// are we done delaying?
if( _elapsedDelay >= delay )
_delayComplete = true;
return false;
}
// loops only start once the delay has completed.
if ( _fireIterationStart )
onIterationStart();
// base will calculate the proper elapsedTime, iterations, etc.
base.update( deltaTime );
// if we are looping back on a PingPong loop
var convertedElapsedTime = _isLoopingBackOnPingPong ? duration - _elapsedTime : _elapsedTime;
//Debug.Log(string.Format("{0} : {1} -- {2}", _elapsedTime, convertedElapsedTime, _isLoopingBackOnPingPong ? "Y" : "N"));
// update all properties
for( var i = 0; i < _tweenPropertyList.Count; ++i )
_tweenPropertyList[i].tick( convertedElapsedTime );
onUpdate();
if ( _fireIterationEnd )
onIterationEnd();
if( state == GoTweenState.Complete )
{
onComplete();
return true; // true if complete
}
return false; // false if not complete
}
/// <summary>
/// we are valid if we have a target and at least one TweenProperty
/// </summary>
public override bool isValid()
{
return target != null;
}
/// <summary>
/// adds the tween property if it passes validation and initializes the property
/// </summary>
public void addTweenProperty( AbstractTweenProperty tweenProp )
{
// make sure the target is valid for this tween before adding
if( tweenProp.validateTarget( target ) )
{
// ensure we dont add two tweens of the same property so they dont fight
if( _tweenPropertyList.Contains( tweenProp ) )
{
Debug.Log( "not adding tween property because one already exists: " + tweenProp );
return;
}
_tweenPropertyList.Add( tweenProp );
tweenProp.init( this );
}
else
{
Debug.Log( "tween failed to validate target: " + tweenProp );
}
}
public override bool removeTweenProperty( AbstractTweenProperty property )
{
if( _tweenPropertyList.Contains( property ) )
{
_tweenPropertyList.Remove( property );
return true;
}
return false;
}
public override bool containsTweenProperty( AbstractTweenProperty property )
{
return _tweenPropertyList.Contains( property );
}
public void clearTweenProperties()
{
_tweenPropertyList.Clear();
}
public override List<AbstractTweenProperty> allTweenProperties()
{
return _tweenPropertyList;
}
#region AbstractTween overrides
/// <summary>
/// called only once the first update of a tween.
/// </summary>
protected override void onInit()
{
base.onInit();
for ( var i = 0; i < _tweenPropertyList.Count; ++i )
_tweenPropertyList[i].prepareForUse();
}
/// <summary>
/// removes the tween and cleans up its state
/// </summary>
public override void destroy()
{
base.destroy();
_tweenPropertyList.Clear();
target = null;
}
/// <summary>
/// goes to the specified time clamping it from 0 to the total duration of the tween. if the tween is
/// not playing it will be force updated to the time specified.
/// </summary>
public override void goTo( float time , bool skipDelay = true )
{
// handle delay, which is specific to Tweens
if( skipDelay )
{
_elapsedDelay = delay;
}
else
{
_elapsedDelay = Mathf.Min( time, delay );
time -= _elapsedDelay;
}
_delayComplete = _elapsedDelay >= delay;
time = Mathf.Clamp( time, 0f, totalDuration );
// provide an early out for calling goto on the same time multiple times.
if ( time == _totalElapsedTime )
return;
// if we are doing a goTo at the "start" of the timeline, based on the isReversed variable,
// allow the onBegin and onIterationStart callback to fire again.
// we only allow the onIterationStart event callback to fire at the start of the timeline,
// as doing a goTo(x) where x % duration == 0 will trigger the onIterationEnd before we
// go to the start.
if ( ( isReversed && time == totalDuration ) || ( !isReversed && time == 0f ) )
{
_didBegin = false;
_fireIterationStart = true;
}
else
{
_didBegin = true;
_fireIterationStart = false;
}
// since we're doing a goTo, we want to stop this tween from remembering that it iterated.
// this could cause issues if you caused the tween to complete an iteration and then goTo somewhere
// else while still paused.
_didIterateThisFrame = false;
// force a time and completedIterations before we update
_totalElapsedTime = time;
_completedIterations = isReversed ? Mathf.CeilToInt( _totalElapsedTime / duration ) : Mathf.FloorToInt( _totalElapsedTime / duration );
update( 0 );
}
/// <summary>
/// completes the tween. sets the object to it's final position as if the tween completed normally.
/// takes into effect if the tween was playing forward or reversed.
/// </summary>
public override void complete()
{
if( iterations < 0 )
return;
// set delayComplete so we get one last update in before we die (base will set the elapsed time for us)
_delayComplete = true;
base.complete();
}
#endregion
}

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: a5e29433d2fb8417c9b59ce3453f2ca3
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,147 @@
using UnityEngine;
using System.Collections;
public class GoTweenChain : AbstractGoTweenCollection
{
public GoTweenChain() : this(new GoTweenCollectionConfig()) {}
public GoTweenChain(GoTweenCollectionConfig config) : base(config) {}
#region internal Chain management
private void append( TweenFlowItem item )
{
// early out for invalid items
if( item.tween != null && !item.tween.isValid() )
return;
if( float.IsInfinity( item.duration ) )
{
Debug.LogError( "adding a Tween with infinite iterations to a TweenChain is not permitted" );
return;
}
if ( item.tween != null )
{
if ( item.tween.isReversed != isReversed )
{
Debug.LogError( "adding a Tween that doesn't match the isReversed property of the TweenChain is not permitted." );
return;
}
// ensure the tween isnt already live
Go.removeTween(item.tween);
// ensure that the item is marked to play.
item.tween.play();
}
_tweenFlows.Add( item );
// update the duration and total duration
duration += item.duration;
if( iterations < 0 )
totalDuration = float.PositiveInfinity;
else
totalDuration = duration * iterations;
}
private void prepend( TweenFlowItem item )
{
// early out for invalid items
if( item.tween != null && !item.tween.isValid() )
return;
if( float.IsInfinity( item.duration ) )
{
Debug.LogError( "adding a Tween with infinite iterations to a TweenChain is not permitted" );
return;
}
if ( item.tween != null )
{
if ( item.tween.isReversed != isReversed )
{
Debug.LogError( "adding a Tween that doesn't match the isReversed property of the TweenChain is not permitted." );
return;
}
// ensure the tween isnt already live
Go.removeTween( item.tween );
// ensure that the item is marked to play.
item.tween.play();
}
// fix all the start times on our previous chains
foreach( var flowItem in _tweenFlows )
flowItem.startTime += item.duration;
_tweenFlows.Insert( 0, item );
// update the duration and total duration
duration += item.duration;
if ( iterations < 0 )
totalDuration = float.PositiveInfinity;
else
totalDuration = duration * iterations;
}
#endregion
#region Chain management
/// <summary>
/// appends a Tween at the end of the current flow
/// </summary>
public GoTweenChain append( AbstractGoTween tween )
{
var item = new TweenFlowItem( duration, tween );
append( item );
return this;
}
/// <summary>
/// appends a delay to the end of the current flow
/// </summary>
public GoTweenChain appendDelay( float delay )
{
var item = new TweenFlowItem( duration, delay );
append( item );
return this;
}
/// <summary>
/// adds a Tween to the front of the flow
/// </summary>
public GoTweenChain prepend( AbstractGoTween tween )
{
var item = new TweenFlowItem( 0, tween );
prepend( item );
return this;
}
/// <summary>
/// adds a delay to the front of the flow
/// </summary>
public GoTweenChain prependDelay( float delay )
{
var item = new TweenFlowItem( 0, delay );
prepend( item );
return this;
}
#endregion
}

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: e4985888b83c04c04b428c6b4d0e9e13
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,122 @@
using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
public class GoTweenCollectionConfig
{
public int id; // id for finding the Tween at a later time. multiple Tweens can have the same id
public int iterations = 1; // number of times to iterate. -1 will loop indefinitely
public GoLoopType loopType = Go.defaultLoopType;
public GoUpdateType propertyUpdateType = Go.defaultUpdateType;
public Action<AbstractGoTween> onInitHandler;
public Action<AbstractGoTween> onBeginHandler;
public Action<AbstractGoTween> onIterationStartHandler;
public Action<AbstractGoTween> onUpdateHandler;
public Action<AbstractGoTween> onIterationEndHandler;
public Action<AbstractGoTween> onCompleteHandler;
/// <summary>
/// sets the number of iterations. setting to -1 will loop infinitely
/// </summary>
public GoTweenCollectionConfig setIterations( int iterations )
{
this.iterations = iterations;
return this;
}
/// <summary>
/// sets the number of iterations and the loop type. setting to -1 will loop infinitely
/// </summary>
public GoTweenCollectionConfig setIterations( int iterations, GoLoopType loopType )
{
this.iterations = iterations;
this.loopType = loopType;
return this;
}
/// <summary>
/// sets the update type for the Tween
/// </summary>
public GoTweenCollectionConfig setUpdateType( GoUpdateType setUpdateType )
{
this.propertyUpdateType = setUpdateType;
return this;
}
/// <summary>
/// sets the onInit handler for the Tween
/// </summary>
public GoTweenCollectionConfig onInit( Action<AbstractGoTween> onInit )
{
onInitHandler = onInit;
return this;
}
/// <summary>
/// sets the onBegin handler for the Tween
/// </summary>
public GoTweenCollectionConfig onBegin( Action<AbstractGoTween> onBegin )
{
onBeginHandler = onBegin;
return this;
}
/// <summary>
/// sets the onIterationStart handler for the Tween
/// </summary>
public GoTweenCollectionConfig onIterationStart( Action<AbstractGoTween> onIterationStart )
{
onIterationStartHandler = onIterationStart;
return this;
}
/// <summary>
/// sets the onUpdate handler for the Tween
/// </summary>
public GoTweenCollectionConfig onUpdate( Action<AbstractGoTween> onUpdate )
{
onUpdateHandler = onUpdate;
return this;
}
/// <summary>
/// sets the onIterationEnd handler for the Tween
/// </summary>
public GoTweenCollectionConfig onIterationEnd( Action<AbstractGoTween> onIterationEnd )
{
onIterationEndHandler = onIterationEnd;
return this;
}
/// <summary>
/// sets the onComplete handler for the Tween
/// </summary>
public GoTweenCollectionConfig onComplete( Action<AbstractGoTween> onComplete )
{
onCompleteHandler = onComplete;
return this;
}
/// <summary>
/// sets the id for the Tween. Multiple Tweens can have the same id and you can retrieve them with the Go class
/// </summary>
public GoTweenCollectionConfig setId( int id )
{
this.id = id;
return this;
}
}

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 04126d38111de41799edaa161b80b0b4
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,533 @@
using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
public class GoTweenConfig
{
private List<AbstractTweenProperty> _tweenProperties = new List<AbstractTweenProperty>();
public List<AbstractTweenProperty> tweenProperties { get { return _tweenProperties; } }
public int id; // id for finding the Tween at a later time. multiple Tweens can have the same id
public float delay; // how long should we delay before starting the Tween
public int iterations = 1; // number of times to iterate. -1 will loop indefinitely
public int timeScale = 1;
public GoLoopType loopType = Go.defaultLoopType;
public GoEaseType easeType = Go.defaultEaseType;
public bool isPaused;
public GoUpdateType propertyUpdateType = Go.defaultUpdateType;
public bool isFrom;
public Action<AbstractGoTween> onInitHandler;
public Action<AbstractGoTween> onBeginHandler;
public Action<AbstractGoTween> onIterationStartHandler;
public Action<AbstractGoTween> onUpdateHandler;
public Action<AbstractGoTween> onIterationEndHandler;
public Action<AbstractGoTween> onCompleteHandler;
#region TweenProperty adders
/// <summary>
/// position tween
/// </summary>
public GoTweenConfig position( Vector3 endValue, bool isRelative = false )
{
var prop = new PositionTweenProperty( endValue, isRelative );
_tweenProperties.Add( prop );
return this;
}
/// <summary>
/// localPosition tween
/// </summary>
public GoTweenConfig localPosition( Vector3 endValue, bool isRelative = false )
{
var prop = new PositionTweenProperty( endValue, isRelative, true );
_tweenProperties.Add( prop );
return this;
}
/// <summary>
/// position path tween
/// </summary>
public GoTweenConfig positionPath( GoSpline path, bool isRelative = false, GoLookAtType lookAtType = GoLookAtType.None, Transform lookTarget = null )
{
var prop = new PositionPathTweenProperty( path, isRelative, false, lookAtType, lookTarget );
_tweenProperties.Add( prop );
return this;
}
/// <summary>
/// uniform scale tween (x, y and z scale to the same value)
/// </summary>
public GoTweenConfig scale( float endValue, bool isRelative = false )
{
return this.scale( new Vector3( endValue, endValue, endValue ), isRelative );
}
/// <summary>
/// scale tween
/// </summary>
public GoTweenConfig scale( Vector3 endValue, bool isRelative = false )
{
var prop = new ScaleTweenProperty( endValue, isRelative );
_tweenProperties.Add( prop );
return this;
}
/// <summary>
/// scale through a series of Vector3s
/// </summary>
public GoTweenConfig scalePath( GoSpline path, bool isRelative = false )
{
var prop = new ScalePathTweenProperty( path, isRelative );
_tweenProperties.Add( prop );
return this;
}
/// <summary>
/// eulerAngle tween
/// </summary>
public GoTweenConfig eulerAngles( Vector3 endValue, bool isRelative = false )
{
var prop = new EulerAnglesTweenProperty( endValue, isRelative );
_tweenProperties.Add( prop );
return this;
}
/// <summary>
/// local eulerAngle tween
/// </summary>
public GoTweenConfig localEulerAngles( Vector3 endValue, bool isRelative = false )
{
var prop = new EulerAnglesTweenProperty( endValue, isRelative, true );
_tweenProperties.Add( prop );
return this;
}
/// <summary>
/// rotation tween
/// </summary>
public GoTweenConfig rotation( Vector3 endValue, bool isRelative = false )
{
var prop = new RotationTweenProperty( endValue, isRelative );
_tweenProperties.Add( prop );
return this;
}
/// <summary>
/// localRotation tween
/// </summary>
public GoTweenConfig localRotation( Vector3 endValue, bool isRelative = false )
{
var prop = new RotationTweenProperty( endValue, isRelative, true );
_tweenProperties.Add( prop );
return this;
}
/// <summary>
/// rotation tween as Quaternion
/// </summary>
public GoTweenConfig rotation( Quaternion endValue, bool isRelative = false )
{
var prop = new RotationQuaternionTweenProperty( endValue, isRelative );
_tweenProperties.Add( prop );
return this;
}
/// <summary>
/// localRotation tween as Quaternion
/// </summary>
public GoTweenConfig localRotation( Quaternion endValue, bool isRelative = false )
{
var prop = new RotationQuaternionTweenProperty( endValue, isRelative, true );
_tweenProperties.Add( prop );
return this;
}
/// <summary>
/// material color tween
/// </summary>
public GoTweenConfig materialColor( Color endValue, string colorName = "_Color", bool isRelative = false )
{
var prop = new MaterialColorTweenProperty( endValue, colorName, isRelative );
_tweenProperties.Add( prop );
return this;
}
/// <summary>
/// shake tween
/// </summary>
public GoTweenConfig shake( Vector3 shakeMagnitude, GoShakeType shakeType = GoShakeType.Position, int frameMod = 1, bool useLocalProperties = false )
{
var prop = new ShakeTweenProperty( shakeMagnitude, shakeType, frameMod, useLocalProperties );
_tweenProperties.Add( prop );
return this;
}
#region generic properties
/// <summary>
/// generic vector2 tween
/// </summary>
public GoTweenConfig vector2Prop( string propertyName, Vector2 endValue, bool isRelative = false )
{
var prop = new Vector2TweenProperty( propertyName, endValue, isRelative );
_tweenProperties.Add( prop );
return this;
}
/// <summary>
/// generic vector3 tween
/// </summary>
public GoTweenConfig vector3Prop( string propertyName, Vector3 endValue, bool isRelative = false )
{
var prop = new Vector3TweenProperty( propertyName, endValue, isRelative );
_tweenProperties.Add( prop );
return this;
}
/// <summary>
/// generic vector4 tween
/// </summary>
public GoTweenConfig vector4Prop( string propertyName, Vector4 endValue, bool isRelative = false )
{
var prop = new Vector4TweenProperty( propertyName, endValue, isRelative );
_tweenProperties.Add( prop );
return this;
}
/// <summary>
/// generic vector3 path tween
/// </summary>
public GoTweenConfig vector3PathProp( string propertyName, GoSpline path, bool isRelative = false )
{
var prop = new Vector3PathTweenProperty( propertyName, path, isRelative );
_tweenProperties.Add( prop );
return this;
}
/// <summary>
/// generic vector3.x tween
/// </summary>
public GoTweenConfig vector3XProp( string propertyName, float endValue, bool isRelative = false )
{
var prop = new Vector3XTweenProperty( propertyName, endValue, isRelative );
_tweenProperties.Add( prop );
return this;
}
/// <summary>
/// generic vector3.y tween
/// </summary>
public GoTweenConfig vector3YProp( string propertyName, float endValue, bool isRelative = false )
{
var prop = new Vector3YTweenProperty( propertyName, endValue, isRelative );
_tweenProperties.Add( prop );
return this;
}
/// <summary>
/// generic vector3.z tween
/// </summary>
public GoTweenConfig vector3ZProp( string propertyName, float endValue, bool isRelative = false )
{
var prop = new Vector3ZTweenProperty( propertyName, endValue, isRelative );
_tweenProperties.Add( prop );
return this;
}
/// <summary>
/// generic color tween
/// </summary>
public GoTweenConfig colorProp( string propertyName, Color endValue, bool isRelative = false )
{
var prop = new ColorTweenProperty( propertyName, endValue, isRelative );
_tweenProperties.Add( prop );
return this;
}
/// <summary>
/// generic integer tween
/// </summary>
public GoTweenConfig intProp( string propertyName, int endValue, bool isRelative = false )
{
var prop = new IntTweenProperty( propertyName, endValue, isRelative );
_tweenProperties.Add( prop );
return this;
}
/// <summary>
/// generic float tween
/// </summary>
public GoTweenConfig floatProp( string propertyName, float endValue, bool isRelative = false )
{
var prop = new FloatTweenProperty( propertyName, endValue, isRelative );
_tweenProperties.Add( prop );
return this;
}
#endregion
#endregion
/// <summary>
/// adds a TweenProperty to the list
/// </summary>
public GoTweenConfig addTweenProperty( AbstractTweenProperty tweenProp )
{
_tweenProperties.Add( tweenProp );
return this;
}
/// <summary>
/// clears out all the TweenProperties
/// </summary>
public GoTweenConfig clearProperties()
{
_tweenProperties.Clear();
return this;
}
/// <summary>
/// clears out all the TweenProperties
/// </summary>
public GoTweenConfig clearEvents()
{
onInitHandler = null;
onBeginHandler = null;
onIterationStartHandler = null;
onUpdateHandler = null;
onIterationEndHandler = null;
onCompleteHandler = null;
return this;
}
/// <summary>
/// sets the delay for the tween
/// </summary>
public GoTweenConfig setDelay( float seconds )
{
delay = seconds;
return this;
}
/// <summary>
/// sets the number of iterations. setting to -1 will loop infinitely
/// </summary>
public GoTweenConfig setIterations( int iterations )
{
this.iterations = iterations;
return this;
}
/// <summary>
/// sets the number of iterations and the loop type. setting to -1 will loop infinitely
/// </summary>
public GoTweenConfig setIterations( int iterations, GoLoopType loopType )
{
this.iterations = iterations;
this.loopType = loopType;
return this;
}
/// <summary>
/// sets the timeScale to be used by the Tween
/// </summary>
public GoTweenConfig setTimeScale( int timeScale )
{
this.timeScale = timeScale;
return this;
}
/// <summary>
/// sets the ease type for the Tween
/// </summary>
public GoTweenConfig setEaseType( GoEaseType easeType )
{
this.easeType = easeType;
return this;
}
/// <summary>
/// sets whether the Tween should start paused
/// </summary>
public GoTweenConfig startPaused()
{
isPaused = true;
return this;
}
/// <summary>
/// sets the update type for the Tween
/// </summary>
public GoTweenConfig setUpdateType( GoUpdateType setUpdateType )
{
propertyUpdateType = setUpdateType;
return this;
}
/// <summary>
/// sets if this Tween should be a "from" Tween. From Tweens use the current property as the endValue and
/// the endValue as the start value
/// </summary>
public GoTweenConfig setIsFrom()
{
isFrom = true;
return this;
}
/// <summary>
/// sets if this Tween should be a "to" Tween.
/// </summary>
public GoTweenConfig setIsTo()
{
isFrom = false;
return this;
}
/// <summary>
/// sets the onInit handler for the Tween
/// </summary>
public GoTweenConfig onInit( Action<AbstractGoTween> onInit )
{
onInitHandler = onInit;
return this;
}
/// <summary>
/// sets the onBegin handler for the Tween
/// </summary>
public GoTweenConfig onBegin( Action<AbstractGoTween> onBegin )
{
onBeginHandler = onBegin;
return this;
}
/// <summary>
/// sets the onIterationStart handler for the Tween
/// </summary>
public GoTweenConfig onIterationStart( Action<AbstractGoTween> onIterationStart )
{
onIterationStartHandler = onIterationStart;
return this;
}
/// <summary>
/// sets the onUpdate handler for the Tween
/// </summary>
public GoTweenConfig onUpdate( Action<AbstractGoTween> onUpdate )
{
onUpdateHandler = onUpdate;
return this;
}
/// <summary>
/// sets the onIterationEnd handler for the Tween
/// </summary>
public GoTweenConfig onIterationEnd( Action<AbstractGoTween> onIterationEnd )
{
onIterationEndHandler = onIterationEnd;
return this;
}
/// <summary>
/// sets the onComplete handler for the Tween
/// </summary>
public GoTweenConfig onComplete( Action<AbstractGoTween> onComplete )
{
onCompleteHandler = onComplete;
return this;
}
/// <summary>
/// sets the id for the Tween. Multiple Tweens can have the same id and you can retrieve them with the Go class
/// </summary>
public GoTweenConfig setId( int id )
{
this.id = id;
return this;
}
}

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 110c83c73e3544e7785938ec38e5361e
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,83 @@
using UnityEngine;
using System.Collections;
/// <summary>
/// TweenFlows are used for creating a chain of Tweens via the append/prepend methods. You can also get timeline
/// like control by inserting Tweens and setting them to start at a specific time. Note that TweenFlows do not
/// honor the delays set within regular Tweens. Use the append/prependDelay method to add any required delays
/// </summary>
public class GoTweenFlow : AbstractGoTweenCollection
{
public GoTweenFlow() : this( new GoTweenCollectionConfig() ) {}
public GoTweenFlow( GoTweenCollectionConfig config ) : base( config ) {}
#region internal Flow management
/// <summary>
/// the item being added already has a start time so no extra parameter is needed
/// </summary>
private void insert( TweenFlowItem item )
{
// early out for invalid items
if( item.tween != null && !item.tween.isValid() )
return;
if( float.IsInfinity( item.duration ) )
{
Debug.LogError( "adding a Tween with infinite iterations to a TweenFlow is not permitted" );
return;
}
if( item.tween != null )
{
if (item.tween.isReversed != isReversed)
{
Debug.LogError( "adding a Tween that doesn't match the isReversed property of the TweenFlow is not permitted." );
return;
}
// ensure the tween isnt already live
Go.removeTween(item.tween);
// ensure that the item is marked to play.
item.tween.play();
}
// add the item then sort based on startTimes
_tweenFlows.Add( item );
_tweenFlows.Sort( ( x, y ) =>
{
return x.startTime.CompareTo( y.startTime );
} );
duration = Mathf.Max( item.startTime + item.duration, duration );
if (iterations < 0)
totalDuration = float.PositiveInfinity;
else
totalDuration = duration * iterations;
}
#endregion
#region Flow management
/// <summary>
/// inserts a Tween and sets it to start at the given startTime
/// </summary>
public GoTweenFlow insert( float startTime, AbstractGoTween tween )
{
var item = new TweenFlowItem( startTime, tween );
insert( item );
return this;
}
#endregion
}

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: fc32096ae2bba43da839e42c553f294c
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 0a0650221f37549c4988877fdaa5e4bb
folderAsset: yes
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,445 @@
using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
/// <summary>
/// base class shared by the Tween and TweenChain classes to allow a seemless API when controlling
/// either of them
/// </summary>
public abstract class AbstractGoTween
{
public int id = 0; // optional id used for identifying this tween
public GoTweenState state { get; protected set; } // current state of the tween
public float duration { get; protected set; } // duration for a single loop
public float totalDuration { get; protected set; } // duration for all loops of this tween
public float timeScale { get; set; } // time scale to be used by this tween
public GoUpdateType updateType { get; protected set; }
public GoLoopType loopType { get; protected set; }
public int iterations { get; protected set; } // set to -1 for infinite
public bool autoRemoveOnComplete { get; set; } // should we automatically remove ourself from the Go's list of tweens when done?
public bool isReversed { get; protected set; } // have we been reversed? this is different than a PingPong loop's backwards section
public bool allowEvents { get; set; } // allow the user to surpress events.
protected bool _didInit; // flag to ensure event only gets fired once
protected bool _didBegin; // flag to ensure event only gets fired once
protected bool _fireIterationStart;
protected bool _fireIterationEnd;
// internal state for update logic
protected float _elapsedTime; // elapsed time for the current loop iteration
protected float _totalElapsedTime; // total elapsed time of the entire tween
public float totalElapsedTime { get { return _totalElapsedTime; } }
protected bool _isLoopingBackOnPingPong;
public bool isLoopingBackOnPingPong { get { return _isLoopingBackOnPingPong; } }
protected bool _didIterateLastFrame;
protected bool _didIterateThisFrame;
protected int _deltaIterations; // change in completed iterations this frame.
protected int _completedIterations;
public int completedIterations { get { return _completedIterations; } }
// action event handlers
protected Action<AbstractGoTween> _onInit; // executes before initial setup.
protected Action<AbstractGoTween> _onBegin; // executes when a tween starts.
protected Action<AbstractGoTween> _onIterationStart; // executes whenever a tween starts an iteration.
protected Action<AbstractGoTween> _onUpdate; // execute whenever a tween updates.
protected Action<AbstractGoTween> _onIterationEnd; // executes whenever a tween ends an iteration.
protected Action<AbstractGoTween> _onComplete; // exectures whenever a tween completes
public void setOnInitHandler( Action<AbstractGoTween> onInit )
{
_onInit = onInit;
}
public void setOnBeginHandler( Action<AbstractGoTween> onBegin )
{
_onBegin = onBegin;
}
public void setonIterationStartHandler( Action<AbstractGoTween> onIterationStart )
{
_onIterationStart = onIterationStart;
}
public void setOnUpdateHandler( Action<AbstractGoTween> onUpdate )
{
_onUpdate = onUpdate;
}
public void setonIterationEndHandler( Action<AbstractGoTween> onIterationEnd )
{
_onIterationEnd = onIterationEnd;
}
public void setOnCompleteHandler( Action<AbstractGoTween> onComplete )
{
_onComplete = onComplete;
}
/// <summary>
/// called once per tween when it is first updated
/// </summary>
protected virtual void onInit()
{
if( !allowEvents )
return;
if( _onInit != null )
_onInit( this );
_didInit = true;
}
/// <summary>
/// called whenever the tween is updated and the playhead is at the start (or end, depending on isReversed) of the tween.
/// </summary>
protected virtual void onBegin()
{
if( !allowEvents )
return;
if( isReversed && _totalElapsedTime != totalDuration )
return;
else if( !isReversed && _totalElapsedTime != 0f )
return;
if( _onBegin != null )
_onBegin( this );
_didBegin = true;
}
/// <summary>
/// called once per iteration at the start of the iteration.
/// </summary>
protected virtual void onIterationStart()
{
if( !allowEvents )
return;
if( _onIterationStart != null )
_onIterationStart( this );
}
/// <summary>
/// called once per update, after the update has occured.
/// </summary>
protected virtual void onUpdate()
{
if( !allowEvents )
return;
if( _onUpdate != null )
_onUpdate( this );
}
/// <summary>
/// called once per iteration at the end of the iteration.
/// </summary>
protected virtual void onIterationEnd()
{
if( !allowEvents )
return;
if( _onIterationEnd != null )
_onIterationEnd( this );
}
/// <summary>
/// called when the tween completes playing.
/// </summary>
protected virtual void onComplete()
{
if( !allowEvents )
return;
if( _onComplete != null )
_onComplete( this );
}
/// <summary>
/// tick method. if it returns true it indicates the tween is complete.
/// note: at it's base, AbstractGoTween does not fire events, it is up to the implementer to
/// do so. see GoTween and AbstractGoTweenCollection for examples.
/// </summary>
public virtual bool update( float deltaTime )
{
// increment or decrement the total elapsed time then clamp from 0 to totalDuration
if( isReversed )
_totalElapsedTime -= deltaTime;
else
_totalElapsedTime += deltaTime;
_totalElapsedTime = Mathf.Clamp( _totalElapsedTime, 0, totalDuration );
_didIterateLastFrame = _didIterateThisFrame || ( !isReversed && _totalElapsedTime == 0 ) || ( isReversed && _totalElapsedTime == totalDuration );
// we flip between ceil and floor based on the direction, because we want the iteration change
// to happen when "duration" seconds has elapsed, not immediately, as was the case if you
// were doing a floor and were going in reverse.
if( isReversed )
_deltaIterations = Mathf.CeilToInt( _totalElapsedTime / duration ) - _completedIterations;
else
_deltaIterations = Mathf.FloorToInt( _totalElapsedTime / duration ) - _completedIterations;
// we iterated this frame if we have done a goTo() to an iteration point, or we've passed over
// an iteration threshold.
_didIterateThisFrame = !_didIterateLastFrame && ( _deltaIterations != 0f || _totalElapsedTime % duration == 0f );
_completedIterations += _deltaIterations;
// set the elapsedTime, given what we know.
if( _didIterateLastFrame )
{
_elapsedTime = isReversed ? duration : 0f;
}
else if( _didIterateThisFrame )
{
// if we iterated this frame, we force the _elapsedTime to the end of the timeline.
_elapsedTime = isReversed ? 0f : duration;
}
else
{
_elapsedTime = _totalElapsedTime % duration;
// if you do a goTo(x) where x is a multiple of duration, we assume that you want
// to be at the end of your duration, as this sets you up to have an automatic OnIterationStart fire
// the next updated frame. the only caveat is when you do a goTo(0) when playing forwards,
// or a goTo(totalDuration) when playing in reverse. we assume that at that point, you want to be
// at the start of your tween.
if( _elapsedTime == 0f && ( ( isReversed && _totalElapsedTime == totalDuration ) || ( !isReversed && _totalElapsedTime > 0f ) ) )
{
_elapsedTime = duration;
}
}
// we can only be looping back on a PingPong if our loopType is PingPong and we are on an odd numbered iteration
_isLoopingBackOnPingPong = false;
if( loopType == GoLoopType.PingPong )
{
// due to the way that we count iterations, and force a tween to remain at the end
// of it's timeline for one frame after passing the duration threshold,
// we need to make sure that _isLoopingBackOnPingPong references the current
// iteration, and not the next one.
if( isReversed )
{
_isLoopingBackOnPingPong = _completedIterations % 2 == 0;
if( _elapsedTime == 0f )
_isLoopingBackOnPingPong = !_isLoopingBackOnPingPong;
}
else
{
_isLoopingBackOnPingPong = _completedIterations % 2 != 0;
if( _elapsedTime == duration )
_isLoopingBackOnPingPong = !_isLoopingBackOnPingPong;
}
}
// set a flag whether to fire the onIterationEnd event or not.
_fireIterationStart = _didIterateThisFrame || ( !isReversed && _elapsedTime == duration ) || ( isReversed && _elapsedTime == 0f );
_fireIterationEnd = _didIterateThisFrame;
// check for completion
if( ( !isReversed && iterations >= 0 && _completedIterations >= iterations ) || ( isReversed && _totalElapsedTime <= 0 ) )
state = GoTweenState.Complete;
if( state == GoTweenState.Complete )
{
// these variables need to be reset here. if a tween were to complete,
// and then get played again:
// * The onIterationStart event would get fired
// * tweens would flip their elapsedTime between 0 and totalDuration
_fireIterationStart = false;
_didIterateThisFrame = false;
return true; // true if complete
}
return false; // false if not complete
}
/// <summary>
/// subclasses should return true if they are a valid and ready to be added to the list of running tweens
/// or false if not ready.
/// technically, this should be marked as internal
/// </summary>
public abstract bool isValid();
/// <summary>
/// attempts to remove the tween property returning true if successful
/// technically, this should be marked as internal
/// </summary>
public abstract bool removeTweenProperty( AbstractTweenProperty property );
/// <summary>
/// returns true if the tween contains the same type (or propertyName) property in its property list
/// technically, this should be marked as internal
/// </summary>
public abstract bool containsTweenProperty( AbstractTweenProperty property );
/// <summary>
/// returns a list of all the TweenProperties contained in the tween and all its children (if it is
/// a TweenChain or a TweenFlow)
/// technically, this should be marked as internal
/// </summary>
public abstract List<AbstractTweenProperty> allTweenProperties();
/// <summary>
/// removes the Tween from action and cleans up its state
/// </summary>
public virtual void destroy()
{
state = GoTweenState.Destroyed;
}
/// <summary>
/// pauses playback
/// </summary>
public virtual void pause()
{
state = GoTweenState.Paused;
}
/// <summary>
/// resumes playback
/// </summary>
public virtual void play()
{
state = GoTweenState.Running;
}
/// <summary>
/// plays the tween forward. if it is already playing forward has no effect
/// </summary>
public void playForward()
{
if( isReversed )
reverse();
play();
}
/// <summary>
/// plays the tween backwards. if it is already playing backwards has no effect
/// </summary>
public void playBackwards()
{
if( !isReversed )
reverse();
play();
}
/// <summary>
/// resets the tween to the beginning, taking isReversed into account.
/// </summary>
protected virtual void reset( bool skipDelay = true )
{
goTo( isReversed ? totalDuration : 0, skipDelay );
_fireIterationStart = true;
}
/// <summary>
/// rewinds the tween to the beginning (or end, depending on isReversed) and pauses playback.
/// </summary>
public virtual void rewind( bool skipDelay = true )
{
reset( skipDelay );
pause();
}
/// <summary>
/// rewinds the tween to the beginning (or end, depending on isReversed) and starts playback,
/// optionally skipping delay (only relevant for Tweens).
/// </summary>
public void restart( bool skipDelay = true )
{
reset( skipDelay );
play();
}
/// <summary>
/// reverses playback. if going forward it will be going backward after this and vice versa.
/// </summary>
public virtual void reverse()
{
isReversed = !isReversed;
_completedIterations = isReversed ? Mathf.CeilToInt( _totalElapsedTime / duration ) : Mathf.FloorToInt( _totalElapsedTime / duration );
// if we are at the "start" of the timeline, based on isReversed,
// allow the onBegin/onIterationStart callbacks to fire again.
if( ( isReversed && _totalElapsedTime == totalDuration ) || ( !isReversed && _totalElapsedTime == 0f ) )
{
_didBegin = false;
_fireIterationStart = true;
}
}
/// <summary>
/// completes the tween. sets the playhead to it's final position as if the tween completed normally.
/// takes into account if the tween was playing forward or reversed.
/// </summary>
public virtual void complete()
{
if( iterations < 0 )
return;
// set full elapsed time and let the next iteration finish it off
goTo( isReversed ? 0 : totalDuration, true );
}
/// <summary>
/// goes to the specified time clamping it from 0 to the total duration of the tween. if the tween is
/// not playing it can optionally be force updated to the time specified. delays are not taken into effect.
/// (must be implemented by inherited classes.)
/// </summary>
public abstract void goTo( float time, bool skipDelay = true );
/// <summary>
/// goes to the time and starts playback skipping any delays
/// </summary>
public void goToAndPlay( float time, bool skipDelay = true )
{
goTo( time, skipDelay );
play();
}
/// <summary>
/// waits for either completion or destruction. call in a Coroutine and yield on the return
/// </summary>
public IEnumerator waitForCompletion()
{
while( state != GoTweenState.Complete && state != GoTweenState.Destroyed )
yield return null;
yield break;
}
}

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: d8eb47665d5434148a4bd7391644861a
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,500 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
/// <summary>
/// base class for TweenChains and TweenFlows
/// </summary>
public class AbstractGoTweenCollection : AbstractGoTween
{
protected List<TweenFlowItem> _tweenFlows = new List<TweenFlowItem>();
/// <summary>
/// data class that wraps an AbstractTween and its start time for the timeline
/// </summary>
protected class TweenFlowItem
{
public float startTime;
public float endTime { get { return startTime + duration; } }
public float duration;
public AbstractGoTween tween;
public TweenFlowItem( float startTime, AbstractGoTween tween )
{
this.tween = tween;
this.startTime = startTime;
this.duration = tween.totalDuration;
}
public TweenFlowItem( float startTime, float duration )
{
this.duration = duration;
this.startTime = startTime;
}
}
public AbstractGoTweenCollection( GoTweenCollectionConfig config )
{
// allow events by default
allowEvents = true;
// setup callback bools
_didInit = false;
_didBegin = false;
// flag the onIterationStart event to fire.
// as long as goTo is not called on this tween, the onIterationStart event will fire
_fireIterationStart = true;
// copy the TweenConfig info over
id = config.id;
loopType = config.loopType;
iterations = config.iterations;
updateType = config.propertyUpdateType;
timeScale = 1;
state = GoTweenState.Paused;
_onInit = config.onInitHandler;
_onBegin = config.onBeginHandler;
_onIterationStart = config.onIterationStartHandler;
_onUpdate = config.onUpdateHandler;
_onIterationEnd = config.onIterationEndHandler;
_onComplete = config.onCompleteHandler;
Go.addTween( this );
}
#region AbstractTween overrides
/// <summary>
/// returns a list of all Tweens with the given target in the collection
/// technically, this should be marked as internal
/// </summary>
public List<GoTween> tweensWithTarget( object target )
{
List<GoTween> list = new List<GoTween>();
foreach( var flowItem in _tweenFlows )
{
// skip TweenFlowItems with no target
if( flowItem.tween == null )
continue;
// check Tweens first
var tween = flowItem.tween as GoTween;
if( tween != null && tween.target == target )
list.Add( tween );
// check for TweenCollections
if( tween == null )
{
var tweenCollection = flowItem.tween as AbstractGoTweenCollection;
if( tweenCollection != null )
{
var tweensInCollection = tweenCollection.tweensWithTarget( target );
if( tweensInCollection.Count > 0 )
list.AddRange( tweensInCollection );
}
}
}
return list;
}
public override bool removeTweenProperty( AbstractTweenProperty property )
{
foreach( var flowItem in _tweenFlows )
{
// skip delay items which have no tween
if( flowItem.tween == null )
continue;
if( flowItem.tween.removeTweenProperty( property ) )
return true;
}
return false;
}
public override bool containsTweenProperty( AbstractTweenProperty property )
{
foreach( var flowItem in _tweenFlows )
{
// skip delay items which have no tween
if( flowItem.tween == null )
continue;
if( flowItem.tween.containsTweenProperty( property ) )
return true;
}
return false;
}
public override List<AbstractTweenProperty> allTweenProperties()
{
var propList = new List<AbstractTweenProperty>();
foreach( var flowItem in _tweenFlows )
{
// skip delay items which have no tween
if( flowItem.tween == null )
continue;
propList.AddRange( flowItem.tween.allTweenProperties() );
}
return propList;
}
/// <summary>
/// we are always considered valid because our constructor adds us to Go and we start paused
/// </summary>
public override bool isValid()
{
return true;
}
/// <summary>
/// resumes playback
/// </summary>
public override void play()
{
base.play();
foreach( var flowItem in _tweenFlows )
{
if( flowItem.tween != null )
flowItem.tween.play();
}
}
/// <summary>
/// pauses playback
/// </summary>
public override void pause()
{
base.pause();
foreach( var flowItem in _tweenFlows )
{
if( flowItem.tween != null )
flowItem.tween.pause();
}
}
/// <summary>
/// tick method. if it returns true it indicates the tween is complete
/// </summary>
public override bool update( float deltaTime )
{
if ( !_didInit )
onInit();
if ( !_didBegin )
onBegin();
if ( _fireIterationStart )
onIterationStart();
// update the timeline and state.
base.update( deltaTime );
// get the proper elapsedTime if we're doing a PingPong
var convertedElapsedTime = _isLoopingBackOnPingPong ? duration - _elapsedTime : _elapsedTime;
// used for iterating over flowItems below.
TweenFlowItem flowItem = null;
// if we iterated last frame and this flow restarts from the beginning, we now need to reset all
// of the flowItem tweens to either the beginning or the end of their respective timelines
// we also want to do this in the _opposite_ way that we would normally iterate on them
// as the start value of a later flowItem may alter a property of an earlier flowItem.
if ( _didIterateLastFrame && loopType == GoLoopType.RestartFromBeginning )
{
if ( isReversed || _isLoopingBackOnPingPong )
{
for ( int i = 0; i < _tweenFlows.Count; ++i )
{
flowItem = _tweenFlows[i];
if ( flowItem.tween == null )
continue;
var cacheAllow = flowItem.tween.allowEvents;
flowItem.tween.allowEvents = false;
flowItem.tween.restart();
flowItem.tween.allowEvents = cacheAllow;
}
}
else
{
for ( int i = _tweenFlows.Count - 1; i >= 0; --i )
{
flowItem = _tweenFlows[i];
if ( flowItem.tween == null )
continue;
var cacheAllow = flowItem.tween.allowEvents;
flowItem.tween.allowEvents = false;
flowItem.tween.restart();
flowItem.tween.allowEvents = cacheAllow;
}
}
}
else
{
if ( ( isReversed && !_isLoopingBackOnPingPong ) || ( !isReversed && _isLoopingBackOnPingPong ) )
{
// if we are moving the tween in reverse, we should be iterating over the flowItems in reverse
// to help properties behave a bit better.
for ( var i = _tweenFlows.Count - 1; i >= 0; --i )
{
flowItem = _tweenFlows[i];
if ( flowItem.tween == null )
continue;
// if there's been an iteration this frame and we're not done yet, we want to make sure
// this tween is set to play in the right direction, and isn't set to complete/paused.
if ( _didIterateLastFrame && state != GoTweenState.Complete )
{
if ( !flowItem.tween.isReversed )
flowItem.tween.reverse();
flowItem.tween.play();
}
if ( flowItem.tween.state == GoTweenState.Running && flowItem.endTime >= convertedElapsedTime )
{
var convertedDeltaTime = Mathf.Abs( convertedElapsedTime - flowItem.startTime - flowItem.tween.totalElapsedTime );
flowItem.tween.update( convertedDeltaTime );
}
}
}
else
{
for ( int i = 0; i < _tweenFlows.Count; ++i )
{
flowItem = _tweenFlows[i];
if ( flowItem.tween == null )
continue;
// if there's been an iteration this frame and we're not done yet, we want to make sure
// this tween is set to play in the right direction, and isn't set to complete/paused.
if ( _didIterateLastFrame && state != GoTweenState.Complete )
{
if ( flowItem.tween.isReversed )
flowItem.tween.reverse();
flowItem.tween.play();
}
if ( flowItem.tween.state == GoTweenState.Running && flowItem.startTime <= convertedElapsedTime )
{
var convertedDeltaTime = convertedElapsedTime - flowItem.startTime - flowItem.tween.totalElapsedTime;
flowItem.tween.update( convertedDeltaTime );
}
}
}
}
onUpdate();
if ( _fireIterationEnd )
onIterationEnd();
if ( state == GoTweenState.Complete )
{
onComplete();
return true; // true if complete
}
return false; // false if not complete
}
/// <summary>
/// reverses playback. if going forward it will be going backward after this and vice versa.
/// </summary>
public override void reverse()
{
base.reverse();
var convertedElapsedTime = _isLoopingBackOnPingPong ? duration - _elapsedTime : _elapsedTime;
foreach ( var flowItem in _tweenFlows )
{
if ( flowItem.tween == null )
continue;
if ( isReversed != flowItem.tween.isReversed )
flowItem.tween.reverse();
flowItem.tween.pause();
// we selectively mark tweens for play if they will be played immediately or in the future.
// update() will filter out more tweens that should not be played yet.
if ( isReversed || _isLoopingBackOnPingPong )
{
if ( flowItem.startTime <= convertedElapsedTime )
flowItem.tween.play();
}
else
{
if ( flowItem.endTime >= convertedElapsedTime )
flowItem.tween.play();
}
}
}
/// <summary>
/// goes to the specified time clamping it from 0 to the total duration of the tween. if the tween is
/// not playing it will be force updated to the time specified.
/// </summary>
public override void goTo( float time, bool skipDelay = true )
{
time = Mathf.Clamp( time, 0f, totalDuration );
// provide an early out for calling goTo on the same time multiple times.
if ( time == _totalElapsedTime )
return;
// we don't simply call base.goTo because that would force an update within AbstractGoTweenCollection,
// which forces an update on all the tweenFlowItems without putting them in the right position.
// it's also possible that people will move around a tween via the goTo method, so we want to
// try to make that as efficient as possible.
// if we are doing a goTo at the "start" of the timeline, based on the isReversed variable,
// allow the onBegin and onIterationStart callback to fire again.
// we only allow the onIterationStart event callback to fire at the start of the timeline,
// as doing a goTo(x) where x % duration == 0 will trigger the onIterationEnd before we
// go to the start.
if ( ( isReversed && time == totalDuration ) || ( !isReversed && time == 0f ) )
{
_didBegin = false;
_fireIterationStart = true;
}
else
{
_didBegin = true;
_fireIterationStart = false;
}
// since we're doing a goTo, we want to stop this tween from remembering that it iterated.
// this could cause issues if you caused the tween to complete an iteration and then goTo somewhere
// else while still paused.
_didIterateThisFrame = false;
// force a time and completedIterations before we update
_totalElapsedTime = time;
_completedIterations = isReversed ? Mathf.CeilToInt( _totalElapsedTime / duration ) : Mathf.FloorToInt( _totalElapsedTime / duration );
// we don't want to use the Collection update function, because we don't have all of our
// child tweenFlowItems setup properly. this will properly setup our iterations,
// totalElapsedTime, and other useful information.
base.update( 0 );
var convertedElapsedTime = _isLoopingBackOnPingPong ? duration - _elapsedTime : _elapsedTime;
// we always want to process items in the future of this tween from last to first.
// and items that have already occured from first to last.
TweenFlowItem flowItem = null;
if ( isReversed || _isLoopingBackOnPingPong )
{
// flowItems in the future of the timeline
for ( int i = 0; i < _tweenFlows.Count; ++i )
{
flowItem = _tweenFlows[i];
if ( flowItem == null )
continue;
if ( flowItem.endTime >= convertedElapsedTime )
break;
changeTimeForFlowItem( flowItem, convertedElapsedTime );
}
// flowItems in the past & current part of the timeline
for ( int i = _tweenFlows.Count - 1; i >= 0; --i )
{
flowItem = _tweenFlows[i];
if ( flowItem == null )
continue;
if ( flowItem.endTime < convertedElapsedTime )
break;
changeTimeForFlowItem( flowItem, convertedElapsedTime );
}
}
else
{
// flowItems in the future of the timeline
for ( int i = _tweenFlows.Count - 1; i >= 0; --i )
{
flowItem = _tweenFlows[i];
if ( flowItem == null )
continue;
if ( flowItem.startTime <= convertedElapsedTime )
break;
changeTimeForFlowItem( flowItem, convertedElapsedTime );
}
// flowItems in the past & current part of the timeline
for ( int i = 0; i < _tweenFlows.Count; ++i )
{
flowItem = _tweenFlows[i];
if ( flowItem == null )
continue;
if ( flowItem.startTime > convertedElapsedTime )
break;
changeTimeForFlowItem( flowItem, convertedElapsedTime );
}
}
}
private void changeTimeForFlowItem( TweenFlowItem flowItem, float time )
{
if ( flowItem == null || flowItem.tween == null )
return;
if ( flowItem.tween.isReversed != ( isReversed || _isLoopingBackOnPingPong ) )
flowItem.tween.reverse();
var convertedTime = Mathf.Clamp( time - flowItem.startTime, 0f, flowItem.endTime );
if ( flowItem.startTime <= time && flowItem.endTime >= time )
{
flowItem.tween.goToAndPlay( convertedTime );
}
else
{
flowItem.tween.goTo( convertedTime );
flowItem.tween.pause();
}
}
#endregion
}

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: c011ef2561dca4c2492fdbf1b78d96a8
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 34b16834b4ced4d9a9b03c6d00303ad5
folderAsset: yes
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,25 @@
public static class GoEaseBack
{
public static float EaseIn( float t, float b, float c, float d )
{
return c * ( t /= d ) * t * ( ( 1.70158f + 1 ) * t - 1.70158f ) + b;
}
public static float EaseOut( float t, float b, float c, float d )
{
return c * ( ( t = t / d - 1 ) * t * ( ( 1.70158f + 1 ) * t + 1.70158f ) + 1 ) + b;
}
public static float EaseInOut( float t, float b, float c, float d )
{
float s = 1.70158f;
if( ( t /= d / 2 ) < 1 )
{
return c / 2 * ( t * t * ( ( ( s *= ( 1.525f ) ) + 1 ) * t - s ) ) + b;
}
return c / 2 * ( ( t -= 2 ) * t * ( ( ( s *= ( 1.525f ) ) + 1 ) * t + s ) + 2 ) + b;
}
}

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: e44fd25dcb7704da0a39cfe042b81293
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,35 @@
public static class GoEaseBounce
{
public static float EaseOut( float t, float b, float c, float d )
{
if( ( t /= d ) < ( 1 / 2.75 ) )
{
return c * ( 7.5625f * t * t ) + b;
}
else if( t < ( 2 / 2.75 ) )
{
return c * ( 7.5625f * ( t -= ( 1.5f / 2.75f ) ) * t + .75f ) + b;
}
else if( t < ( 2.5 / 2.75 ) )
{
return c * ( 7.5625f * ( t -= ( 2.25f / 2.75f ) ) * t + .9375f ) + b;
}
else
{
return c * ( 7.5625f * ( t -= ( 2.625f / 2.75f ) ) * t + .984375f ) + b;
}
}
public static float EaseIn( float t, float b, float c, float d )
{
return c - EaseOut( d - t, 0, c, d ) + b;
}
public static float EaseInOut( float t, float b, float c, float d )
{
if( t < d / 2 )
return EaseIn( t * 2, 0, c, d ) * 0.5f + b;
else
return EaseOut( t * 2 - d, 0, c, d ) * .5f + c * 0.5f + b;
}
}

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 95777a3e9f3304c5f87d79f0035e7cce
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,24 @@
using System;
public static class GoEaseCircular
{
public static float EaseIn( float t, float b, float c, float d )
{
return -c * ( (float)Math.Sqrt( 1 - ( t /= d ) * t ) - 1 ) + b;
}
public static float EaseOut( float t, float b, float c, float d )
{
return c * (float)Math.Sqrt( 1 - ( t = t / d - 1 ) * t ) + b;
}
public static float EaseInOut( float t, float b, float c, float d )
{
if( ( t /= d / 2 ) < 1 )
{
return -c / 2 * ( (float)Math.Sqrt( 1 - t * t ) - 1 ) + b;
}
return c / 2 * ( (float)Math.Sqrt( 1 - ( t -= 2 ) * t ) + 1 ) + b;
}
}

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 1b7f811e7d59a41bf99d08c646d1725b
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,21 @@
public static class GoEaseCubic
{
public static float EaseIn( float t, float b, float c, float d )
{
return c * ( t /= d ) * t * t + b;
}
public static float EaseOut( float t, float b, float c, float d )
{
return c * ( ( t = t / d - 1 ) * t * t + 1 ) + b;
}
public static float EaseInOut( float t, float b, float c, float d )
{
if( ( t /= d / 2 ) < 1 )
{
return c / 2 * t * t * t + b;
}
return c / 2 * ( ( t -= 2 ) * t * t + 2 ) + b;
}
}

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 7210f854113854752bdff44a9b562d42
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,68 @@
using System;
using UnityEngine;
public class GoEaseElastic
{
public static float EaseIn( float t, float b, float c, float d )
{
if( t == 0 )
{
return b;
}
if( ( t /= d ) == 1 )
{
return b + c;
}
float p = d * .3f;
float s = p / 4;
return -(float)( c * Math.Pow( 2, 10 * ( t -= 1 ) ) * Math.Sin( ( t * d - s ) * ( 2 * Math.PI ) / p ) ) + b;
}
public static float EaseOut( float t, float b, float c, float d )
{
if( t == 0 )
{
return b;
}
if( ( t /= d ) == 1 )
{
return b + c;
}
float p = d * .3f;
float s = p / 4;
return (float)( c * Math.Pow( 2, -10 * t ) * Math.Sin( ( t * d - s ) * ( 2 * Math.PI ) / p ) + c + b );
}
public static float EaseInOut( float t, float b, float c, float d )
{
if( t == 0 )
{
return b;
}
if( ( t /= d / 2 ) == 2 )
{
return b + c;
}
float p = d * ( .3f * 1.5f );
float a = c;
float s = p / 4;
if( t < 1 )
{
return -.5f * (float)( a * Math.Pow( 2, 10 * ( t -= 1 ) ) * Math.Sin( ( t * d - s ) * ( 2 * Math.PI ) / p ) ) + b;
}
return (float)( a * Math.Pow( 2, -10 * ( t -= 1 ) ) * Math.Sin( ( t * d - s ) * ( 2 * Math.PI ) / p ) * .5 + c + b );
}
public static float Punch( float t, float b, float c, float d )
{
if( t == 0 )
return 0;
if( ( t /= d ) == 1 )
return 0;
const float p = 0.3f;
return ( c * Mathf.Pow( 2, -10 * t ) * Mathf.Sin( t * ( 2 * Mathf.PI ) / p ) );
}
}

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 2c183f70ddaf54b6caa706e2d7a15837
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,32 @@
using System;
public static class GoEaseExponential
{
public static float EaseIn( float t, float b, float c, float d )
{
return ( t == 0 ) ? b : c * (float)Math.Pow( 2, 10 * ( t / d - 1 ) ) + b;
}
public static float EaseOut( float t, float b, float c, float d )
{
return ( t == d ) ? b + c : c * (float)( -Math.Pow( 2, -10 * t / d ) + 1 ) + b;
}
public static float EaseInOut( float t, float b, float c, float d )
{
if( t == 0 )
{
return b;
}
if( t == d )
{
return b + c;
}
if( ( t /= d / 2 ) < 1 )
{
return c / 2 * (float)Math.Pow( 2, 10 * ( t - 1 ) ) + b;
}
return c / 2 * (float)( -Math.Pow( 2, -10 * --t ) + 2 ) + b;
}
}

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 9db2ed7f90d404641b604f6db1368fcc
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,10 @@
using UnityEngine;
public static class GoEaseLinear
{
public static float EaseNone( float t, float b, float c, float d )
{
return c * t / d + b;
}
}

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: d2f840d866998449683cf9b8a34c0b8f
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,21 @@
public static class GoEaseQuadratic
{
public static float EaseIn( float t, float b, float c, float d )
{
return c * ( t /= d ) * t + b;
}
public static float EaseOut( float t, float b, float c, float d )
{
return -c * ( t /= d ) * ( t - 2 ) + b;
}
public static float EaseInOut( float t, float b, float c, float d )
{
if( ( t /= d / 2 ) < 1 )
{
return c / 2 * t * t + b;
}
return -c / 2 * ( ( --t ) * ( t - 2 ) - 1 ) + b;
}
}

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 94e247c3236114f678e9ffffa07bfe09
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,21 @@
public static class GoEaseQuartic
{
public static float EaseIn( float t, float b, float c, float d )
{
return c * ( t /= d ) * t * t * t + b;
}
public static float EaseOut( float t, float b, float c, float d )
{
return -c * ( ( t = t / d - 1 ) * t * t * t - 1 ) + b;
}
public static float EaseInOut( float t, float b, float c, float d )
{
if( ( t /= d / 2 ) < 1 )
{
return c / 2 * t * t * t * t + b;
}
return -c / 2 * ( ( t -= 2 ) * t * t * t - 2 ) + b;
}
}

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 178a095287feb40b3b2fb42327529cf3
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,21 @@
public static class GoEaseQuintic
{
public static float EaseIn( float t, float b, float c, float d )
{
return c * ( t /= d ) * t * t * t * t + b;
}
public static float EaseOut( float t, float b, float c, float d )
{
return c * ( ( t = t / d - 1 ) * t * t * t * t + 1 ) + b;
}
public static float EaseInOut( float t, float b, float c, float d )
{
if( ( t /= d / 2 ) < 1 )
{
return c / 2 * t * t * t * t * t + b;
}
return c / 2 * ( ( t -= 2 ) * t * t * t * t + 2 ) + b;
}
}

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: ec4a9f5d98bf04114b5a015db1308a60
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,21 @@
using System;
using UnityEngine;
public static class GoEaseSinusoidal
{
public static float EaseIn( float t, float b, float c, float d )
{
return -c * (float)Math.Cos( t / d * ( Math.PI / 2 ) ) + c + b;
}
public static float EaseOut( float t, float b, float c, float d )
{
return c * (float)Math.Sin( t / d * ( Math.PI / 2 ) ) + b;
}
public static float EaseInOut( float t, float b, float c, float d )
{
return -c / 2 * ( (float)Math.Cos( Math.PI * t / d ) - 1 ) + b;
}
}

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 5fa97311d39f04b93b833ca28fac10ae
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,33 @@
/*
Microsoft Public License (Ms-PL)
This license governs use of the accompanying software. If you use the software, you accept this license. If you do not accept the license, do not use the software.
1. Definitions
The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under U.S. copyright law.
A "contribution" is the original software, or any additions or changes to the software.
A "contributor" is any person that distributes its contribution under this license.
"Licensed patents" are a contributor's patent claims that read directly on its contribution.
2. Grant of Rights
(A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create.
(B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software.
3. Conditions and Limitations
(A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks.
(B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically.
(C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software.
(D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license.
(E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement.
*/

View File

@ -0,0 +1,6 @@
fileFormatVersion: 2
guid: 098d0b0599d2b4fcc8c8f24379e8bf90
TextScriptImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 3fdf9641baedb40338ca9a110aa99706
folderAsset: yes
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,15 @@
using UnityEngine;
using System.Collections;
/// <summary>
/// defines what should be done in the event that a TweenProperty is being added to Go when an existing TweenProperty
/// of the same type with the same target object is already present
/// </summary>
public enum GoDuplicatePropertyRuleType
{
None, // dont bother checking or doing anything
RemoveRunningProperty, // removes the property from the Tween that was already running
DontAddCurrentProperty // leaves the original property intact and doesnt add the current property
}

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 7107639cda4a541a79a05bd60caf35c8
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,50 @@
using UnityEngine;
using System.Collections;
public enum GoEaseType
{
Linear,
SineIn,
SineOut,
SineInOut,
QuadIn,
QuadOut,
QuadInOut,
CubicIn,
CubicOut,
CubicInOut,
QuartIn,
QuartOut,
QuartInOut,
QuintIn,
QuintOut,
QuintInOut,
ExpoIn,
ExpoOut,
ExpoInOut,
CircIn,
CircOut,
CircInOut,
ElasticIn,
ElasticOut,
ElasticInOut,
Punch,
BackIn,
BackOut,
BackInOut,
BounceIn,
BounceOut,
BounceInOut
}

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: e53d7306407a34ceaa133d772fa1ec3b
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,11 @@
using UnityEngine;
using System.Collections;
public enum GoLogLevel
{
None,
Info,
Warn,
Error
}

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 95f2b1a5decae452784d0c332801c1d1
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,13 @@
using UnityEngine;
using System.Collections;
/// <summary>
/// used by paths to identify what the object being tweened should look at
/// </summary>
public enum GoLookAtType
{
None,
NextPathNode,
TargetTransform
}

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 08691283d482e4054b037fc5d4030e48
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,10 @@
using UnityEngine;
using System.Collections;
public enum GoLoopType
{
RestartFromBeginning,
PingPong
}

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 8820e9c24b06041b8ab4157ec84b5f86
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,11 @@
using UnityEngine;
using System.Collections;
[System.Flags]
public enum GoShakeType
{
Position = ( 1 << 0 ),
Scale = ( 1 << 1 ),
Eulers = ( 1 << 2 )
}

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 83c69d81ac63f4b789dd05ab1f326517
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,11 @@
using UnityEngine;
using System.Collections;
public enum GoSplineType
{
StraightLine, // 2 points
QuadraticBezier, // 3 points
CubicBezier, // 4 points
CatmullRom // 5+ points
}

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 3b24cf23dec3f4db7869ebfde6112be9
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,11 @@
using UnityEngine;
using System.Collections;
public enum GoTweenState
{
Running,
Paused,
Complete,
Destroyed
}

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: de15fdc9763ed4873b7021c616d7952d
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,11 @@
using UnityEngine;
using System.Collections;
public enum GoUpdateType
{
Update,
LateUpdate,
FixedUpdate,
TimeScaleIndependentUpdate
}

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 634c22f604be24212ae1f75ddec523f9
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: cb14c988d1865428599a6a5bc46a79e5
folderAsset: yes
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,124 @@
using UnityEngine;
using System.Collections;
public static class GoKitTweenExtensions
{
#region Transform extensions
// to tweens
public static GoTween rotationTo( this Transform self, float duration, Vector3 endValue, bool isRelative = false )
{
return Go.to( self, duration, new GoTweenConfig().rotation( endValue, isRelative ) );
}
public static GoTween localRotationTo( this Transform self, float duration, Vector3 endValue, bool isRelative = false )
{
return Go.to( self, duration, new GoTweenConfig().localRotation( endValue, isRelative ) );
}
public static GoTween eulerAnglesTo( this Transform self, float duration, Vector3 endValue, bool isRelative = false )
{
return Go.to( self, duration, new GoTweenConfig().eulerAngles( endValue, isRelative ) );
}
public static GoTween localEulerAnglesTo( this Transform self, float duration, Vector3 endValue, bool isRelative = false )
{
return Go.to( self, duration, new GoTweenConfig().localEulerAngles( endValue, isRelative ) );
}
public static GoTween positionTo( this Transform self, float duration, Vector3 endValue, bool isRelative = false )
{
return Go.to( self, duration, new GoTweenConfig().position( endValue, isRelative ) );
}
public static GoTween localPositionTo( this Transform self, float duration, Vector3 endValue, bool isRelative = false )
{
return Go.to( self, duration, new GoTweenConfig().localPosition( endValue, isRelative ) );
}
public static GoTween scaleTo( this Transform self, float duration, float endValue, bool isRelative = false )
{
return self.scaleTo( duration, new Vector3( endValue, endValue, endValue ), isRelative );
}
public static GoTween scaleTo( this Transform self, float duration, Vector3 endValue, bool isRelative = false )
{
return Go.to( self, duration, new GoTweenConfig().scale( endValue, isRelative ) );
}
public static GoTween shake( this Transform self, float duration, Vector3 shakeMagnitude, GoShakeType shakeType = GoShakeType.Position, int frameMod = 1, bool useLocalProperties = false )
{
return Go.to( self, duration, new GoTweenConfig().shake( shakeMagnitude, shakeType, frameMod, useLocalProperties ) );
}
// from tweens
public static GoTween rotationFrom( this Transform self, float duration, Vector3 endValue, bool isRelative = false )
{
return Go.from( self, duration, new GoTweenConfig().rotation( endValue, isRelative ) );
}
public static GoTween localRotationFrom( this Transform self, float duration, Vector3 endValue, bool isRelative = false )
{
return Go.from( self, duration, new GoTweenConfig().localRotation( endValue, isRelative ) );
}
public static GoTween eulerAnglesFrom( this Transform self, float duration, Vector3 endValue, bool isRelative = false )
{
return Go.from( self, duration, new GoTweenConfig().eulerAngles( endValue, isRelative ) );
}
public static GoTween localEulerAnglesFrom( this Transform self, float duration, Vector3 endValue, bool isRelative = false )
{
return Go.from( self, duration, new GoTweenConfig().localEulerAngles( endValue, isRelative ) );
}
public static GoTween positionFrom( this Transform self, float duration, Vector3 endValue, bool isRelative = false )
{
return Go.from( self, duration, new GoTweenConfig().position( endValue, isRelative ) );
}
public static GoTween localPositionFrom( this Transform self, float duration, Vector3 endValue, bool isRelative = false )
{
return Go.from( self, duration, new GoTweenConfig().localPosition( endValue, isRelative ) );
}
public static GoTween scaleFrom( this Transform self, float duration, Vector3 endValue, bool isRelative = false )
{
return Go.from( self, duration, new GoTweenConfig().scale( endValue, isRelative ) );
}
#endregion
#region Material extensions
public static GoTween colorTo( this Material self, float duration, Color endValue, string colorName = "_Color" )
{
return Go.to( self, duration, new GoTweenConfig().materialColor( endValue, colorName ) );
}
public static GoTween colorFrom( this Material self, float duration, Color endValue, string colorName = "_Color" )
{
return Go.from( self, duration, new GoTweenConfig().materialColor( endValue, colorName ) );
}
#endregion
}

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 21ffa6d37448541bead4c009180436bd
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 4204282772fc1408da934f8775d6da4f
folderAsset: yes
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,236 @@
using UnityEngine;
using System;
using System.Collections;
using System.Reflection;
public static class GoTweenUtils
{
/// <summary>
/// fetches the actual function for the given ease type
/// </summary>
public static Func<float,float,float,float,float> easeFunctionForType( GoEaseType easeType )
{
switch( easeType )
{
case GoEaseType.Linear:
return GoEaseLinear.EaseNone;
case GoEaseType.BackIn:
return GoEaseBack.EaseIn;
case GoEaseType.BackOut:
return GoEaseBack.EaseOut;
case GoEaseType.BackInOut:
return GoEaseBack.EaseInOut;
case GoEaseType.BounceIn:
return GoEaseBounce.EaseIn;
case GoEaseType.BounceOut:
return GoEaseBounce.EaseOut;
case GoEaseType.BounceInOut:
return GoEaseBounce.EaseInOut;
case GoEaseType.CircIn:
return GoEaseCircular.EaseIn;
case GoEaseType.CircOut:
return GoEaseCircular.EaseOut;
case GoEaseType.CircInOut:
return GoEaseCircular.EaseInOut;
case GoEaseType.CubicIn:
return GoEaseCubic.EaseIn;
case GoEaseType.CubicOut:
return GoEaseCubic.EaseOut;
case GoEaseType.CubicInOut:
return GoEaseCubic.EaseInOut;
case GoEaseType.ElasticIn:
return GoEaseElastic.EaseIn;
case GoEaseType.ElasticOut:
return GoEaseElastic.EaseOut;
case GoEaseType.ElasticInOut:
return GoEaseElastic.EaseInOut;
case GoEaseType.Punch:
return GoEaseElastic.Punch;
case GoEaseType.ExpoIn:
return GoEaseExponential.EaseIn;
case GoEaseType.ExpoOut:
return GoEaseExponential.EaseOut;
case GoEaseType.ExpoInOut:
return GoEaseExponential.EaseInOut;
case GoEaseType.QuadIn:
return GoEaseQuadratic.EaseIn;
case GoEaseType.QuadOut:
return GoEaseQuadratic.EaseOut;
case GoEaseType.QuadInOut:
return GoEaseQuadratic.EaseInOut;
case GoEaseType.QuartIn:
return GoEaseQuartic.EaseIn;
case GoEaseType.QuartOut:
return GoEaseQuartic.EaseOut;
case GoEaseType.QuartInOut:
return GoEaseQuartic.EaseInOut;
case GoEaseType.QuintIn:
return GoEaseQuintic.EaseIn;
case GoEaseType.QuintOut:
return GoEaseQuintic.EaseOut;
case GoEaseType.QuintInOut:
return GoEaseQuintic.EaseInOut;
case GoEaseType.SineIn:
return GoEaseSinusoidal.EaseIn;
case GoEaseType.SineOut:
return GoEaseSinusoidal.EaseOut;
case GoEaseType.SineInOut:
return GoEaseSinusoidal.EaseInOut;
}
return GoEaseLinear.EaseNone;
}
/// <summary>
/// either returns a super fast Delegate to set the given property or null if it couldn't be found
/// via reflection
/// </summary>
public static T setterForProperty<T>( System.Object targetObject, string propertyName )
{
// first get the property
#if NETFX_CORE
var propInfo = targetObject.GetType().GetRuntimeProperty( propertyName );
#else
var propInfo = targetObject.GetType().GetProperty( propertyName );
#endif
if( propInfo == null )
{
Debug.Log( "could not find property with name: " + propertyName );
return default( T );
}
#if NETFX_CORE
// Windows Phone/Store new API
return (T)(object)propInfo.SetMethod.CreateDelegate( typeof( T ), targetObject );
#else
return (T)(object)Delegate.CreateDelegate( typeof( T ), targetObject, propInfo.GetSetMethod() );
#endif
}
/// <summary>
/// either returns a super fast Delegate to get the given property or null if it couldn't be found
/// via reflection
/// </summary>
public static T getterForProperty<T>( System.Object targetObject, string propertyName )
{
// first get the property
#if NETFX_CORE
var propInfo = targetObject.GetType().GetRuntimeProperty( propertyName );
#else
var propInfo = targetObject.GetType().GetProperty( propertyName );
#endif
if( propInfo == null )
{
Debug.Log( "could not find property with name: " + propertyName );
return default( T );
}
#if NETFX_CORE
// Windows Phone/Store new API
return (T)(object)propInfo.GetMethod.CreateDelegate( typeof( T ), targetObject );
#else
return (T)(object)Delegate.CreateDelegate( typeof( T ), targetObject, propInfo.GetGetMethod() );
#endif
}
#region math functions
/// <summary>
/// note for all lerps: normally a lerp would be something like the following:
/// val1 + ( val2 - val1 ) * t
/// or in more familiar terms:
/// start + ( end - start ) * t
///
/// when lerping relatively, the formula simplifies to:
/// start + end * t
///
/// for all the unclamped lerps in this class the diff value is precalculated and cached. that means these arent like normal
/// lerps where you pass in the start and end values. the "diff" paramter in each method should be either the cached
/// ( end - start ) for non-relative tweens or just end for relative tweens (that are not "from" tweens)
/// </summary>
/// <summary>
/// unclamped lerp from c1 to c2. diff should be c2 - c1 (or just c2 for relative lerps)
/// </summary>
public static Color unclampedColorLerp( Color c1, Color diff, float value )
{
return new Color
(
c1.r + diff.r * value,
c1.g + diff.g * value,
c1.b + diff.b * value,
c1.a + diff.a * value
);
}
/// <summary>
/// unclamped lerp from v1 to v2. diff should be v2 - v1 (or just v2 for relative lerps)
/// </summary>
public static Vector2 unclampedVector2Lerp( Vector2 v1, Vector2 diff, float value )
{
return new Vector2
(
v1.x + diff.x * value,
v1.y + diff.y * value
);
}
/// <summary>
/// unclamped lerp from v1 to v2. diff should be v2 - v1 (or just v2 for relative lerps)
/// </summary>
public static Vector3 unclampedVector3Lerp( Vector3 v1, Vector3 diff, float value )
{
return new Vector3
(
v1.x + diff.x * value,
v1.y + diff.y * value,
v1.z + diff.z * value
);
/*
return new Vector3
(
v1.x + ( v2.x - v1.x ) * value,
v1.y + ( v2.y - v1.y ) * value,
v1.z + ( v2.z - v1.z ) * value
);
*/
}
/// <summary>
/// unclamped lerp from v1 to v2. diff should be v2 - v1 (or just v2 for relative lerps)
/// </summary>
public static Vector4 unclampedVector4Lerp( Vector4 v1, Vector4 diff, float value )
{
return new Vector4
(
v1.x + diff.x * value,
v1.y + diff.y * value,
v1.z + diff.z * value,
v1.w + diff.w * value
);
}
#endregion
}

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: a79611b258ffd496990f232247eefc3a
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: b015a50b4ac6b4515bd5116d6da7ff5d
folderAsset: yes
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,54 @@
using UnityEngine;
using System.Collections;
/// <summary>
/// base class for any color tweens (MaterialColor and ColorTween)
/// </summary>
public abstract class AbstractColorTweenProperty : AbstractTweenProperty
{
protected Material _target;
protected Color _originalEndValue;
protected Color _startValue;
protected Color _endValue;
protected Color _diffValue;
public AbstractColorTweenProperty( Color endValue, bool isRelative ) : base( isRelative )
{
_originalEndValue = endValue;
}
public override bool validateTarget( object target )
{
return ( target is Material || target is GameObject || target is Transform || target is Renderer );
}
public override void init( GoTween owner )
{
// setup our target before initting
if( owner.target is Material )
_target = (Material)owner.target;
else if( owner.target is GameObject )
_target = ((GameObject)owner.target).GetComponent<Renderer>().material;
else if( owner.target is Transform )
_target = ((Transform)owner.target).GetComponent<Renderer>().material;
else if( owner.target is Renderer )
_target = ((Renderer)owner.target).material;
base.init( owner );
}
public override void prepareForUse()
{
if( _isRelative && !_ownerTween.isFrom )
_diffValue = _endValue;
else
_diffValue = _endValue - _startValue;
}
}

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 06d1e7d9b36ea4b9fb70c40298d959ec
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,38 @@
using UnityEngine;
using System.Collections;
/// <summary>
/// base class for generic Quaternion props
/// </summary>
public abstract class AbstractQuaternionTweenProperty : AbstractTweenProperty
{
protected Transform _target;
protected Quaternion _originalEndValue;
protected Quaternion _startValue;
protected Quaternion _endValue;
public AbstractQuaternionTweenProperty()
{}
public AbstractQuaternionTweenProperty( Quaternion endValue, bool isRelative = false ) : base( isRelative )
{
_originalEndValue = endValue;
}
public override bool validateTarget( object target )
{
return target is Transform;
}
public override void prepareForUse()
{
if (_isRelative && !_ownerTween.isFrom)
_endValue = _startValue * _endValue;
}
}

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 91d9cba1487704697be079449afdefbb
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,112 @@
using UnityEngine;
using System;
using System.Collections;
public abstract class AbstractTweenProperty
{
protected bool _isInitialized;
public bool isInitialized { get { return _isInitialized; } }
protected bool _isRelative;
protected GoTween _ownerTween;
protected Func<float, float, float, float, float> _easeFunction;
public AbstractTweenProperty( bool isRelative = false )
{
_isRelative = isRelative;
}
public override int GetHashCode()
{
return base.GetHashCode();
}
/// <summary>
/// checks to see if a TweenProperty matches another. checks propertyNames of IGenericPropertys first then
/// resorts to direct type checking
/// </summary>
public override bool Equals( object obj )
{
// null check first
if( obj == null )
return false;
// handle IGenericProperty comparisons which just have the property name checked
if( this is IGenericProperty && obj is IGenericProperty )
return ((IGenericProperty)this).propertyName == ((IGenericProperty)obj).propertyName;
// check for the same types
if( obj.GetType() == this.GetType() )
return true;
return base.Equals( obj );
}
/// <summary>
/// called by a Tween just after this property is validated and added to the Tweens property list
/// </summary>
public virtual void init( GoTween owner )
{
_isInitialized = true;
_ownerTween = owner;
// if we dont have an easeFunction use the owners type
if( _easeFunction == null )
setEaseType( owner.easeType );
}
/// <summary>
/// clones the instance
/// </summary>
public AbstractTweenProperty clone()
{
var clone = MemberwiseClone() as AbstractTweenProperty;
clone._ownerTween = null;
clone._isInitialized = false;
clone._easeFunction = null;
return clone;
}
/// <summary>
/// sets the ease type for this tween property
/// technically, this should be an internal method
/// </summary>
public void setEaseType( GoEaseType easeType )
{
_easeFunction = GoTweenUtils.easeFunctionForType( easeType );
}
/// <summary>
/// each TweenProperty should override this to ensure the object is the correct type
/// </summary>
public virtual bool validateTarget( object target )
{
return true;
}
/// <summary>
/// subclasses should get the eased time then set the new value on the object
/// </summary>
public abstract void tick( float totalElapsedTime );
/// <summary>
/// called when a Tween is initially started.
/// subclasses should strongly type the start/end/target and handle isFrom with
/// regard to setting the proper start/end values
/// </summary>
public abstract void prepareForUse();
}

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: cf8a9f19ff8c84f3d9b75558baec7117
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,49 @@
using UnityEngine;
using System.Collections;
/// <summary>
/// base class for position, scale, eulers and the generic Vector3 props
/// </summary>
public abstract class AbstractVector3TweenProperty : AbstractTweenProperty
{
protected Transform _target;
protected Vector3 _originalEndValue;
protected Vector3 _startValue;
protected Vector3 _endValue;
protected Vector3 _diffValue;
public AbstractVector3TweenProperty()
{}
public AbstractVector3TweenProperty( Vector3 endValue, bool isRelative = false ) : base( isRelative )
{
_originalEndValue = endValue;
}
public override bool validateTarget( object target )
{
return target is Transform;
}
public override void prepareForUse()
{
if( _isRelative && !_ownerTween.isFrom )
_diffValue = _endValue;
else
_diffValue = _endValue - _startValue;
}
public void resetWithNewEndValue( Vector3 endValue )
{
_originalEndValue = endValue;
prepareForUse();
}
}

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 7f73ba6304fca4593ac3756c9c01864e
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 568b4e56e499a47b6b1edebd41563940
folderAsset: yes
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,59 @@
using UnityEngine;
using System;
using System.Collections;
public class ColorTweenProperty : AbstractColorTweenProperty, IGenericProperty
{
public string propertyName { get; private set; }
private Action<Color> _setter;
public ColorTweenProperty( string propertyName, Color endValue, bool isRelative = false ) : base( endValue, isRelative )
{
this.propertyName = propertyName;
}
/// <summary>
/// validation checks to make sure the target has a valid property with an accessible setter
/// </summary>
public override bool validateTarget( object target )
{
// cache the setter
_setter = GoTweenUtils.setterForProperty<Action<Color>>( target, propertyName );
return _setter != null;
}
public override void prepareForUse()
{
// retrieve the getter
var getter = GoTweenUtils.getterForProperty<Func<Color>>( _ownerTween.target, propertyName );
_endValue = _originalEndValue;
// if this is a from tween we need to swap the start and end values
if( _ownerTween.isFrom )
{
_startValue = _endValue;
_endValue = getter();
}
else
{
_startValue = getter();
}
base.prepareForUse();
}
public override void tick( float totalElapsedTime )
{
var easedTime = _easeFunction( totalElapsedTime, 0, 1, _ownerTween.duration );
var newColor = GoTweenUtils.unclampedColorLerp( _startValue, _diffValue, easedTime );
_setter( newColor );
}
}

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 8feba848df2ec4a0cb2b5c4b11d09fde
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,66 @@
using UnityEngine;
using System;
using System.Collections;
public class FloatTweenProperty : AbstractTweenProperty, IGenericProperty
{
public string propertyName { get; private set; }
private Action<float> _setter;
protected float _originalEndValue;
protected float _startValue;
protected float _endValue;
protected float _diffValue;
public FloatTweenProperty( string propertyName, float endValue, bool isRelative = false ) : base( isRelative )
{
this.propertyName = propertyName;
_originalEndValue = endValue;
}
/// <summary>
/// validation checks to make sure the target has a valid property with an accessible setter
/// </summary>
public override bool validateTarget( object target )
{
// cache the setter
_setter = GoTweenUtils.setterForProperty<Action<float>>( target, propertyName );
return _setter != null;
}
public override void prepareForUse()
{
// retrieve the getter
var getter = GoTweenUtils.getterForProperty<Func<float>>( _ownerTween.target, propertyName );
_endValue = _originalEndValue;
// if this is a from tween we need to swap the start and end values
if( _ownerTween.isFrom )
{
_startValue = _endValue;
_endValue = getter();
}
else
{
_startValue = getter();
}
// setup the diff value
if( _isRelative && !_ownerTween.isFrom )
_diffValue = _endValue;
else
_diffValue = _endValue - _startValue;
}
public override void tick( float totalElapsedTime )
{
var easedValue = _easeFunction( totalElapsedTime, _startValue, _diffValue, _ownerTween.duration );
_setter( easedValue );
}
}

Some files were not shown because too many files have changed in this diff Show More