├── .gitignore ├── Assets ├── BorrowedFromUtilityKit.meta ├── BorrowedFromUtilityKit │ ├── BitMaskAttribute.cs │ ├── BitMaskAttribute.cs.meta │ ├── Editor.meta │ └── Editor │ │ ├── EditorExtension.cs │ │ └── EditorExtension.cs.meta ├── CameraKit2D.meta ├── CameraKit2D │ ├── BaseBehaviors.meta │ ├── BaseBehaviors │ │ ├── CameraWindow.cs │ │ ├── CameraWindow.cs.meta │ │ ├── DualForwardFocus.cs │ │ ├── DualForwardFocus.cs.meta │ │ ├── PositionLocking.cs │ │ └── PositionLocking.cs.meta │ ├── CameraKit2D.cs │ ├── CameraKit2D.cs.meta │ ├── Effectors.meta │ ├── Effectors │ │ ├── CueFocusRing.cs │ │ └── CueFocusRing.cs.meta │ ├── Finalizer.meta │ ├── Finalizer │ │ ├── MapExtentsFinalizer.cs │ │ └── MapExtentsFinalizer.cs.meta │ ├── Utils.meta │ └── Utils │ │ ├── CameraAxis.cs │ │ ├── CameraAxis.cs.meta │ │ ├── CameraKit2DUtils.cs │ │ ├── CameraKit2DUtils.cs.meta │ │ ├── CameraKitInterfaces.cs │ │ ├── CameraKitInterfaces.cs.meta │ │ ├── CameraSmoothingType.cs │ │ ├── CameraSmoothingType.cs.meta │ │ ├── FixedSizedVector3Queue.cs │ │ └── FixedSizedVector3Queue.cs.meta ├── CameraKit2DDemo.meta ├── CameraKit2DDemo │ ├── CameraKitDemoScene.unity │ ├── CameraKitDemoScene.unity.meta │ ├── DemoUI.cs │ ├── DemoUI.cs.meta │ ├── SimplePlayerController.cs │ ├── SimplePlayerController.cs.meta │ ├── Slippy.physicsMaterial2D │ ├── Slippy.physicsMaterial2D.meta │ ├── ZoneMaterial.mat │ ├── ZoneMaterial.mat.meta │ ├── ZoomZone.cs │ └── ZoomZone.cs.meta ├── Editor.meta └── Editor │ ├── StripGeneratedSolutionSettings.cs │ └── StripGeneratedSolutionSettings.cs.meta ├── Packages └── manifest.json ├── ProjectSettings ├── AudioManager.asset ├── ClusterInputManager.asset ├── DynamicsManager.asset ├── EditorBuildSettings.asset ├── EditorSettings.asset ├── GraphicsSettings.asset ├── InputManager.asset ├── NavMeshAreas.asset ├── NetworkManager.asset ├── Physics2DSettings.asset ├── PresetManager.asset ├── ProjectSettings.asset ├── ProjectVersion.txt ├── QualitySettings.asset ├── TagManager.asset ├── TimeManager.asset └── UnityConnectSettings.asset └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | [Ll]ibrary/ 2 | [Tt]emp/ 3 | [Oo]bj/ 4 | [Bb]uild/ 5 | 6 | # Autogenerated VS/MD solution and project files 7 | *.csproj 8 | *.unityproj 9 | *.sln 10 | *.suo 11 | *.tmp 12 | *.user 13 | *.userprefs 14 | *.pidb 15 | *.booproj 16 | 17 | # Unity3D generated meta files 18 | *.pidb.meta 19 | 20 | # Unity3D Generated File On Crash Reports 21 | sysinfo.txt 22 | CameraKit2D.app 23 | .vscode 24 | -------------------------------------------------------------------------------- /Assets/BorrowedFromUtilityKit.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3499c665cdc99459f852dae9719a78d3 3 | folderAsset: yes 4 | timeCreated: 1435184008 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/BorrowedFromUtilityKit/BitMaskAttribute.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | 4 | 5 | namespace Prime31 6 | { 7 | /// 8 | /// stick this sucker as the type for a property drawer on a bitmask enum field like so: 9 | /// [CustomPropertyDrawer( typeof( BitMaskAttribute ) )] 10 | /// 11 | public class BitMaskAttribute : PropertyAttribute 12 | { 13 | } 14 | } -------------------------------------------------------------------------------- /Assets/BorrowedFromUtilityKit/BitMaskAttribute.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ba524d5a8c81b466c903ce770879005e 3 | timeCreated: 1435184008 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/BorrowedFromUtilityKit/Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: db301af819f8e4d658be85ecc17f0f9c 3 | folderAsset: yes 4 | timeCreated: 1435184008 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/BorrowedFromUtilityKit/Editor/EditorExtension.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEditor; 3 | 4 | 5 | namespace Prime31 6 | { 7 | public static class EditorExtension 8 | { 9 | public static int DrawBitMaskField( Rect rect, int mask, System.Type type, GUIContent label ) 10 | { 11 | var itemNames = System.Enum.GetNames( type ); 12 | var itemValues = System.Enum.GetValues( type ) as int[]; 13 | 14 | var val = mask; 15 | var maskVal = 0; 16 | for( var i = 0; i < itemValues.Length; i++ ) 17 | { 18 | if( itemValues[i] != 0 ) 19 | { 20 | if( ( val & itemValues[i] ) == itemValues[i] ) 21 | maskVal |= 1 << i; 22 | } 23 | else if( val == 0 ) 24 | { 25 | maskVal |= 1 << i; 26 | } 27 | } 28 | 29 | var newMaskVal = EditorGUI.MaskField( rect, label, maskVal, itemNames ); 30 | var changes = maskVal ^ newMaskVal; 31 | 32 | for( var i = 0; i < itemValues.Length; i++ ) 33 | { 34 | if( ( changes & ( 1 << i ) ) != 0 ) // has this list item changed? 35 | { 36 | if( ( newMaskVal & ( 1 << i ) ) != 0 ) // has it been set? 37 | { 38 | if( itemValues[i] == 0 ) // special case: if "0" is set, just set the val to 0 39 | { 40 | val = 0; 41 | break; 42 | } 43 | else 44 | val |= itemValues[i]; 45 | } 46 | else // it has been reset 47 | { 48 | val &= ~itemValues[i]; 49 | } 50 | } 51 | } 52 | 53 | return val; 54 | } 55 | } 56 | 57 | 58 | [CustomPropertyDrawer( typeof( BitMaskAttribute ) )] 59 | public class EnumBitMaskPropertyDrawer : PropertyDrawer 60 | { 61 | public override void OnGUI( Rect position, SerializedProperty prop, GUIContent label ) 62 | { 63 | label.text = label.text; 64 | prop.intValue = EditorExtension.DrawBitMaskField( position, prop.intValue, fieldInfo.FieldType, label ); 65 | } 66 | } 67 | } -------------------------------------------------------------------------------- /Assets/BorrowedFromUtilityKit/Editor/EditorExtension.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 06a8baf1b314f491f97c8821eebb7179 3 | timeCreated: 1435184008 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/CameraKit2D.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 58e27649a73ff4c5fb6ecd829037e33c 3 | folderAsset: yes 4 | timeCreated: 1433356210 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/CameraKit2D/BaseBehaviors.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b1d82c89977104064928bb18b84698c2 3 | folderAsset: yes 4 | timeCreated: 1433443053 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/CameraKit2D/BaseBehaviors/CameraWindow.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | 4 | 5 | namespace Prime31 6 | { 7 | public class CameraWindow : MonoBehaviour, ICameraBaseBehavior 8 | { 9 | [Range( 0f, 20f )] 10 | public float width = 3f; 11 | [Range( 0f, 20f )] 12 | public float height = 3f; 13 | 14 | [BitMaskAttribute] 15 | public CameraAxis axis; 16 | 17 | 18 | // this is only here so that we get the "Enabled" checkbox in the Inspector 19 | [System.Diagnostics.Conditional( "UNITY_EDITOR" )] 20 | void Update() 21 | {} 22 | 23 | 24 | public Vector3 getDesiredPositionDelta( Bounds targetBounds, Vector3 basePosition, Vector3 targetAvgVelocity ) 25 | { 26 | var desiredOffset = Vector3.zero; 27 | var hasHorizontal = ( axis & CameraAxis.Horizontal ) == CameraAxis.Horizontal; 28 | var hasVertical = ( axis & CameraAxis.Vertical ) == CameraAxis.Vertical; 29 | var bounds = new Bounds( basePosition, new Vector3( width, height, 5f ) ); 30 | 31 | if( !bounds.Contains( targetBounds.max ) || !bounds.Contains( targetBounds.min ) ) 32 | { 33 | // figure out the minimum distance we need to move to get the player back in our bounds 34 | // x-axis 35 | if( hasHorizontal && bounds.min.x > targetBounds.min.x ) 36 | { 37 | desiredOffset.x = targetBounds.min.x - bounds.min.x; 38 | } 39 | else if( hasHorizontal && bounds.max.x < targetBounds.max.x ) 40 | { 41 | desiredOffset.x = targetBounds.max.x - bounds.max.x; 42 | } 43 | 44 | // y-axis. disregard movement above the trap when in platform snap mode 45 | if( hasVertical && bounds.min.y > targetBounds.min.y ) 46 | { 47 | desiredOffset.y = targetBounds.min.y - bounds.min.y; 48 | } 49 | else if( /*!inPlatformSnapMode &&*/ hasVertical && bounds.max.y < targetBounds.max.y ) 50 | { 51 | desiredOffset.y = targetBounds.max.y - bounds.max.y; 52 | } 53 | } 54 | 55 | return desiredOffset; 56 | } 57 | 58 | 59 | public bool isEnabled() 60 | { 61 | return enabled; 62 | } 63 | 64 | 65 | #if UNITY_EDITOR 66 | public void onDrawGizmos( Vector3 basePosition ) 67 | { 68 | Gizmos.color = new Color( 1f, 0f, 0.6f ); 69 | 70 | var hasHorizontal = ( axis & CameraAxis.Horizontal ) == CameraAxis.Horizontal; 71 | var hasVertical = ( axis & CameraAxis.Vertical ) == CameraAxis.Vertical; 72 | var hasBothAxis = hasHorizontal && hasVertical; 73 | var bounds = new Bounds( basePosition, new Vector3( width, height ) ); 74 | var lineWidth = Camera.main.orthographicSize; 75 | 76 | // expand our bounds to have larger lines if we only have a single axis 77 | if( hasVertical && !hasBothAxis ) 78 | { 79 | bounds.Expand( new Vector3( lineWidth - bounds.size.x, 0f ) ); 80 | } 81 | 82 | if( hasHorizontal && !hasBothAxis ) 83 | { 84 | bounds.Expand( new Vector3( 0f, lineWidth - bounds.size.y ) ); 85 | } 86 | 87 | if( hasVertical || hasBothAxis ) 88 | { 89 | Gizmos.DrawLine( bounds.min, bounds.min + new Vector3( bounds.size.x, 0f ) ); 90 | Gizmos.DrawLine( bounds.max, bounds.max - new Vector3( bounds.size.x, 0f ) ); 91 | } 92 | 93 | if( hasHorizontal || hasBothAxis ) 94 | { 95 | Gizmos.DrawLine( bounds.min, bounds.min + new Vector3( 0f, bounds.size.y ) ); 96 | Gizmos.DrawLine( bounds.max, bounds.max - new Vector3( 0f, bounds.size.y ) ); 97 | } 98 | } 99 | #endif 100 | 101 | } 102 | } -------------------------------------------------------------------------------- /Assets/CameraKit2D/BaseBehaviors/CameraWindow.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9f14eb5fd3c54431f9eb25d1b64a8d94 3 | timeCreated: 1433443059 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/CameraKit2D/BaseBehaviors/DualForwardFocus.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | 4 | 5 | namespace Prime31 6 | { 7 | public class DualForwardFocus : MonoBehaviour, ICameraBaseBehavior 8 | { 9 | public enum DualForwardFocusType 10 | { 11 | ThresholdBased, 12 | VelocityBased, 13 | DirectionBased 14 | } 15 | 16 | 17 | [Range( 0f, 20f )] 18 | public float width = 3f; 19 | 20 | 21 | public DualForwardFocusType dualForwardFocusType; 22 | 23 | [Header( "Threshold Based" )] 24 | [Range( 0.5f, 5f )] 25 | public float dualForwardFocusThresholdExtents = 0.5f; 26 | RectTransform.Edge _currentEdgeFocus; 27 | 28 | [Header( "Velocity Based" )] 29 | public float velocityInfluenceMultiplier = 3f; 30 | 31 | 32 | // this is only here so that we get the "Enabled" checkbox in the Inspector 33 | [System.Diagnostics.Conditional( "UNITY_EDITOR" )] 34 | void Update() 35 | { 36 | } 37 | 38 | 39 | #region ICameraBaseBehavior 40 | 41 | public Vector3 getDesiredPositionDelta( Bounds targetBounds, Vector3 basePosition, Vector3 targetAvgVelocity ) 42 | { 43 | var desiredOffset = Vector3.zero; 44 | 45 | if( dualForwardFocusType == DualForwardFocusType.ThresholdBased ) 46 | { 47 | var deltaPositionFromBounds = Vector3.zero; 48 | var didLastEdgeContactChange = false; 49 | float leftEdge, rightEdge; 50 | 51 | if( _currentEdgeFocus == RectTransform.Edge.Left ) 52 | { 53 | rightEdge = basePosition.x - width * 0.5f; 54 | leftEdge = rightEdge - dualForwardFocusThresholdExtents * 0.5f; 55 | } 56 | else 57 | { 58 | leftEdge = basePosition.x + width * 0.5f; 59 | rightEdge = leftEdge + dualForwardFocusThresholdExtents * 0.5f; 60 | } 61 | 62 | if( leftEdge > targetBounds.center.x ) 63 | { 64 | deltaPositionFromBounds.x = targetBounds.center.x - leftEdge; 65 | 66 | if( _currentEdgeFocus == RectTransform.Edge.Left ) 67 | { 68 | didLastEdgeContactChange = true; 69 | _currentEdgeFocus = RectTransform.Edge.Right; 70 | } 71 | } 72 | else if( rightEdge < targetBounds.center.x ) 73 | { 74 | deltaPositionFromBounds.x = targetBounds.center.x - rightEdge; 75 | 76 | if( _currentEdgeFocus == RectTransform.Edge.Right ) 77 | { 78 | didLastEdgeContactChange = true; 79 | _currentEdgeFocus = RectTransform.Edge.Left; 80 | } 81 | } 82 | 83 | 84 | var desiredX = _currentEdgeFocus == RectTransform.Edge.Left ? rightEdge : leftEdge; 85 | desiredOffset.x = targetBounds.center.x - desiredX; 86 | 87 | // if we didnt switch direction this works much like a normal camera window 88 | if( !didLastEdgeContactChange ) 89 | desiredOffset.x = deltaPositionFromBounds.x; 90 | } 91 | else // velocity or direction based 92 | { 93 | var averagedHorizontalVelocity = targetAvgVelocity.x; 94 | 95 | // direction switches are determined by velocity 96 | if( averagedHorizontalVelocity > 0f ) 97 | _currentEdgeFocus = RectTransform.Edge.Left; 98 | else if( averagedHorizontalVelocity < 0f ) 99 | _currentEdgeFocus = RectTransform.Edge.Right; 100 | 101 | var desiredX = _currentEdgeFocus == RectTransform.Edge.Left ? basePosition.x - width * 0.5f : basePosition.x + width * 0.5f; 102 | desiredX = targetBounds.center.x - desiredX; 103 | 104 | if( dualForwardFocusType == DualForwardFocusType.DirectionBased ) 105 | { 106 | desiredOffset.x = desiredX; 107 | } 108 | else 109 | { 110 | var velocityMultiplier = Mathf.Max( 1f, Mathf.Abs( averagedHorizontalVelocity ) ); 111 | desiredOffset.x = Mathf.Lerp( 0f, desiredX, Time.deltaTime * velocityInfluenceMultiplier * velocityMultiplier ); 112 | } 113 | } 114 | 115 | return desiredOffset; 116 | } 117 | 118 | 119 | public bool isEnabled() 120 | { 121 | return enabled; 122 | } 123 | 124 | 125 | #if UNITY_EDITOR 126 | public void onDrawGizmos( Vector3 basePosition ) 127 | { 128 | Gizmos.color = new Color( 0f, 0.5f, 0.6f ); 129 | 130 | var bounds = new Bounds( basePosition, new Vector3( width, 10f ) ); 131 | var lineWidth = Camera.main.orthographicSize; 132 | 133 | bounds.center = new Vector3( bounds.center.x, basePosition.y, bounds.center.z ); 134 | bounds.Expand( new Vector3( 0f, lineWidth - bounds.size.y ) ); 135 | 136 | Gizmos.DrawLine( bounds.min, bounds.min + new Vector3( 0f, bounds.size.y ) ); 137 | Gizmos.DrawLine( bounds.max, bounds.max - new Vector3( 0f, bounds.size.y ) ); 138 | 139 | 140 | if( dualForwardFocusType == DualForwardFocusType.ThresholdBased ) 141 | { 142 | bounds.Expand( new Vector3( dualForwardFocusThresholdExtents, 1f ) ); 143 | Gizmos.color = Color.blue; 144 | Gizmos.DrawLine( bounds.min, bounds.min + new Vector3( 0f, bounds.size.y ) ); 145 | Gizmos.DrawLine( bounds.max, bounds.max - new Vector3( 0f, bounds.size.y ) ); 146 | } 147 | } 148 | #endif 149 | 150 | #endregion 151 | 152 | } 153 | } -------------------------------------------------------------------------------- /Assets/CameraKit2D/BaseBehaviors/DualForwardFocus.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 020752e5394a64e2e8dd12462923a9b6 3 | timeCreated: 1433536592 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/CameraKit2D/BaseBehaviors/PositionLocking.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections.Generic; 3 | using System; 4 | 5 | 6 | namespace Prime31 7 | { 8 | public class PositionLocking : MonoBehaviour, ICameraBaseBehavior 9 | { 10 | [BitMaskAttribute] 11 | public CameraAxis axis; 12 | 13 | [Header( "Projected Focus" )] 14 | [Tooltip( "projected focus will have the camera push ahead in the direction of the current velocity which is averaged over 5 frames" )] 15 | public bool enableProjectedFocus; 16 | [Tooltip( "when projected focus is enabled the multiplier will increase the forward projection" )] 17 | public float projectedFocusMultiplier = 3f; 18 | 19 | 20 | // this is only here so that we get the "Enabled" checkbox in the Inspector 21 | [System.Diagnostics.Conditional( "UNITY_EDITOR" )] 22 | void Update() 23 | { 24 | } 25 | 26 | 27 | /// 28 | /// gets a center point for our position locking calculation based on the CameraAxis. The targetPosition is needed so that if 29 | /// only one axis is present we don't calculate a desired position in that direction. 30 | /// 31 | /// The center based on contraints. 32 | /// Target position. 33 | Vector3 getCenterBasedOnContraints( Vector3 basePosition, Vector3 targetPosition ) 34 | { 35 | var centerPos = basePosition; 36 | centerPos.z = 0f; 37 | 38 | // if we arent contrained to an axis make it match the targetPosition so we dont have any offset in that direction 39 | if( ( axis & CameraAxis.Horizontal ) != CameraAxis.Horizontal ) 40 | centerPos.x = targetPosition.x; 41 | 42 | if( ( axis & CameraAxis.Vertical ) != CameraAxis.Vertical ) 43 | centerPos.y = targetPosition.y; 44 | 45 | return centerPos; 46 | } 47 | 48 | 49 | #region ICameraBaseBehavior 50 | 51 | public Vector3 getDesiredPositionDelta( Bounds targetBounds, Vector3 basePosition, Vector3 targetAvgVelocity ) 52 | { 53 | var centerPos = getCenterBasedOnContraints( basePosition, targetBounds.center ); 54 | var desiredOffset = targetBounds.center - centerPos; 55 | 56 | // projected focus uses the velocity to project forward 57 | // TODO: this needs proper smoothing. it only uses the avg velocity right now which can jump around 58 | if( enableProjectedFocus ) 59 | { 60 | var hasHorizontal = ( axis & CameraAxis.Horizontal ) == CameraAxis.Horizontal; 61 | var hasVertical = ( axis & CameraAxis.Vertical ) == CameraAxis.Vertical; 62 | var hasBothAxis = hasHorizontal && hasVertical; 63 | 64 | if( hasBothAxis ) 65 | desiredOffset += targetAvgVelocity * Time.deltaTime * projectedFocusMultiplier; 66 | else if( hasHorizontal ) 67 | desiredOffset.x += targetAvgVelocity.x * Time.deltaTime * projectedFocusMultiplier; 68 | else if( hasVertical ) 69 | desiredOffset.y += targetAvgVelocity.y * Time.deltaTime * projectedFocusMultiplier; 70 | } 71 | 72 | return desiredOffset; 73 | } 74 | 75 | 76 | public bool isEnabled() 77 | { 78 | return enabled; 79 | } 80 | 81 | 82 | #if UNITY_EDITOR 83 | public void onDrawGizmos( Vector3 basePosition ) 84 | { 85 | Gizmos.color = new Color( 0f, 0.4f, 0.8f ); 86 | 87 | var hasHorizontal = ( axis & CameraAxis.Horizontal ) == CameraAxis.Horizontal; 88 | var hasVertical = ( axis & CameraAxis.Vertical ) == CameraAxis.Vertical; 89 | var hasBothAxis = hasHorizontal && hasVertical; 90 | 91 | var lineWidth = hasBothAxis ? Camera.main.orthographicSize / 5f : Camera.main.orthographicSize / 2f; 92 | 93 | if( hasVertical || hasBothAxis ) 94 | { 95 | Gizmos.DrawLine( basePosition + new Vector3( -lineWidth, 0f, 1f ), basePosition + new Vector3( lineWidth, 0f, 1f ) ); 96 | } 97 | 98 | if( hasHorizontal || hasBothAxis ) 99 | { 100 | Gizmos.DrawLine( basePosition + new Vector3( 0f, -lineWidth, 1f ), basePosition + new Vector3( 0f, lineWidth, 1f ) ); 101 | } 102 | } 103 | #endif 104 | 105 | #endregion 106 | 107 | } 108 | } -------------------------------------------------------------------------------- /Assets/CameraKit2D/BaseBehaviors/PositionLocking.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e0776d5d01552416893310b784df4710 3 | timeCreated: 1433443069 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/CameraKit2D/CameraKit2D.cs: -------------------------------------------------------------------------------- 1 | // uncomment this if you have ZestKit in your project and you want to use the tweened methods 2 | //#define ENABLE_ZEST_KIT 3 | 4 | #if ENABLE_ZEST_KIT 5 | using Prime31.ZestKit; 6 | #endif 7 | using UnityEngine; 8 | using System.Collections.Generic; 9 | 10 | 11 | namespace Prime31 12 | { 13 | [RequireComponent( typeof( Camera ) )] 14 | public class CameraKit2D : MonoBehaviour 15 | { 16 | [System.NonSerialized][HideInInspector] 17 | public new Camera camera; 18 | public Collider2D targetCollider; 19 | [Tooltip( "percentage from -0.5 - 0.5 from the center of the screen" )] 20 | [Range( -0.5f, 0.5f )] 21 | public float horizontalOffset = 0f; 22 | [Tooltip( "percentage from -0.5 - 0.5 from the center of the screen" )] 23 | [Range( -0.5f, 0.5f )] 24 | public float verticalOffset = 0f; 25 | 26 | 27 | [Header( "Platform Snap" )] 28 | [Tooltip( "all platform snap settings only apply if enablePlatformSnap is true" )] 29 | public bool enablePlatformSnap; 30 | [Tooltip( "If true, no other base behaviors will be able to modify the y-position of the camera when grounded" )] 31 | public bool isPlatformSnapExclusiveWhenEnabled; 32 | [Range( -10f, 10f )] 33 | public float platformSnapVerticalOffset = 0f; 34 | [Tooltip( "This should be set as the player becomes grounded/ungrounded if using platform snap" )] 35 | public bool isPlayerGrounded; 36 | 37 | 38 | [Header( "Smoothing" )] 39 | public CameraSmoothingType cameraSmoothingType; 40 | [Tooltip( "approximately the time it will take to reach the target. A smaller value will reach the target faster." )] 41 | public float smoothDampTime = 0.08f; 42 | [Tooltip( "lower values are less damped and higher values are more damped resulting in less springiness. should be between 0.01f, 1f to avoid unstable systems." )] 43 | public float springDampingRatio = 0.7f; 44 | [Tooltip( "An angular frequency of 2pi (radians per second) means the oscillation completes one full period over one second, i.e. 1Hz. should be less than 35 or so to remain stable" )] 45 | public float springAngularFrequency = 20f; 46 | public float lerpTowardsFactor = 0.002f; 47 | 48 | 49 | Transform _transform; 50 | List _baseCameraBehaviors = new List( 3 ); 51 | List _cameraEffectors = new List( 3 ); 52 | List _cameraFinalizers = new List( 1 ); 53 | 54 | FixedSizedVector3Queue _averageVelocityQueue = new FixedSizedVector3Queue( 10 ); 55 | Vector3 _targetPositionLastFrame; 56 | Vector3 _cameraVelocity; 57 | // used for SmoothDamp and spring smoothing 58 | 59 | #pragma warning disable 0414 60 | float _originalOrthoSize; 61 | #pragma warning restore 0414 62 | #if ENABLE_ZEST_KIT 63 | ITween _orthoSizeTween; 64 | #endif 65 | 66 | private static CameraKit2D _instance; 67 | 68 | public static CameraKit2D instance 69 | { 70 | get 71 | { 72 | if( System.Object.Equals( _instance, null ) ) 73 | { 74 | _instance = FindObjectOfType( typeof( CameraKit2D ) ) as CameraKit2D; 75 | 76 | if( System.Object.Equals( _instance, null ) ) 77 | throw new UnityException( "CameraKit2D does not appear to exist" ); 78 | } 79 | 80 | return _instance; 81 | } 82 | } 83 | 84 | 85 | #region MonoBehaviour 86 | 87 | void Awake() 88 | { 89 | _instance = this; 90 | _transform = GetComponent(); 91 | camera = GetComponent(); 92 | _originalOrthoSize = camera.orthographicSize; 93 | 94 | var behaviors = GetComponents(); 95 | for( var i = 0; i < behaviors.Length; i++ ) 96 | addCameraBaseBehavior( behaviors[i] ); 97 | } 98 | 99 | 100 | void LateUpdate() 101 | { 102 | var targetBounds = targetCollider.bounds; 103 | 104 | // we keep track of the target's velocity since some camera behaviors need to know about it 105 | var velocity = ( targetBounds.center - _targetPositionLastFrame ) / Time.deltaTime; 106 | velocity.z = 0f; 107 | _averageVelocityQueue.push( velocity ); 108 | _targetPositionLastFrame = targetBounds.center; 109 | 110 | // fetch the average velocity for use in our camera behaviors 111 | var targetAvgVelocity = _averageVelocityQueue.average(); 112 | 113 | 114 | // we use the transform.position plus the offset when passing the base position to our camera behaviors 115 | var basePosition = getNormalizedCameraPosition(); 116 | var accumulatedDeltaOffset = Vector3.zero; 117 | 118 | for( var i = 0; i < _baseCameraBehaviors.Count; i++ ) 119 | { 120 | var cameraBehavior = _baseCameraBehaviors[i]; 121 | if( cameraBehavior.isEnabled() ) 122 | { 123 | // once we get the desired position we have to subtract the offset that we previously added 124 | var desiredPos = cameraBehavior.getDesiredPositionDelta( targetBounds, basePosition, targetAvgVelocity ); 125 | accumulatedDeltaOffset += desiredPos; 126 | } 127 | } 128 | 129 | if( enablePlatformSnap && isPlayerGrounded ) 130 | { 131 | // when exclusive, no base behaviors can mess with y 132 | if( isPlatformSnapExclusiveWhenEnabled ) 133 | accumulatedDeltaOffset.y = 0f; 134 | 135 | var desiredOffset = targetBounds.min.y - basePosition.y - platformSnapVerticalOffset; 136 | accumulatedDeltaOffset += new Vector3( 0f, desiredOffset ); 137 | } 138 | 139 | 140 | // fetch our effectors 141 | var totalWeight = 0f; 142 | var accumulatedEffectorPosition = Vector3.zero; 143 | for( var i = 0; i < _cameraEffectors.Count; i++ ) 144 | { 145 | var weight = _cameraEffectors[i].getEffectorWeight(); 146 | var position = _cameraEffectors[i].getDesiredPositionDelta( targetBounds, basePosition, targetAvgVelocity ); 147 | 148 | totalWeight += weight; 149 | accumulatedEffectorPosition += ( weight * position ); 150 | } 151 | 152 | var desiredPosition = _transform.position + accumulatedDeltaOffset; 153 | 154 | // if we have a totalWeight we need to take into account our effectors 155 | if( totalWeight > 0 ) 156 | { 157 | totalWeight += 1f; 158 | accumulatedEffectorPosition += desiredPosition; 159 | var finalAccumulatedPosition = accumulatedEffectorPosition / totalWeight; 160 | finalAccumulatedPosition.z = _transform.position.z; 161 | desiredPosition = finalAccumulatedPosition; 162 | } 163 | 164 | 165 | var smoothing = cameraSmoothingType; 166 | 167 | // and finally, our finalizers have a go if we have any 168 | for( var i = 0; i < _cameraFinalizers.Count; i++ ) 169 | { 170 | desiredPosition = _cameraFinalizers[i].getFinalCameraPosition( targetBounds, transform.position, desiredPosition ); 171 | 172 | // allow the finalizer with a 0 priority to skip smoothing if it wants to 173 | if( i == 0 && _cameraFinalizers[i].getFinalizerPriority() == 0 && _cameraFinalizers[i].shouldSkipSmoothingThisFrame() ) 174 | smoothing = CameraSmoothingType.None; 175 | } 176 | 177 | 178 | 179 | // reset Z just in case one of the other scripts messed with it 180 | desiredPosition.z = _transform.position.z; 181 | 182 | // time to smooth our movement to the desired position 183 | switch( smoothing ) 184 | { 185 | case CameraSmoothingType.None: 186 | _transform.position = desiredPosition; 187 | break; 188 | case CameraSmoothingType.SmoothDamp: 189 | _transform.position = Vector3.SmoothDamp( _transform.position, desiredPosition, ref _cameraVelocity, smoothDampTime ); 190 | break; 191 | case CameraSmoothingType.Spring: 192 | _transform.position = fastSpring( _transform.position, desiredPosition ); 193 | break; 194 | case CameraSmoothingType.Lerp: 195 | _transform.position = lerpTowards( _transform.position, desiredPosition, lerpTowardsFactor ); 196 | break; 197 | } 198 | } 199 | 200 | 201 | #if UNITY_EDITOR 202 | void OnDrawGizmos() 203 | { 204 | var positionInFrontOfCamera = getNormalizedCameraPosition(); 205 | positionInFrontOfCamera.z = 1f; 206 | 207 | var allCameraBehaviors = GetComponents(); 208 | foreach( var cameraBehavior in allCameraBehaviors ) 209 | { 210 | if( cameraBehavior.isEnabled() ) 211 | cameraBehavior.onDrawGizmos( positionInFrontOfCamera ); 212 | } 213 | 214 | if( enablePlatformSnap ) 215 | { 216 | Gizmos.color = new Color( 0.3f, 0.1f, 0.6f ); 217 | 218 | var lineWidth = Camera.main.orthographicSize / 2f; 219 | Gizmos.DrawLine( positionInFrontOfCamera + new Vector3( -lineWidth, platformSnapVerticalOffset, 1f ), positionInFrontOfCamera + new Vector3( lineWidth, platformSnapVerticalOffset, 1f ) ); 220 | } 221 | } 222 | #endif 223 | 224 | 225 | void OnApplicationQuit() 226 | { 227 | _instance = null; 228 | } 229 | 230 | #endregion 231 | 232 | 233 | Vector3 getNormalizedCameraPosition() 234 | { 235 | //Camera.main.ViewportToWorldPoint() 236 | #if UNITY_EDITOR 237 | return GetComponent().ViewportToWorldPoint( new Vector3( 0.5f + horizontalOffset, 0.5f + verticalOffset, 0f ) ); 238 | #else 239 | return camera.ViewportToWorldPoint( new Vector3( 0.5f + horizontalOffset, 0.5f + verticalOffset, 0f ) ); 240 | #endif 241 | } 242 | 243 | 244 | #region smoothing 245 | 246 | Vector3 lerpTowards( Vector3 from, Vector3 to, float remainingFactorPerSecond ) 247 | { 248 | return Vector3.Lerp( from, to, 1f - Mathf.Pow( remainingFactorPerSecond, Time.deltaTime ) ); 249 | } 250 | 251 | 252 | /// 253 | /// uses the semi-implicit euler method. faster, but not always stable. 254 | /// see http://allenchou.net/2015/04/game-math-more-on-numeric-springing/ 255 | /// 256 | /// The spring. 257 | /// Current value. 258 | /// Target value. 259 | /// Velocity by reference. Be sure to reset it to 0 if changing the targetValue between calls 260 | /// lower values are less damped and higher values are more damped resulting in less springiness. 261 | /// should be between 0.01f, 1f to avoid unstable systems. 262 | /// An angular frequency of 2pi (radians per second) means the oscillation completes one 263 | /// full period over one second, i.e. 1Hz. should be less than 35 or so to remain stable 264 | Vector3 fastSpring( Vector3 currentValue, Vector3 targetValue ) 265 | { 266 | _cameraVelocity += -2.0f * Time.deltaTime * springDampingRatio * springAngularFrequency * _cameraVelocity + Time.deltaTime * springAngularFrequency * springAngularFrequency * ( targetValue - currentValue ); 267 | currentValue += Time.deltaTime * _cameraVelocity; 268 | 269 | return currentValue; 270 | } 271 | 272 | #endregion 273 | 274 | 275 | #if ENABLE_ZEST_KIT 276 | public void setOrthographicSize( float orthographicSize, float duration = 0.3f, EaseType easeType = EaseType.QuartInOut ) 277 | { 278 | // we create a non-recyclable tween so we can reuse it whenever the orthosize changes 279 | if( _orthoSizeTween == null ) 280 | _orthoSizeTween = camera.ZKorthographicSizeTo( 0f, 0f ).setRecycleTween( false ); 281 | else 282 | _orthoSizeTween.stop(); 283 | 284 | _orthoSizeTween.prepareForReuse( camera.orthographicSize, orthographicSize, duration ) 285 | .setEaseType( easeType ) 286 | .start(); 287 | } 288 | 289 | 290 | public void resetOrthoSize( float duration = 0.3f, EaseType easeType = EaseType.QuartInOut ) 291 | { 292 | setOrthographicSize( _originalOrthoSize, duration, easeType ); 293 | } 294 | #endif 295 | 296 | 297 | #region Camera Behavior and Effector management 298 | 299 | public void addCameraBaseBehavior( ICameraBaseBehavior cameraBehavior ) 300 | { 301 | _baseCameraBehaviors.Add( cameraBehavior ); 302 | } 303 | 304 | 305 | public void removeCameraBaseBehavior() where T : ICameraBaseBehavior 306 | { 307 | var requestedType = typeof( T ); 308 | for( var i = _baseCameraBehaviors.Count - 1; i >= 0; i-- ) 309 | { 310 | if( _baseCameraBehaviors[i].GetType() == requestedType ) 311 | { 312 | _baseCameraBehaviors.RemoveAt( i ); 313 | return; 314 | } 315 | } 316 | } 317 | 318 | 319 | public T getCameraBaseBehavior() where T : ICameraBaseBehavior 320 | { 321 | var requestedType = typeof( T ); 322 | for( var i = 0; i < _baseCameraBehaviors.Count; i++ ) 323 | { 324 | if( _baseCameraBehaviors[i].GetType() == requestedType ) 325 | return (T)_baseCameraBehaviors[i]; 326 | } 327 | 328 | return default( T ); 329 | } 330 | 331 | 332 | public void addCameraEffector( ICameraEffector cameraEffector ) 333 | { 334 | _cameraEffectors.Add( cameraEffector ); 335 | } 336 | 337 | 338 | public void removeCameraEffector( ICameraEffector cameraEffector ) 339 | { 340 | for( var i = _cameraEffectors.Count - 1; i >= 0; i-- ) 341 | { 342 | if( _cameraEffectors[i] == cameraEffector ) 343 | { 344 | _cameraEffectors.RemoveAt( i ); 345 | return; 346 | } 347 | } 348 | } 349 | 350 | 351 | public void addCameraFinalizer( ICameraFinalizer cameraFinalizer ) 352 | { 353 | _cameraFinalizers.Add( cameraFinalizer ); 354 | 355 | // sort the list if we need to 356 | if( _cameraFinalizers.Count > 1 ) 357 | _cameraFinalizers.Sort( ( first, second ) => first.getFinalizerPriority().CompareTo( second.getFinalizerPriority() ) ); 358 | } 359 | 360 | 361 | public void removeCameraFinalizer( ICameraFinalizer cameraFinalizer ) 362 | { 363 | for( var i = _cameraFinalizers.Count - 1; i >= 0; i-- ) 364 | { 365 | if( _cameraFinalizers[i] == cameraFinalizer ) 366 | { 367 | _cameraFinalizers.RemoveAt( i ); 368 | return; 369 | } 370 | } 371 | } 372 | 373 | #endregion 374 | 375 | } 376 | } -------------------------------------------------------------------------------- /Assets/CameraKit2D/CameraKit2D.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d38b02a8722ad49e2ae96154c7ac2ea7 3 | timeCreated: 1435183158 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 31100 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/CameraKit2D/Effectors.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 450805787ec9846e28da5ba517bce37b 3 | folderAsset: yes 4 | timeCreated: 1433645901 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/CameraKit2D/Effectors/CueFocusRing.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | 4 | 5 | namespace Prime31 6 | { 7 | [RequireComponent( typeof( CircleCollider2D ) )] 8 | public class CueFocusRing : MonoBehaviour, ICameraEffector 9 | { 10 | [Tooltip( "when true, an additional inner ring can be used to have it's own specific weight indpendent of the outer ring" )] 11 | public bool enableInnerRing = false; 12 | public float outerRingRadius = 8f; 13 | public float insideRingRadius = 2f; 14 | public float outsideEffectorWeight = 0.5f; 15 | public float insideEffectorWeight = 5f; 16 | [Tooltip( "The curve should go from 0 to 1 being the normalized distance from center to radius. It's value will be multiplied by the effectorWeight to get the final weight used." )] 17 | public AnimationCurve effectorFalloffCurve = AnimationCurve.Linear( 0f, 0f, 1f, 1f ); 18 | 19 | Transform _trackedTarget; 20 | 21 | 22 | void Awake() 23 | { 24 | GetComponent().radius = outerRingRadius; 25 | } 26 | 27 | 28 | void OnTriggerEnter2D( Collider2D other ) 29 | { 30 | if( other.gameObject.CompareTag( "Player" ) ) 31 | { 32 | _trackedTarget = other.transform; 33 | CameraKit2D.instance.addCameraEffector( this ); 34 | } 35 | } 36 | 37 | 38 | void OnTriggerExit2D( Collider2D other ) 39 | { 40 | if( other.transform == _trackedTarget ) 41 | { 42 | _trackedTarget = null; 43 | CameraKit2D.instance.removeCameraEffector( this ); 44 | } 45 | } 46 | 47 | 48 | #if UNITY_EDITOR 49 | void OnDrawGizmos() 50 | { 51 | UnityEditor.Handles.color = Color.green; 52 | 53 | if( enableInnerRing ) 54 | UnityEditor.Handles.DrawWireDisc( transform.position, Vector3.back, insideRingRadius ); 55 | else 56 | UnityEditor.Handles.DrawWireDisc( transform.position, Vector3.back, outerRingRadius ); 57 | } 58 | #endif 59 | 60 | 61 | #region ICameraEffector 62 | 63 | public float getEffectorWeight() 64 | { 65 | var distanceToTarget = Vector3.Distance( transform.position, _trackedTarget.position ); 66 | if( enableInnerRing && distanceToTarget <= insideRingRadius ) 67 | return insideEffectorWeight; 68 | 69 | return effectorFalloffCurve.Evaluate( 1f - ( distanceToTarget / outerRingRadius ) ) * outsideEffectorWeight; 70 | } 71 | 72 | 73 | public Vector3 getDesiredPositionDelta( Bounds targetBounds, Vector3 basePosition, Vector3 targetAvgVelocity ) 74 | { 75 | return transform.position; 76 | } 77 | 78 | #endregion 79 | 80 | } 81 | } -------------------------------------------------------------------------------- /Assets/CameraKit2D/Effectors/CueFocusRing.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1133f8c43ff574d70ab0964090680aa4 3 | timeCreated: 1433645934 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/CameraKit2D/Finalizer.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1498ad5a616cc43529a330e561a6084f 3 | folderAsset: yes 4 | timeCreated: 1434691832 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/CameraKit2D/Finalizer/MapExtentsFinalizer.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections.Generic; 3 | 4 | 5 | namespace Prime31 6 | { 7 | public class MapExtentsFinalizer : ICameraFinalizer 8 | { 9 | public bool snapToBottom; 10 | public bool snapToTop; 11 | public bool snapToRight; 12 | public bool snapToLeft; 13 | 14 | public Bounds bounds; 15 | 16 | bool _shouldSkipSmoothingThisFrame; 17 | 18 | 19 | #region ICameraFinalizer 20 | 21 | public Vector3 getFinalCameraPosition( Bounds targetBounds, Vector3 currentCameraPosition, Vector3 desiredCameraPosition ) 22 | { 23 | _shouldSkipSmoothingThisFrame = false; 24 | 25 | // orthographicSize is 0.5 * height. aspect is width / height. that makes this calculation equal 0.5 * width 26 | var orthoSize = CameraKit2D.instance.camera.orthographicSize; 27 | var orthographicHalfWidth = orthoSize * CameraKit2D.instance.camera.aspect; 28 | 29 | // clamp the camera position to the maps bounds 30 | // left 31 | if( snapToLeft && desiredCameraPosition.x - orthographicHalfWidth < bounds.min.x ) 32 | { 33 | _shouldSkipSmoothingThisFrame = true; 34 | desiredCameraPosition.x = bounds.min.x + orthographicHalfWidth; 35 | } 36 | 37 | // right 38 | if( snapToRight && desiredCameraPosition.x + orthographicHalfWidth > bounds.max.x ) 39 | { 40 | _shouldSkipSmoothingThisFrame = true; 41 | desiredCameraPosition.x = bounds.max.x - orthographicHalfWidth; 42 | } 43 | 44 | // top 45 | if( snapToTop && desiredCameraPosition.y + orthoSize > bounds.max.y ) 46 | { 47 | _shouldSkipSmoothingThisFrame = true; 48 | desiredCameraPosition.y = bounds.max.y - orthoSize; 49 | } 50 | 51 | // bottom 52 | if( snapToBottom && desiredCameraPosition.y - orthoSize < bounds.min.y ) 53 | { 54 | _shouldSkipSmoothingThisFrame = true; 55 | desiredCameraPosition.y = bounds.min.y + orthoSize; 56 | } 57 | 58 | return desiredCameraPosition; 59 | } 60 | 61 | 62 | public int getFinalizerPriority() 63 | { 64 | return 0; 65 | } 66 | 67 | 68 | public bool shouldSkipSmoothingThisFrame() 69 | { 70 | return _shouldSkipSmoothingThisFrame; 71 | } 72 | 73 | #endregion 74 | 75 | } 76 | } -------------------------------------------------------------------------------- /Assets/CameraKit2D/Finalizer/MapExtentsFinalizer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ada637011e40b4c4d9160dd583bfd929 3 | timeCreated: 1434691839 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/CameraKit2D/Utils.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5354ff5bd77394456848f8bbdb581634 3 | folderAsset: yes 4 | timeCreated: 1433566374 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/CameraKit2D/Utils/CameraAxis.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | using System; 4 | 5 | 6 | namespace Prime31 7 | { 8 | [Flags] 9 | public enum CameraAxis 10 | { 11 | Horizontal = 1 << 0, 12 | Vertical = 1 << 1 13 | } 14 | } -------------------------------------------------------------------------------- /Assets/CameraKit2D/Utils/CameraAxis.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 38e5b84eb64984ecf83620b24df85317 3 | timeCreated: 1433445761 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/CameraKit2D/Utils/CameraKit2DUtils.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | 4 | 5 | namespace Prime31 6 | { 7 | public static class CameraKit2DUtils 8 | { 9 | public static void drawDesiredPositionGizmo( Vector3 position, Color color = default( Color ) ) 10 | { 11 | position.z = 0f; 12 | if( color == default( Color ) ) 13 | color = Color.green; 14 | 15 | Gizmos.color = color; 16 | var size = Camera.main.orthographicSize * 0.04f; 17 | var verticalOffset = new Vector3( 0f, size, 0f ); 18 | var horizontalOffset = new Vector3( size, 0f, 0f ); 19 | 20 | Gizmos.DrawLine( position - verticalOffset, position + verticalOffset ); 21 | Gizmos.DrawLine( position - horizontalOffset, position + horizontalOffset ); 22 | } 23 | 24 | 25 | #if UNITY_EDITOR 26 | public static void drawCurrentPositionGizmo( Vector3 position, Color color = default( Color ) ) 27 | { 28 | position.z = 0f; 29 | if( color == default( Color ) ) 30 | color = Color.yellow; 31 | 32 | var size = Camera.main.orthographicSize * 0.04f; 33 | UnityEditor.Handles.color = color; 34 | UnityEditor.Handles.DrawWireDisc( position, Vector3.back, size ); 35 | } 36 | #endif 37 | 38 | 39 | public static void drawForGizmo( Vector3 pos, Vector3 direction, float arrowHeadLength = 0.25f, float arrowHeadAngle = 20.0f ) 40 | { 41 | Gizmos.DrawRay( pos, direction ); 42 | drawArrowEnd( true, pos, direction, Gizmos.color, arrowHeadLength, arrowHeadAngle ); 43 | } 44 | 45 | 46 | public static void drawForGizmo( Vector3 pos, Vector3 direction, Color color, float arrowHeadLength = 0.25f, float arrowHeadAngle = 20.0f ) 47 | { 48 | Gizmos.DrawRay( pos, direction ); 49 | drawArrowEnd( true, pos, direction, color, arrowHeadLength, arrowHeadAngle ); 50 | } 51 | 52 | 53 | public static void ForDebug( Vector3 pos, Vector3 direction, float arrowHeadLength = 0.25f, float arrowHeadAngle = 20.0f ) 54 | { 55 | Debug.DrawRay( pos, direction ); 56 | drawArrowEnd( false, pos, direction, Gizmos.color, arrowHeadLength, arrowHeadAngle ); 57 | } 58 | 59 | 60 | public static void ForDebug( Vector3 pos, Vector3 direction, Color color, float arrowHeadLength = 0.25f, float arrowHeadAngle = 20.0f ) 61 | { 62 | Debug.DrawRay( pos, direction, color ); 63 | drawArrowEnd( false, pos, direction, color, arrowHeadLength, arrowHeadAngle ); 64 | } 65 | 66 | 67 | static void drawArrowEnd( bool gizmos, Vector3 pos, Vector3 direction, Color color, float arrowHeadLength = 0.25f, float arrowHeadAngle = 20.0f ) 68 | { 69 | Vector3 right = Quaternion.LookRotation( direction ) * Quaternion.Euler( arrowHeadAngle, 0, 0 ) * Vector3.back; 70 | Vector3 left = Quaternion.LookRotation( direction ) * Quaternion.Euler( -arrowHeadAngle, 0, 0 ) * Vector3.back; 71 | Vector3 up = Quaternion.LookRotation( direction ) * Quaternion.Euler( 0, arrowHeadAngle, 0 ) * Vector3.back; 72 | Vector3 down = Quaternion.LookRotation( direction ) * Quaternion.Euler( 0, -arrowHeadAngle, 0 ) * Vector3.back; 73 | if( gizmos ) 74 | { 75 | Gizmos.color = color; 76 | Gizmos.DrawRay( pos + direction, right * arrowHeadLength ); 77 | Gizmos.DrawRay( pos + direction, left * arrowHeadLength ); 78 | Gizmos.DrawRay( pos + direction, up * arrowHeadLength ); 79 | Gizmos.DrawRay( pos + direction, down * arrowHeadLength ); 80 | } 81 | else 82 | { 83 | Debug.DrawRay( pos + direction, right * arrowHeadLength, color ); 84 | Debug.DrawRay( pos + direction, left * arrowHeadLength, color ); 85 | Debug.DrawRay( pos + direction, up * arrowHeadLength, color ); 86 | Debug.DrawRay( pos + direction, down * arrowHeadLength, color ); 87 | } 88 | } 89 | 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /Assets/CameraKit2D/Utils/CameraKit2DUtils.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b81f64e92bb784580a3208b72b462843 3 | timeCreated: 1433522633 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/CameraKit2D/Utils/CameraKitInterfaces.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | 4 | 5 | namespace Prime31 6 | { 7 | /// 8 | /// BaseBehaviors get to decide a desired position for the camera. They are first in line for the calculation. 9 | /// 10 | public interface ICameraBaseBehavior : ICameraPositionAssertion 11 | { 12 | bool isEnabled(); 13 | #if UNITY_EDITOR 14 | // useful for while we are in the editor to provide a UI 15 | void onDrawGizmos( Vector3 basePosition ); 16 | #endif 17 | } 18 | 19 | 20 | /// 21 | /// Effectors get evaluated after BaesBehaviors. They each have a weight that is used for a weighted average to get a final 22 | /// camera position. The BaseBehavior has a weight of 1f which should be taken into account when deciding your Effector's weight. 23 | /// 24 | public interface ICameraEffector : ICameraPositionAssertion 25 | { 26 | /// 27 | /// each effector has a weight that changes how much it effects the final position. When the position is calculated the 28 | /// camera base behavior has a weight of 1. Your effectors can have weights larger than one if you want them weighted more than the 29 | /// base behavior 30 | /// 31 | float getEffectorWeight(); 32 | } 33 | 34 | 35 | /// 36 | /// common interface for BaseBehaviors and Effectors. Importantly, basePosition is the camera's position plus the offsets 37 | /// of CameraKit. The method should return the desired offset from that position that it wants the camera to be moved by. 38 | /// 39 | public interface ICameraPositionAssertion 40 | { 41 | Vector3 getDesiredPositionDelta( Bounds targetBounds, Vector3 basePosition, Vector3 targetAvgVelocity ); 42 | } 43 | 44 | 45 | /// 46 | /// camera finalizers get the final say for the camera position. They are sorted by priority and passed the current and desired 47 | /// camera positions. shouldSkipSmoothingThisFrame will ONLY be called on a priority 0 finalizer. It allows the finalizer to 48 | /// force smoothing to None. This is important when the finalizer has a position change that is absolute (extents are a good 49 | /// example since you never want to display outside of your extents). 50 | /// 51 | public interface ICameraFinalizer 52 | { 53 | Vector3 getFinalCameraPosition( Bounds targetBounds, Vector3 currentCameraPosition, Vector3 desiredCameraPosition ); 54 | 55 | int getFinalizerPriority(); 56 | 57 | bool shouldSkipSmoothingThisFrame(); 58 | } 59 | } -------------------------------------------------------------------------------- /Assets/CameraKit2D/Utils/CameraKitInterfaces.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 91b8ef7600b0b42ea8d4061b06cb3bd8 3 | timeCreated: 1433560245 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/CameraKit2D/Utils/CameraSmoothingType.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections.Generic; 3 | 4 | 5 | namespace Prime31 6 | { 7 | public enum CameraSmoothingType 8 | { 9 | None, 10 | SmoothDamp, 11 | Spring, 12 | Lerp 13 | } 14 | } -------------------------------------------------------------------------------- /Assets/CameraKit2D/Utils/CameraSmoothingType.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1024ad724ef2b46d7b85d7424b7ac7e1 3 | timeCreated: 1434425414 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/CameraKit2D/Utils/FixedSizedVector3Queue.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections.Generic; 3 | 4 | 5 | namespace Prime31 6 | { 7 | public class FixedSizedVector3Queue 8 | { 9 | List _list; 10 | int _limit; 11 | 12 | 13 | public FixedSizedVector3Queue( int limit ) 14 | { 15 | _limit = limit; 16 | _list = new List( limit ); 17 | } 18 | 19 | 20 | public void push( Vector3 item ) 21 | { 22 | if( _list.Count == _limit ) 23 | _list.RemoveAt( 0 ); 24 | 25 | _list.Add( item ); 26 | } 27 | 28 | 29 | public Vector3 average() 30 | { 31 | var avg = Vector3.zero; 32 | 33 | // early out for no items 34 | if( _list.Count == 0 ) 35 | return avg; 36 | 37 | for( var i = 0; i < _list.Count; i++ ) 38 | avg += _list[i]; 39 | 40 | return avg / _list.Count; 41 | } 42 | } 43 | } -------------------------------------------------------------------------------- /Assets/CameraKit2D/Utils/FixedSizedVector3Queue.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 92088fdf26a034f73902b040d091e2a9 3 | timeCreated: 1433533166 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/CameraKit2DDemo.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0884ac33e44ef4dc4a0bee7832a5b6ec 3 | folderAsset: yes 4 | timeCreated: 1433356217 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/CameraKit2DDemo/CameraKitDemoScene.unity: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prime31/CameraKit2D/ac8f73b6071e469fd07c6acd92adf2ae917b4dca/Assets/CameraKit2DDemo/CameraKitDemoScene.unity -------------------------------------------------------------------------------- /Assets/CameraKit2DDemo/CameraKitDemoScene.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c361f8a536c474be3a016f5bbd66befb 3 | timeCreated: 1433356226 4 | licenseType: Pro 5 | DefaultImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/CameraKit2DDemo/DemoUI.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections.Generic; 3 | using Prime31; 4 | 5 | 6 | public class DemoUI : MonoBehaviour 7 | { 8 | public CameraWindow camWindow; 9 | public DualForwardFocus dualForwardFocus; 10 | public PositionLocking positionLocking; 11 | 12 | 13 | void OnGUI() 14 | { 15 | CameraKit2D.instance.enablePlatformSnap = GUILayout.Toggle( CameraKit2D.instance.enablePlatformSnap, "Enabled Platform Snap" ); 16 | 17 | GUILayout.Label( "Horizontal Offset " + CameraKit2D.instance.horizontalOffset ); 18 | CameraKit2D.instance.horizontalOffset = GUILayout.HorizontalSlider( CameraKit2D.instance.horizontalOffset, -0.5f, 0.5f ); 19 | 20 | GUILayout.Label( "Vertical Offset" ); 21 | CameraKit2D.instance.verticalOffset = GUILayout.HorizontalSlider( CameraKit2D.instance.verticalOffset, -0.5f, 0.5f ); 22 | 23 | 24 | if( GUILayout.Button( "Enable Camera Window" ) ) 25 | { 26 | camWindow.axis = CameraAxis.Horizontal | CameraAxis.Vertical; 27 | camWindow.enabled = true; 28 | dualForwardFocus.enabled = positionLocking.enabled = false; 29 | } 30 | 31 | if( GUILayout.Button( "Enable Dual Forward Focus (Direction Based)" ) ) 32 | { 33 | dualForwardFocus.enabled = true; 34 | dualForwardFocus.dualForwardFocusType = DualForwardFocus.DualForwardFocusType.DirectionBased; 35 | 36 | // we also enable the Camera Window in the vertical direction here 37 | camWindow.axis = CameraAxis.Vertical; 38 | camWindow.enabled = true; 39 | positionLocking.enabled = false; 40 | } 41 | 42 | if( GUILayout.Button( "Enable Dual Forward Focus (Threshold Based)" ) ) 43 | { 44 | dualForwardFocus.enabled = true; 45 | dualForwardFocus.dualForwardFocusType = DualForwardFocus.DualForwardFocusType.ThresholdBased; 46 | 47 | // we also enable the Camera Window in the vertical direction here 48 | camWindow.axis = CameraAxis.Vertical; 49 | camWindow.enabled = true; 50 | positionLocking.enabled = false; 51 | } 52 | 53 | if( GUILayout.Button( "Enable Dual Forward Focus (Velocity Based)" ) ) 54 | { 55 | dualForwardFocus.enabled = true; 56 | dualForwardFocus.dualForwardFocusType = DualForwardFocus.DualForwardFocusType.VelocityBased; 57 | 58 | // we also enable the Camera Window in the vertical direction here 59 | camWindow.axis = CameraAxis.Vertical; 60 | camWindow.enabled = true; 61 | positionLocking.enabled = false; 62 | } 63 | 64 | if( GUILayout.Button( "Enable Position Locking" ) ) 65 | { 66 | CameraKit2D.instance.enablePlatformSnap = false; 67 | positionLocking.axis = CameraAxis.Horizontal | CameraAxis.Vertical; 68 | positionLocking.enabled = true; 69 | dualForwardFocus.enabled = camWindow.enabled = false; 70 | } 71 | 72 | 73 | if( GUILayout.Button( "Enable Camera Window + Position Locking" ) ) 74 | { 75 | camWindow.enabled = positionLocking.enabled = true; 76 | camWindow.axis = CameraAxis.Vertical; 77 | positionLocking.axis = CameraAxis.Horizontal; 78 | } 79 | 80 | 81 | GUILayout.Space( 20 ); 82 | 83 | GUILayout.Label( "Smoothing" ); 84 | 85 | if( GUILayout.Button( "Enable SmoothDamp" ) ) 86 | CameraKit2D.instance.cameraSmoothingType = CameraSmoothingType.SmoothDamp; 87 | 88 | GUILayout.Label( "Smooth Damp Time" ); 89 | CameraKit2D.instance.smoothDampTime = GUILayout.HorizontalSlider( CameraKit2D.instance.smoothDampTime, 0.01f, 0.4f ); 90 | 91 | 92 | if( GUILayout.Button( "Enable Spring" ) ) 93 | CameraKit2D.instance.cameraSmoothingType = CameraSmoothingType.Spring; 94 | 95 | GUILayout.Label( "Damping Ratio" ); 96 | CameraKit2D.instance.springDampingRatio = GUILayout.HorizontalSlider( CameraKit2D.instance.springDampingRatio, 0.01f, 1.0f ); 97 | GUILayout.Label( "Angular Frequency" ); 98 | CameraKit2D.instance.springAngularFrequency = GUILayout.HorizontalSlider( CameraKit2D.instance.springAngularFrequency, 0.0f, 35f ); 99 | 100 | if( GUILayout.Button( "Enable Lerp" ) ) 101 | CameraKit2D.instance.cameraSmoothingType = CameraSmoothingType.Lerp; 102 | } 103 | } -------------------------------------------------------------------------------- /Assets/CameraKit2DDemo/DemoUI.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9028327498ab34e89b4d3ae48b0fc2fb 3 | timeCreated: 1434423818 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/CameraKit2DDemo/SimplePlayerController.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections.Generic; 3 | using Prime31; 4 | 5 | 6 | public class SimplePlayerController : MonoBehaviour 7 | { 8 | public float maxSpeed = 6f; 9 | public Transform feetTransform; 10 | public float feetRadius = 0.1f; 11 | public float jumpForce = 500f; 12 | 13 | Rigidbody2D _rigidBody; 14 | bool _grounded; 15 | bool grounded 16 | { 17 | get { return _grounded; } 18 | set 19 | { 20 | if( _grounded == value ) 21 | return; 22 | 23 | CameraKit2D.instance.isPlayerGrounded = value; 24 | _grounded = value; 25 | } 26 | } 27 | 28 | 29 | void Awake() 30 | { 31 | Physics2D.gravity = new Vector2( 0f, -25f ); 32 | _rigidBody = GetComponent(); 33 | } 34 | 35 | 36 | void FixedUpdate() 37 | { 38 | grounded = Physics2D.OverlapCircle( feetTransform.position, feetRadius, 1 << LayerMask.NameToLayer( "Default" ) ); 39 | 40 | var move = Input.GetAxis( "Horizontal" ); 41 | _rigidBody.velocity = new Vector2( move * maxSpeed , _rigidBody.velocity.y ); 42 | } 43 | 44 | 45 | void Update() 46 | { 47 | if( _grounded && ( Input.GetKeyDown( KeyCode.Z ) || Input.GetKeyDown( KeyCode.Space ) || Input.GetKeyDown( KeyCode.UpArrow ) ) ) 48 | _rigidBody.AddForce( new Vector2( 0f, jumpForce ) ); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Assets/CameraKit2DDemo/SimplePlayerController.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2d2282f328efb4cc6b098f6d9ae17848 3 | timeCreated: 1434423309 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/CameraKit2DDemo/Slippy.physicsMaterial2D: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prime31/CameraKit2D/ac8f73b6071e469fd07c6acd92adf2ae917b4dca/Assets/CameraKit2DDemo/Slippy.physicsMaterial2D -------------------------------------------------------------------------------- /Assets/CameraKit2DDemo/Slippy.physicsMaterial2D.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ec2481c60913b47d8bb304dd228940ec 3 | timeCreated: 1434424471 4 | licenseType: Pro 5 | NativeFormatImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/CameraKit2DDemo/ZoneMaterial.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prime31/CameraKit2D/ac8f73b6071e469fd07c6acd92adf2ae917b4dca/Assets/CameraKit2DDemo/ZoneMaterial.mat -------------------------------------------------------------------------------- /Assets/CameraKit2DDemo/ZoneMaterial.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4baf6c484a7cc43dcb7ac9873bbbadd6 3 | timeCreated: 1435190683 4 | licenseType: Pro 5 | NativeFormatImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/CameraKit2DDemo/ZoomZone.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections.Generic; 3 | using Prime31; 4 | using System.Collections; 5 | 6 | 7 | /// 8 | /// simple example of how to make a camera zoom zone. Note that if you are using ZestKit this is much easier. Just call 9 | /// CameraKit2D.setOrthographicSize and ZestKit will handle the animation for you. 10 | /// 11 | public class ZoomZone : MonoBehaviour 12 | { 13 | public float zoomDuration = 0.7f; 14 | public bool disableSmoothingDuringZoom; 15 | 16 | float _originalOrthoSize; 17 | 18 | 19 | void OnTriggerEnter2D( Collider2D other ) 20 | { 21 | if( other.gameObject.CompareTag( "Player" ) ) 22 | { 23 | _originalOrthoSize = CameraKit2D.instance.camera.orthographicSize; 24 | StartCoroutine( zoom( 3f ) ); 25 | } 26 | } 27 | 28 | 29 | void OnTriggerExit2D( Collider2D other ) 30 | { 31 | if( other.gameObject.CompareTag( "Player" ) ) 32 | { 33 | StopAllCoroutines(); 34 | StartCoroutine( zoom( _originalOrthoSize ) ); 35 | } 36 | } 37 | 38 | 39 | float ease( float t, float d ) 40 | { 41 | return -1 * ( ( t = t / d - 1 ) * t * t * t - 1 ); 42 | } 43 | 44 | 45 | IEnumerator zoom( float to ) 46 | { 47 | var originalSmoothingType = CameraKit2D.instance.cameraSmoothingType; 48 | if( disableSmoothingDuringZoom ) 49 | CameraKit2D.instance.cameraSmoothingType = CameraSmoothingType.None; 50 | 51 | var from = CameraKit2D.instance.camera.orthographicSize; 52 | var elapsedTime = 0f; 53 | 54 | while( elapsedTime <= zoomDuration ) 55 | { 56 | CameraKit2D.instance.camera.orthographicSize = Mathf.Lerp( from, to, ease( elapsedTime, zoomDuration ) ); 57 | elapsedTime += Time.deltaTime; 58 | yield return null; 59 | } 60 | CameraKit2D.instance.cameraSmoothingType = originalSmoothingType; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /Assets/CameraKit2DDemo/ZoomZone.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b2788a8e3fe7948eba2b0a31988898fc 3 | timeCreated: 1435190612 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a0a713a66c3fc486c8c57cb73425bee9 3 | folderAsset: yes 4 | timeCreated: 1433356309 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Editor/StripGeneratedSolutionSettings.cs: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | v2: Matt Rix pointed out there's an undocumented ONGeneratedCSProjectFiles() callback 4 | https://gist.github.com/MattRix/0bf8de88e16e8b494dbb 5 | 6 | v1: Still available in the gist history if you want a FileSystemWatcher solution! 7 | 8 | THE PROBLEM: 9 | 10 | - Unity constantly rewrites its .sln files whenever you rename/add/remove scripts 11 | - Their solution files includes a bunch of formatting/tab/etc settings 12 | - Unfortunately, MonoDevelop / Xamarin Studio give these settings priority over your other defaults 13 | 14 | (At least sometimes--over here I only get issues maybe once or twice a day) 15 | 16 | THE SOLUTION: 17 | 18 | - Strip out this entire block of settings whenever any .sln file changes 19 | 20 | TO USE: 21 | 22 | - Toss this script anywhere in an Editor/ folder 23 | - Enjoy your tabs not getting constantly mangled! 24 | 25 | Enjoy, 26 | Matthew / Team Colorblind 27 | 28 | */ 29 | 30 | 31 | using UnityEngine; 32 | using UnityEditor; 33 | using System.IO; 34 | using System.Text.RegularExpressions; 35 | 36 | 37 | 38 | public class StripGeneratedSolutionSettings : AssetPostprocessor 39 | { 40 | /// 41 | /// Undocumented callback, thanks Matt Rix! 42 | /// 43 | private static void OnGeneratedCSProjectFiles() 44 | { 45 | var currentDir = Directory.GetCurrentDirectory(); 46 | foreach( var filePath in Directory.GetFiles( currentDir, "*.sln" ) ) 47 | fixSolution( filePath ); 48 | 49 | foreach( var filePath in Directory.GetFiles( currentDir, "*.csproj" ) ) 50 | fixProject( filePath ); 51 | } 52 | 53 | 54 | /// 55 | /// Put any project changes here 56 | /// 57 | /// true, if project was fixed, false otherwise. 58 | /// File path. 59 | static void fixProject( string filePath ) 60 | { 61 | var content = File.ReadAllText( filePath ); 62 | 63 | var searchString = "v3.5"; 64 | var replaceString = "v4.0"; 65 | 66 | if( content.IndexOf( searchString ) != -1 ) 67 | { 68 | content = Regex.Replace( content, searchString, replaceString ); 69 | File.WriteAllText( filePath, content ); 70 | } 71 | } 72 | 73 | 74 | /// 75 | /// Remove settings and .unityproj files 76 | /// 77 | /// true, if solution was fixed, false otherwise. 78 | /// File path. 79 | static void fixSolution( string filePath ) 80 | { 81 | var content = File.ReadAllText( filePath ); 82 | var newContent = content; 83 | 84 | // xamarin studio/monodevelop barf on .unityproj files 85 | var stripUnityProject = @"Project.*?EndProject"; 86 | newContent = Regex.Replace( newContent, stripUnityProject, cleanProjects, RegexOptions.Singleline ); 87 | 88 | // strip out all solution preferences 89 | var stripSettings = @"GlobalSection\(MonoDevelopProperties\)\s=\spreSolution.*EndGlobalSection"; 90 | newContent = Regex.Replace( newContent, stripSettings, "", RegexOptions.Singleline | RegexOptions.RightToLeft ); 91 | 92 | // save back if it was changed 93 | if( content != newContent ) 94 | File.WriteAllText( filePath, newContent ); 95 | } 96 | 97 | 98 | /// 99 | /// If our project match is a .unityproj file, strip it 100 | /// 101 | /// The projects. 102 | /// M. 103 | static string cleanProjects( Match m ) 104 | { 105 | string text = m.ToString(); 106 | 107 | if( text.Contains( ".unityproj" ) ) 108 | return ""; 109 | else 110 | return text; 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /Assets/Editor/StripGeneratedSolutionSettings.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0b550d88e2768470480274357b2880b4 3 | timeCreated: 1433356348 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Packages/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "com.unity.ads": "2.0.8", 4 | "com.unity.analytics": "2.0.16", 5 | "com.unity.package-manager-ui": "1.9.11", 6 | "com.unity.purchasing": "2.0.3", 7 | "com.unity.textmeshpro": "1.2.4", 8 | "com.unity.modules.ai": "1.0.0", 9 | "com.unity.modules.animation": "1.0.0", 10 | "com.unity.modules.assetbundle": "1.0.0", 11 | "com.unity.modules.audio": "1.0.0", 12 | "com.unity.modules.cloth": "1.0.0", 13 | "com.unity.modules.director": "1.0.0", 14 | "com.unity.modules.imageconversion": "1.0.0", 15 | "com.unity.modules.imgui": "1.0.0", 16 | "com.unity.modules.jsonserialize": "1.0.0", 17 | "com.unity.modules.particlesystem": "1.0.0", 18 | "com.unity.modules.physics": "1.0.0", 19 | "com.unity.modules.physics2d": "1.0.0", 20 | "com.unity.modules.screencapture": "1.0.0", 21 | "com.unity.modules.terrain": "1.0.0", 22 | "com.unity.modules.terrainphysics": "1.0.0", 23 | "com.unity.modules.tilemap": "1.0.0", 24 | "com.unity.modules.ui": "1.0.0", 25 | "com.unity.modules.uielements": "1.0.0", 26 | "com.unity.modules.umbra": "1.0.0", 27 | "com.unity.modules.unityanalytics": "1.0.0", 28 | "com.unity.modules.unitywebrequest": "1.0.0", 29 | "com.unity.modules.unitywebrequestassetbundle": "1.0.0", 30 | "com.unity.modules.unitywebrequestaudio": "1.0.0", 31 | "com.unity.modules.unitywebrequesttexture": "1.0.0", 32 | "com.unity.modules.unitywebrequestwww": "1.0.0", 33 | "com.unity.modules.vehicles": "1.0.0", 34 | "com.unity.modules.video": "1.0.0", 35 | "com.unity.modules.vr": "1.0.0", 36 | "com.unity.modules.wind": "1.0.0", 37 | "com.unity.modules.xr": "1.0.0" 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /ProjectSettings/AudioManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prime31/CameraKit2D/ac8f73b6071e469fd07c6acd92adf2ae917b4dca/ProjectSettings/AudioManager.asset -------------------------------------------------------------------------------- /ProjectSettings/ClusterInputManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prime31/CameraKit2D/ac8f73b6071e469fd07c6acd92adf2ae917b4dca/ProjectSettings/ClusterInputManager.asset -------------------------------------------------------------------------------- /ProjectSettings/DynamicsManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prime31/CameraKit2D/ac8f73b6071e469fd07c6acd92adf2ae917b4dca/ProjectSettings/DynamicsManager.asset -------------------------------------------------------------------------------- /ProjectSettings/EditorBuildSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prime31/CameraKit2D/ac8f73b6071e469fd07c6acd92adf2ae917b4dca/ProjectSettings/EditorBuildSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/EditorSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prime31/CameraKit2D/ac8f73b6071e469fd07c6acd92adf2ae917b4dca/ProjectSettings/EditorSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/GraphicsSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prime31/CameraKit2D/ac8f73b6071e469fd07c6acd92adf2ae917b4dca/ProjectSettings/GraphicsSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/InputManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prime31/CameraKit2D/ac8f73b6071e469fd07c6acd92adf2ae917b4dca/ProjectSettings/InputManager.asset -------------------------------------------------------------------------------- /ProjectSettings/NavMeshAreas.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prime31/CameraKit2D/ac8f73b6071e469fd07c6acd92adf2ae917b4dca/ProjectSettings/NavMeshAreas.asset -------------------------------------------------------------------------------- /ProjectSettings/NetworkManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prime31/CameraKit2D/ac8f73b6071e469fd07c6acd92adf2ae917b4dca/ProjectSettings/NetworkManager.asset -------------------------------------------------------------------------------- /ProjectSettings/Physics2DSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prime31/CameraKit2D/ac8f73b6071e469fd07c6acd92adf2ae917b4dca/ProjectSettings/Physics2DSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/PresetManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prime31/CameraKit2D/ac8f73b6071e469fd07c6acd92adf2ae917b4dca/ProjectSettings/PresetManager.asset -------------------------------------------------------------------------------- /ProjectSettings/ProjectSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prime31/CameraKit2D/ac8f73b6071e469fd07c6acd92adf2ae917b4dca/ProjectSettings/ProjectSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/ProjectVersion.txt: -------------------------------------------------------------------------------- 1 | m_EditorVersion: 2018.2.6f1 2 | -------------------------------------------------------------------------------- /ProjectSettings/QualitySettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prime31/CameraKit2D/ac8f73b6071e469fd07c6acd92adf2ae917b4dca/ProjectSettings/QualitySettings.asset -------------------------------------------------------------------------------- /ProjectSettings/TagManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prime31/CameraKit2D/ac8f73b6071e469fd07c6acd92adf2ae917b4dca/ProjectSettings/TagManager.asset -------------------------------------------------------------------------------- /ProjectSettings/TimeManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prime31/CameraKit2D/ac8f73b6071e469fd07c6acd92adf2ae917b4dca/ProjectSettings/TimeManager.asset -------------------------------------------------------------------------------- /ProjectSettings/UnityConnectSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prime31/CameraKit2D/ac8f73b6071e469fd07c6acd92adf2ae917b4dca/ProjectSettings/UnityConnectSettings.asset -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | CameraKit2D 2 | ========== 3 | 4 | CameraKit2D is a 2D camera framework for Unity. This was originally going to be an implementation of the fantastic vocubulary that Itay Karen introduced in his GDC talk (more info available [here](http://bit.ly/1c8bRpI)). After a couple weeks of development the realization that you can't make a great camera system entirely generically was found. Games and cameras are just too specific to have a drop-in, perfect solution. Rather than settle for just a *good* solution CameraKit2D was made into a base framework that is very easy to add your own behaviors to. 5 | 6 | Several components are provided out of the box so you can get up and running quickly and with good examples to make your own behaviors and effectors from. Three different smoothing methods are also provided (smooth damp, spring and lerp). 7 | 8 | 9 | ### Base Camera Behaviors (ICameraBaseBehavior) 10 | 11 | Base camera behaviors are the main controllers of your camera. Included with CameraKit2D in the initial release are the following: Camera Window (vertical, horizontal or both), Dual Forward Focus (direction, threshold or velocity based) and Position Locking (vertical, horizontal or both). They all include Gizmos in the editor so you can visualize how they work. Use these classes as a base to make your own behviors. The only requirement is that you implement the *ICameraBaseBehavior* interface. 12 | 13 | Any Base Camera Behaviors that are components on the same GameObject as the CameraKit2D script will automatically be added in Awake. You can add and remove base camera behaviors at runtime via the *addCameraBaseBehavior* and *removeCameraBaseBehavior* methods. There can be more than one base behavior affecting a camera at any time. This lets you have separate behaviors for horizontal and vertical camera positioning for example. 14 | 15 | Here are some examples of the included base behaviors: 16 | ![camera behaviors](http://cl.ly/bf0D/CameraKit2D.png) 17 | 18 | 19 | ### Effectors (ICameraEffector) 20 | 21 | Effectors let you modify the base camera behavior. These allow you to augment your camera most often based on a specific region in your level. There can be more than one effector active at any time. Effectors also provide a weight which is used to position the camera. Higher weights mean that the effector has more influence on the camera. The *Cue Focus Ring* effector is included as an example. It is a single or dual ring circular trigger that pulls the camera towards it's center when the player enters. An AnimationCurve is used to modify how much the camera is pulled towards the center. 22 | 23 | Creating your own effectors only requires implementing the *ICameraEffector* interface. You can then add and remove your effectors at runtime as needed via the *addCameraEffector* and *removeCameraEffector* methods. 24 | 25 | 26 | ### Finalizers (ICameraFinalizer) 27 | 28 | Finalizers provide a last ditch chance to fully modify the camera position. Unlink base behaviors and effectors finalizers are not weighted. The finalizers are passed the desired position that the base behaviors and effectors calculated. The main use cases for finalizers are hard lines like map bounds (see MapExtentsFinalizer for that one) or constraining movement to a region. 29 | 30 | 31 | ### CameraKit2D Flow 32 | 33 | ![Flow chart](http://cl.ly/beFK/CameraKit2DFlow.png) 34 | 35 | The final result of the base behaviors and the effectors is then passed on to the finalizers. 36 | 37 | 38 | License 39 | ----- 40 | 41 | [Attribution-NonCommercial-ShareAlike 3.0 Unported](http://creativecommons.org/licenses/by-nc-sa/3.0/legalcode) with [simple explanation](http://creativecommons.org/licenses/by-nc-sa/3.0/deed.en_US) with the attribution clause waived. You are free to use CameraKit2D in any and all games that you make. You cannot sell CameraKit2D directly or as part of a larger game asset. 42 | --------------------------------------------------------------------------------