Insanely huge initial commit

This commit is contained in:
2026-02-21 16:40:15 -08:00
parent 2ba1c94b88
commit ee9aee0a1b
33825 changed files with 5213498 additions and 0 deletions

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: df1dfd0554382468e99896521979dc38
folderAsset: yes
timeCreated: 1432593640
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,236 @@
using System;
using UnityEngine;
namespace Com.LuisPedroFonseca.ProCamera2D
{
public abstract class BasePC2D : MonoBehaviour, ISerializationCallbackReceiver
{
public ProCamera2D ProCamera2D
{
get
{
if (_pc2D != null) return _pc2D;
_pc2D = GetComponent<ProCamera2D>();
if (_pc2D == null && Camera.main != null)
_pc2D = Camera.main.GetComponent<ProCamera2D>();
if (_pc2D == null)
_pc2D = FindObjectOfType<ProCamera2D>();
#if UNITY_EDITOR
if (!Application.isPlaying && _pc2D != null && UnityEditor.SceneManagement.EditorSceneManager.preventCrossSceneReferences && _pc2D.gameObject.scene != gameObject.scene)
{
Debug.LogWarning("ProCamera2D is in a different scene. Cross scene references are not supported during edit mode but everything will work correctly during play. Unfortunately the cross scene reference warnings are unavoidable at the moment.");
}
#endif
return _pc2D;
}
set { _pc2D = value; }
}
[SerializeField]
private ProCamera2D _pc2D;
protected Func<Vector3, float> Vector3H;
protected Func<Vector3, float> Vector3V;
protected Func<Vector3, float> Vector3D;
protected Func<float, float, Vector3> VectorHV;
protected Func<float, float, float, Vector3> VectorHVD;
protected Transform _transform;
bool _enabled;
[SerializeField, HideInInspector] private MovementAxis _serializedAxis;
protected virtual void Awake()
{
_transform = transform;
if(enabled)
Enable();
ResetAxisFunctions();
}
protected virtual void OnEnable()
{
Enable();
}
protected virtual void OnDisable()
{
Disable();
}
protected virtual void OnDestroy()
{
Disable();
}
/// <summary>Called when the method Reset is called on the Core. Use it to reset an extension.</summary>
public virtual void OnReset()
{
}
void Enable()
{
if (_enabled || _pc2D == null)
return;
_enabled = true;
_pc2D.OnReset += OnReset;
}
void Disable()
{
if (_pc2D != null && _enabled)
{
_enabled = false;
_pc2D.OnReset -= OnReset;
}
}
void ResetAxisFunctions()
{
if (Vector3H != null || ProCamera2D == null)
return;
switch (_pc2D.Axis)
{
case MovementAxis.XY:
Vector3H = vector => vector.x;
Vector3V = vector => vector.y;
Vector3D = vector => vector.z;
VectorHV = (h, v) => new Vector3(h, v, 0);
VectorHVD = (h, v, d) => new Vector3(h, v, d);
break;
case MovementAxis.XZ:
Vector3H = vector => vector.x;
Vector3V = vector => vector.z;
Vector3D = vector => vector.y;
VectorHV = (h, v) => new Vector3(h, 0, v);
VectorHVD = (h, v, d) => new Vector3(h, d, v);
break;
case MovementAxis.YZ:
Vector3H = vector => vector.z;
Vector3V = vector => vector.y;
Vector3D = vector => vector.x;
VectorHV = (h, v) => new Vector3(0, v, h);
VectorHVD = (h, v, d) => new Vector3(d, v, h);
break;
}
}
#if UNITY_EDITOR
int _drawGizmosCounter;
void OnDrawGizmos()
{
if (!enabled)
return;
if (_pc2D == null && Camera.main != null)
_pc2D = Camera.main.GetComponent<ProCamera2D>();
if (_pc2D == null)
return;
// Don't draw gizmos on other cameras
if (Camera.current != _pc2D.GameCamera &&
((UnityEditor.SceneView.lastActiveSceneView != null && Camera.current != UnityEditor.SceneView.lastActiveSceneView.camera) ||
(UnityEditor.SceneView.lastActiveSceneView == null)))
return;
ResetAxisFunctions();
// HACK to prevent Unity bug on startup: http://forum.unity3d.com/threads/screen-position-out-of-view-frustum.9918/
_drawGizmosCounter++;
if (_drawGizmosCounter < 5 && UnityEditor.EditorApplication.timeSinceStartup < 60f)
return;
DrawGizmos();
}
void OnDrawGizmosSelected()
{
if (!enabled)
return;
if (_pc2D == null && Camera.main != null)
_pc2D = Camera.main.GetComponent<ProCamera2D>();
if (_pc2D == null)
return;
// Don't draw gizmos on other cameras
if (Camera.current != _pc2D.GameCamera &&
((UnityEditor.SceneView.lastActiveSceneView != null && Camera.current != UnityEditor.SceneView.lastActiveSceneView.camera) ||
(UnityEditor.SceneView.lastActiveSceneView == null)))
return;
ResetAxisFunctions();
// HACK to prevent Unity bug on startup: http://forum.unity3d.com/threads/screen-position-out-of-view-frustum.9918/
_drawGizmosCounter++;
if (_drawGizmosCounter < 5 && UnityEditor.EditorApplication.timeSinceStartup < 60f)
return;
DrawGizmosSelected();
}
protected virtual void DrawGizmos()
{
}
protected virtual void DrawGizmosSelected()
{
}
#endif
#region ISerializationCallbackReceiver
public void OnBeforeSerialize()
{
if (ProCamera2D != null)
{
_serializedAxis = ProCamera2D.Axis;
}
}
public void OnAfterDeserialize()
{
switch (_serializedAxis)
{
case MovementAxis.XY:
Vector3H = vector => vector.x;
Vector3V = vector => vector.y;
Vector3D = vector => vector.z;
VectorHV = (h, v) => new Vector3(h, v, 0);
VectorHVD = (h, v, d) => new Vector3(h, v, d);
break;
case MovementAxis.XZ:
Vector3H = vector => vector.x;
Vector3V = vector => vector.z;
Vector3D = vector => vector.y;
VectorHV = (h, v) => new Vector3(h, 0, v);
VectorHVD = (h, v, d) => new Vector3(h, d, v);
break;
case MovementAxis.YZ:
Vector3H = vector => vector.z;
Vector3V = vector => vector.y;
Vector3D = vector => vector.x;
VectorHV = (h, v) => new Vector3(0, v, h);
VectorHVD = (h, v, d) => new Vector3(d, v, h);
break;
default:
throw new ArgumentOutOfRangeException();
}
}
#endregion
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 4eeae9fa8562d4f4eb938bab965d71ff
timeCreated: 1453709387
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,230 @@
using System;
using System.Collections;
using UnityEngine;
namespace Com.LuisPedroFonseca.ProCamera2D
{
abstract public class BaseTrigger : BasePC2D
{
public Action OnEnteredTrigger;
public Action OnExitedTrigger;
[TooltipAttribute("Every X seconds detect collision. Smaller intervals are more precise but also require more processing.")]
public float UpdateInterval = .1f;
public TriggerShape TriggerShape;
[TooltipAttribute("If enabled, use the targets mid point to know when inside/outside the trigger.")]
public bool UseTargetsMidPoint = true;
[TooltipAttribute("If UseTargetsMidPoint is disabled, use this transform to know when inside/outside the trigger.")]
public Transform TriggerTarget;
protected float _exclusiveInfluencePercentage;
Coroutine _testTriggerRoutine;
protected bool _insideTrigger;
protected Vector2 _vectorFromPointToCenter;
protected int _instanceID;
bool _triggerEnabled;
protected override void Awake()
{
base.Awake();
if (ProCamera2D == null)
return;
_instanceID = GetInstanceID();
// Small random time offset to avoid having all the triggers calculatations on the same frame
UpdateInterval += UnityEngine.Random.Range(-.02f, .02f);
// Start update routine
Toggle(true);
}
override protected void OnEnable()
{
base.OnEnable();
if(ProCamera2D == null)
return;
if (_triggerEnabled)
Toggle(true);
}
override protected void OnDisable()
{
base.OnDisable();
_testTriggerRoutine = null;
}
/// <summary>Manually enable or disable the trigger</summary>
/// <param name="value">If true it will enable the trigger. If false it will disable it.</param>
public void Toggle(bool value)
{
if (value)
{
if (_testTriggerRoutine == null)
_testTriggerRoutine = StartCoroutine(TestTriggerRoutine());
_triggerEnabled = true;
}
else
{
if (_testTriggerRoutine != null)
{
StopCoroutine(_testTriggerRoutine);
_testTriggerRoutine = null;
}
if (_insideTrigger)
ExitedTrigger();
_triggerEnabled = false;
}
}
/// <summary>Manually force the trigger to test if the target(s) is inside it</summary>
public void TestTrigger()
{
var triggerPos = ProCamera2D.TargetsMidPoint;
if (!UseTargetsMidPoint && TriggerTarget != null)
triggerPos = TriggerTarget.position;
if (TriggerShape == TriggerShape.RECTANGLE &&
Utils.IsInsideRectangle(
Vector3H(_transform.position),
Vector3V(_transform.position),
Vector3H(_transform.localScale),
Vector3V(_transform.localScale),
Vector3H(triggerPos),
Vector3V(triggerPos)))
{
if (!_insideTrigger)
EnteredTrigger();
}
else if (TriggerShape == TriggerShape.CIRCLE &&
Utils.IsInsideCircle(
Vector3H(_transform.position),
Vector3V(_transform.position),
(Vector3H(_transform.localScale) + Vector3V(_transform.localScale)) * .25f,
Vector3H(triggerPos),
Vector3V(triggerPos)))
{
if (!_insideTrigger)
EnteredTrigger();
}
else
{
if (_insideTrigger)
ExitedTrigger();
}
}
protected virtual void EnteredTrigger()
{
_insideTrigger = true;
if (OnEnteredTrigger != null)
OnEnteredTrigger();
}
protected virtual void ExitedTrigger()
{
_insideTrigger = false;
if (OnExitedTrigger != null)
OnExitedTrigger();
}
IEnumerator TestTriggerRoutine()
{
yield return new WaitForEndOfFrame();
var waitForSeconds = new WaitForSeconds(UpdateInterval);
var waitForSecondsRealtime = new WaitForSecondsRealtime(UpdateInterval);
while (true)
{
TestTrigger();
if(ProCamera2D.IgnoreTimeScale)
yield return waitForSecondsRealtime;
else
yield return waitForSeconds;
}
}
protected float GetDistanceToCenterPercentage(Vector2 point)
{
_vectorFromPointToCenter = point - new Vector2(Vector3H(_transform.position), Vector3V(_transform.position));
if (TriggerShape == TriggerShape.RECTANGLE)
{
var distancePercentageH = Vector3H(_vectorFromPointToCenter) / (Vector3H(_transform.localScale) * .5f);
var distancePercentageV = Vector3V(_vectorFromPointToCenter) / (Vector3V(_transform.localScale) * .5f);
var distancePercentage = (Mathf.Max(Mathf.Abs(distancePercentageH), Mathf.Abs(distancePercentageV))).Remap(_exclusiveInfluencePercentage, 1, 0, 1);
return distancePercentage;
}
else
{
var distancePercentage = (_vectorFromPointToCenter.magnitude / ((Vector3H(_transform.localScale) + Vector3V(_transform.localScale)) * .25f)).Remap(_exclusiveInfluencePercentage, 1, 0, 1);
return distancePercentage;
}
}
#if UNITY_EDITOR
override protected void DrawGizmos()
{
float cameraDepthOffset = Vector3D(ProCamera2D.transform.localPosition) + Mathf.Abs(Vector3D(ProCamera2D.transform.localPosition)) * Vector3D(ProCamera2D.transform.forward);
var cameraCenter = VectorHVD(Vector3H(transform.position), Vector3V(transform.position), cameraDepthOffset);
Gizmos.color = EditorPrefsX.GetColor(PrefsData.TriggerShapeColorKey, PrefsData.TriggerShapeColorValue);
if (TriggerShape == TriggerShape.RECTANGLE)
{
Gizmos.DrawWireCube(cameraCenter, VectorHVD(Vector3H(transform.localScale), Vector3V(transform.localScale), 0f));
if (_exclusiveInfluencePercentage > 0)
Gizmos.DrawWireCube(cameraCenter, VectorHVD(Vector3H(transform.localScale) * _exclusiveInfluencePercentage, Vector3V(transform.localScale) * _exclusiveInfluencePercentage, 0f));
}
else
{
var axis = Vector3.zero;
switch (ProCamera2D.Axis)
{
case MovementAxis.XY:
axis = new Vector3(1f, 1f, 0f);
break;
case MovementAxis.XZ:
axis = new Vector3(1f, 0f, 1f);
break;
case MovementAxis.YZ:
axis = new Vector3(0f, 1f, 1f);
break;
}
Gizmos.matrix = Matrix4x4.TRS(cameraCenter, Quaternion.identity, axis);
Gizmos.DrawWireSphere(Vector3.zero, ((Vector3H(transform.localScale) + Vector3V(transform.localScale)) * .25f));
if (_exclusiveInfluencePercentage > 0)
Gizmos.DrawWireSphere(Vector3.zero, ((Vector3H(transform.localScale) + Vector3V(transform.localScale)) * .25f) * _exclusiveInfluencePercentage);
Gizmos.matrix = Matrix4x4.identity;
}
}
#endif
}
public enum TriggerShape
{
CIRCLE,
RECTANGLE
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: b36ebbbf1bc7e4c5e8cbd8a2b01ac67d
timeCreated: 1453709387
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,372 @@
using UnityEngine;
using System;
using System.Collections;
namespace Com.LuisPedroFonseca.ProCamera2D
{
public class BoundariesAnimator
{
public Action OnTransitionStarted;
public Action OnTransitionFinished;
public bool UseTopBoundary;
public float TopBoundary;
public bool UseBottomBoundary;
public float BottomBoundary;
public bool UseLeftBoundary;
public float LeftBoundary;
public bool UseRightBoundary;
public float RightBoundary;
public float TransitionDuration = 1f;
public EaseType TransitionEaseType;
ProCamera2D ProCamera2D;
ProCamera2DNumericBoundaries NumericBoundaries;
Func<Vector3, float> Vector3H;
Func<Vector3, float> Vector3V;
public BoundariesAnimator(ProCamera2D proCamera2D, ProCamera2DNumericBoundaries numericBoundaries)
{
ProCamera2D = proCamera2D;
NumericBoundaries = numericBoundaries;
switch (ProCamera2D.Axis)
{
case MovementAxis.XY:
Vector3H = vector => vector.x;
Vector3V = vector => vector.y;
break;
case MovementAxis.XZ:
Vector3H = vector => vector.x;
Vector3V = vector => vector.z;
break;
case MovementAxis.YZ:
Vector3H = vector => vector.z;
Vector3V = vector => vector.y;
break;
}
}
public int GetAnimsCount()
{
var animsCount = 0;
if (UseLeftBoundary)
animsCount++;
else if (!UseLeftBoundary && NumericBoundaries.UseLeftBoundary && UseRightBoundary && RightBoundary < NumericBoundaries.TargetLeftBoundary)
animsCount++;
if (UseRightBoundary)
animsCount++;
else if (!UseRightBoundary && NumericBoundaries.UseRightBoundary && UseLeftBoundary && LeftBoundary > NumericBoundaries.TargetRightBoundary)
animsCount++;
if (UseTopBoundary)
animsCount++;
else if (!UseTopBoundary && NumericBoundaries.UseTopBoundary && UseBottomBoundary && BottomBoundary > NumericBoundaries.TargetTopBoundary)
animsCount++;
if (UseBottomBoundary)
animsCount++;
else if (!UseBottomBoundary && NumericBoundaries.UseBottomBoundary && UseTopBoundary && TopBoundary < NumericBoundaries.TargetBottomBoundary)
animsCount++;
return animsCount;
}
public void Transition()
{
if (!NumericBoundaries.HasFiredTransitionStarted && OnTransitionStarted != null)
{
NumericBoundaries.HasFiredTransitionStarted = true;
OnTransitionStarted();
}
NumericBoundaries.HasFiredTransitionFinished = false;
NumericBoundaries.UseNumericBoundaries = true;
// Animate boundaries
if (UseLeftBoundary)
{
NumericBoundaries.UseLeftBoundary = true;
if (NumericBoundaries.LeftBoundaryAnimRoutine != null)
NumericBoundaries.StopCoroutine(NumericBoundaries.LeftBoundaryAnimRoutine);
NumericBoundaries.LeftBoundaryAnimRoutine = NumericBoundaries.StartCoroutine(LeftTransitionRoutine(TransitionDuration));
}
else if (!UseLeftBoundary && NumericBoundaries.UseLeftBoundary && UseRightBoundary && RightBoundary < NumericBoundaries.TargetLeftBoundary)
{
NumericBoundaries.UseLeftBoundary = true;
UseLeftBoundary = true;
LeftBoundary = RightBoundary - ProCamera2D.ScreenSizeInWorldCoordinates.x * 100f;
if (NumericBoundaries.LeftBoundaryAnimRoutine != null)
NumericBoundaries.StopCoroutine(NumericBoundaries.LeftBoundaryAnimRoutine);
NumericBoundaries.LeftBoundaryAnimRoutine = NumericBoundaries.StartCoroutine(LeftTransitionRoutine(TransitionDuration, true));
}
else if (!UseLeftBoundary)
{
NumericBoundaries.UseLeftBoundary = false;
}
if (UseRightBoundary)
{
NumericBoundaries.UseRightBoundary = true;
if (NumericBoundaries.RightBoundaryAnimRoutine != null)
NumericBoundaries.StopCoroutine(NumericBoundaries.RightBoundaryAnimRoutine);
NumericBoundaries.RightBoundaryAnimRoutine = NumericBoundaries.StartCoroutine(RightTransitionRoutine(TransitionDuration));
}
else if (!UseRightBoundary && NumericBoundaries.UseRightBoundary && UseLeftBoundary && LeftBoundary > NumericBoundaries.TargetRightBoundary)
{
NumericBoundaries.UseRightBoundary = true;
UseRightBoundary = true;
RightBoundary = LeftBoundary + ProCamera2D.ScreenSizeInWorldCoordinates.x * 100f;
if (NumericBoundaries.RightBoundaryAnimRoutine != null)
NumericBoundaries.StopCoroutine(NumericBoundaries.RightBoundaryAnimRoutine);
NumericBoundaries.RightBoundaryAnimRoutine = NumericBoundaries.StartCoroutine(RightTransitionRoutine(TransitionDuration, true));
}
else if (!UseRightBoundary)
{
NumericBoundaries.UseRightBoundary = false;
}
if (UseTopBoundary)
{
NumericBoundaries.UseTopBoundary = true;
if (NumericBoundaries.TopBoundaryAnimRoutine != null)
NumericBoundaries.StopCoroutine(NumericBoundaries.TopBoundaryAnimRoutine);
NumericBoundaries.TopBoundaryAnimRoutine = NumericBoundaries.StartCoroutine(TopTransitionRoutine(TransitionDuration));
}
else if (!UseTopBoundary && NumericBoundaries.UseTopBoundary && UseBottomBoundary && BottomBoundary > NumericBoundaries.TargetTopBoundary)
{
NumericBoundaries.UseTopBoundary = true;
UseTopBoundary = true;
TopBoundary = BottomBoundary + ProCamera2D.ScreenSizeInWorldCoordinates.y * 100f;
if (NumericBoundaries.TopBoundaryAnimRoutine != null)
NumericBoundaries.StopCoroutine(NumericBoundaries.TopBoundaryAnimRoutine);
NumericBoundaries.TopBoundaryAnimRoutine = NumericBoundaries.StartCoroutine(TopTransitionRoutine(TransitionDuration, true));
}
else if (!UseTopBoundary)
{
NumericBoundaries.UseTopBoundary = false;
}
if (UseBottomBoundary)
{
NumericBoundaries.UseBottomBoundary = true;
if (NumericBoundaries.BottomBoundaryAnimRoutine != null)
NumericBoundaries.StopCoroutine(NumericBoundaries.BottomBoundaryAnimRoutine);
NumericBoundaries.BottomBoundaryAnimRoutine = NumericBoundaries.StartCoroutine(BottomTransitionRoutine(TransitionDuration));
}
else if (!UseBottomBoundary && NumericBoundaries.UseBottomBoundary && UseTopBoundary && TopBoundary < NumericBoundaries.TargetBottomBoundary)
{
NumericBoundaries.UseBottomBoundary = true;
UseBottomBoundary = true;
BottomBoundary = TopBoundary - ProCamera2D.ScreenSizeInWorldCoordinates.y * 100f;
if (NumericBoundaries.BottomBoundaryAnimRoutine != null)
NumericBoundaries.StopCoroutine(NumericBoundaries.BottomBoundaryAnimRoutine);
NumericBoundaries.BottomBoundaryAnimRoutine = NumericBoundaries.StartCoroutine(BottomTransitionRoutine(TransitionDuration, true));
}
else if (!UseBottomBoundary)
{
NumericBoundaries.UseBottomBoundary = false;
}
}
IEnumerator LeftTransitionRoutine(float duration, bool turnOffBoundaryAfterwards = false)
{
var initialLeftBoundary = Vector3H(ProCamera2D.LocalPosition) - ProCamera2D.ScreenSizeInWorldCoordinates.x / 2;
NumericBoundaries.TargetLeftBoundary = LeftBoundary;
var t = 0f;
while (t <= 1.0f)
{
t += ProCamera2D.DeltaTime / duration;
// Move left
if (UseLeftBoundary && UseRightBoundary && LeftBoundary < initialLeftBoundary)
{
NumericBoundaries.LeftBoundary = LeftBoundary;
}
// Move right
else if (UseLeftBoundary)
{
NumericBoundaries.LeftBoundary = Utils.EaseFromTo(initialLeftBoundary, LeftBoundary, t, TransitionEaseType);
var currentCamLeftEdge = Vector3H(ProCamera2D.LocalPosition) - ProCamera2D.ScreenSizeInWorldCoordinates.x / 2;
if (currentCamLeftEdge < NumericBoundaries.TargetLeftBoundary &&
NumericBoundaries.LeftBoundary < currentCamLeftEdge)
NumericBoundaries.LeftBoundary = currentCamLeftEdge;
}
yield return ProCamera2D.GetYield();
}
if (turnOffBoundaryAfterwards)
{
NumericBoundaries.UseLeftBoundary = false;
UseLeftBoundary = false;
}
if (!NumericBoundaries.HasFiredTransitionFinished && OnTransitionFinished != null)
{
NumericBoundaries.HasFiredTransitionStarted = false;
NumericBoundaries.HasFiredTransitionFinished = true;
OnTransitionFinished();
}
}
IEnumerator RightTransitionRoutine(float duration, bool turnOffBoundaryAfterwards = false)
{
var initialRightBoundary = Vector3H(ProCamera2D.LocalPosition) + ProCamera2D.ScreenSizeInWorldCoordinates.x / 2;
NumericBoundaries.TargetRightBoundary = RightBoundary;
var t = 0f;
while (t <= 1.0f)
{
t += ProCamera2D.DeltaTime / duration;
// Move right
if (UseRightBoundary && UseLeftBoundary && RightBoundary > initialRightBoundary)
{
NumericBoundaries.RightBoundary = RightBoundary;
}
// Move left
else if (UseRightBoundary)
{
NumericBoundaries.RightBoundary = Utils.EaseFromTo(initialRightBoundary, RightBoundary, t, TransitionEaseType);
var currentCamRightEdge = Vector3H(ProCamera2D.LocalPosition) + ProCamera2D.ScreenSizeInWorldCoordinates.x / 2;
if (currentCamRightEdge > NumericBoundaries.TargetRightBoundary &&
NumericBoundaries.RightBoundary > currentCamRightEdge)
NumericBoundaries.RightBoundary = currentCamRightEdge;
}
yield return ProCamera2D.GetYield();
}
if (turnOffBoundaryAfterwards)
{
NumericBoundaries.UseRightBoundary = false;
UseRightBoundary = false;
}
if (!NumericBoundaries.HasFiredTransitionFinished && OnTransitionFinished != null)
{
NumericBoundaries.HasFiredTransitionStarted = false;
NumericBoundaries.HasFiredTransitionFinished = true;
OnTransitionFinished();
}
}
IEnumerator TopTransitionRoutine(float duration, bool turnOffBoundaryAfterwards = false)
{
var initialTopBoundary = Vector3V(ProCamera2D.LocalPosition) + ProCamera2D.ScreenSizeInWorldCoordinates.y / 2;
NumericBoundaries.TargetTopBoundary = TopBoundary;
var t = 0f;
while (t <= 1.0f)
{
t += ProCamera2D.DeltaTime / duration;
// Move up
if (UseTopBoundary && UseBottomBoundary && TopBoundary > initialTopBoundary)
{
NumericBoundaries.TopBoundary = TopBoundary;
}
// Move down
else if (UseTopBoundary)
{
NumericBoundaries.TopBoundary = Utils.EaseFromTo(initialTopBoundary, TopBoundary, t, TransitionEaseType);
var currentCamTopEdge = Vector3V(ProCamera2D.LocalPosition) + ProCamera2D.ScreenSizeInWorldCoordinates.y / 2;
if (currentCamTopEdge > NumericBoundaries.TargetTopBoundary &&
NumericBoundaries.TopBoundary > currentCamTopEdge)
NumericBoundaries.TopBoundary = currentCamTopEdge;
}
yield return ProCamera2D.GetYield();
}
if (turnOffBoundaryAfterwards)
{
NumericBoundaries.UseTopBoundary = false;
UseTopBoundary = false;
}
if (!NumericBoundaries.HasFiredTransitionFinished && OnTransitionFinished != null)
{
NumericBoundaries.HasFiredTransitionStarted = false;
NumericBoundaries.HasFiredTransitionFinished = true;
OnTransitionFinished();
}
}
IEnumerator BottomTransitionRoutine(float duration, bool turnOffBoundaryAfterwards = false)
{
var initialBottomBoundary = Vector3V(ProCamera2D.LocalPosition) - ProCamera2D.ScreenSizeInWorldCoordinates.y / 2;
NumericBoundaries.TargetBottomBoundary = BottomBoundary;
var t = 0f;
while (t <= 1.0f)
{
t += ProCamera2D.DeltaTime / duration;
// Move down
if (UseBottomBoundary && UseTopBoundary && BottomBoundary < initialBottomBoundary)
{
NumericBoundaries.BottomBoundary = BottomBoundary;
}
// Move up
else if (UseBottomBoundary)
{
NumericBoundaries.BottomBoundary = Utils.EaseFromTo(initialBottomBoundary, BottomBoundary, t, TransitionEaseType);
var currentCamBottomEdge = Vector3V(ProCamera2D.LocalPosition) - ProCamera2D.ScreenSizeInWorldCoordinates.y / 2;
if (currentCamBottomEdge < NumericBoundaries.TargetBottomBoundary &&
NumericBoundaries.BottomBoundary < currentCamBottomEdge)
NumericBoundaries.BottomBoundary = currentCamBottomEdge;
}
yield return ProCamera2D.GetYield();
}
if (turnOffBoundaryAfterwards)
{
NumericBoundaries.UseBottomBoundary = false;
UseBottomBoundary = false;
}
if (!NumericBoundaries.HasFiredTransitionFinished && OnTransitionFinished != null)
{
NumericBoundaries.HasFiredTransitionStarted = false;
NumericBoundaries.HasFiredTransitionFinished = true;
OnTransitionFinished();
}
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 189a6e28bac9643759ef1b01a4328d01
timeCreated: 1429281456
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,40 @@
using System;
using UnityEngine;
namespace Com.LuisPedroFonseca.ProCamera2D
{
[Serializable]
public class CameraTarget
{
public Transform TargetTransform;
public float TargetInfluence
{
set
{
TargetInfluenceH = value;
TargetInfluenceV = value;
}
}
[RangeAttribute(0f, 1f)]
public float TargetInfluenceH = 1f;
[RangeAttribute(0f, 1f)]
public float TargetInfluenceV = 1f;
public Vector2 TargetOffset;
public Vector3 TargetPosition
{
get
{
if (TargetTransform != null)
return _targetPosition = TargetTransform.position;
else
return _targetPosition;
}
}
Vector3 _targetPosition;
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 3e0fcaf74434343259050f5f11d998f0
timeCreated: 1432593543
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,29 @@
using System.Collections.Generic;
using UnityEngine;
namespace Com.LuisPedroFonseca.ProCamera2D
{
[System.Serializable]
[CreateAssetMenu(menuName = "ProCamera2D/Constant Shake Preset")]
public class ConstantShakePreset : ScriptableObject
{
public float Intensity = .3f;
public List<ConstantShakeLayer> Layers;
}
[System.Serializable]
public struct ConstantShakeLayer
{
[MinMaxSlider(0.001f, 10f)]
public Vector2 Frequency;
[Range(0f, 100f)]
public float AmplitudeHorizontal;
[Range(0f, 100f)]
public float AmplitudeVertical;
[Range(0f, 100f)]
public float AmplitudeDepth;
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 2b203a55d908247b5a828b0c77fca2c1
timeCreated: 1487263380
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,9 @@
namespace Com.LuisPedroFonseca.ProCamera2D
{
public enum MovementAxis
{
XY,
XZ,
YZ
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 2156a7911234749219b1562c116fbae8
timeCreated: 1432599265
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,9 @@
namespace Com.LuisPedroFonseca.ProCamera2D
{
public enum UpdateType
{
LateUpdate,
FixedUpdate,
ManualUpdate
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 40bf6ecc65d754092959189e66e01906
timeCreated: 1432599301
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,11 @@
using UnityEngine;
namespace Com.LuisPedroFonseca.ProCamera2D
{
public interface IPositionDeltaChanger
{
Vector3 AdjustDelta(float deltaTime, Vector3 originalDelta);
int PDCOrder { get; set;}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 115d44f578d1f4b0895ea97e52aaff1c
timeCreated: 1454609120
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,11 @@
using UnityEngine;
namespace Com.LuisPedroFonseca.ProCamera2D
{
public interface IPositionOverrider
{
Vector3 OverridePosition(float deltaTime, Vector3 originalPosition);
int POOrder { get; set; }
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: b7f0378f234734fe1bcee70739d44960
timeCreated: 1454652912
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,11 @@
using UnityEngine;
namespace Com.LuisPedroFonseca.ProCamera2D
{
public interface IPostMover
{
void PostMove(float deltaTime);
int PMOrder { get; set; }
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: bfb0d95b2946d4048b4a72b3c5c88a4d
timeCreated: 1455021848
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,11 @@
using UnityEngine;
namespace Com.LuisPedroFonseca.ProCamera2D
{
public interface IPreMover
{
void PreMove(float deltaTime);
int PrMOrder { get; set; }
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 32bf46b1206e344308f4d7b271c6676c
timeCreated: 1455023700
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,9 @@
namespace Com.LuisPedroFonseca.ProCamera2D
{
public interface ISizeDeltaChanger
{
float AdjustSize(float deltaTime, float originalDelta);
int SDCOrder { get; set;}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 434498afe170f4dd0bb5bab7925edfbc
timeCreated: 1454660357
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,9 @@
namespace Com.LuisPedroFonseca.ProCamera2D
{
public interface ISizeOverrider
{
float OverrideSize(float deltaTime, float originalSize);
int SOOrder { get; set;}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 2fa9ca6042aa143529e3cb816d3b4cae
timeCreated: 1454659084
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,246 @@
// KDTree.cs - A Stark, September 2009.
// This class implements a data structure that stores a list of points in space.
// A common task in game programming is to take a supplied point and discover which
// of a stored set of points is nearest to it. For example, in path-plotting, it is often
// useful to know which waypoint is nearest to the player's current
// position. The kd-tree allows this "nearest neighbour" search to be carried out quickly,
// or at least much more quickly than a simple linear search through the list.
// At present, the class only allows for construction (using the MakeFromPoints static method)
// and nearest-neighbour searching (using FindNearest). More exotic kd-trees are possible, and
// this class may be extended in the future if there seems to be a need.
// The nearest-neighbour search returns an integer index - it is assumed that the original
// array of points is available for the lifetime of the tree, and the index refers to that
// array.
using UnityEngine;
using System.Collections;
namespace Com.LuisPedroFonseca.ProCamera2D
{
public class KDTree
{
public KDTree[] lr;
public Vector3 pivot;
public int pivotIndex;
public int axis;
// Change this value to 2 if you only need two-dimensional X,Y points. The search will
// be quicker in two dimensions.
const int numDims = 3;
public KDTree()
{
lr = new KDTree[2];
}
// Make a new tree from a list of points.
public static KDTree MakeFromPoints(params Vector3[] points)
{
int[] indices = Iota(points.Length);
return MakeFromPointsInner(0, 0, points.Length - 1, points, indices);
}
// Recursively build a tree by separating points at plane boundaries.
static KDTree MakeFromPointsInner(
int depth,
int stIndex, int enIndex,
Vector3[] points,
int[] inds
)
{
KDTree root = new KDTree();
root.axis = depth % numDims;
int splitPoint = FindPivotIndex(points, inds, stIndex, enIndex, root.axis);
root.pivotIndex = inds[splitPoint];
root.pivot = points[root.pivotIndex];
int leftEndIndex = splitPoint - 1;
if (leftEndIndex >= stIndex)
{
root.lr[0] = MakeFromPointsInner(depth + 1, stIndex, leftEndIndex, points, inds);
}
int rightStartIndex = splitPoint + 1;
if (rightStartIndex <= enIndex)
{
root.lr[1] = MakeFromPointsInner(depth + 1, rightStartIndex, enIndex, points, inds);
}
return root;
}
static void SwapElements(int[] arr, int a, int b)
{
int temp = arr[a];
arr[a] = arr[b];
arr[b] = temp;
}
// Simple "median of three" heuristic to find a reasonable splitting plane.
static int FindSplitPoint(Vector3[] points, int[] inds, int stIndex, int enIndex, int axis)
{
float a = points[inds[stIndex]][axis];
float b = points[inds[enIndex]][axis];
int midIndex = (stIndex + enIndex) / 2;
float m = points[inds[midIndex]][axis];
if (a > b)
{
if (m > a)
{
return stIndex;
}
if (b > m)
{
return enIndex;
}
return midIndex;
}
else
{
if (a > m)
{
return stIndex;
}
if (m > b)
{
return enIndex;
}
return midIndex;
}
}
// Find a new pivot index from the range by splitting the points that fall either side
// of its plane.
public static int FindPivotIndex(Vector3[] points, int[] inds, int stIndex, int enIndex, int axis)
{
int splitPoint = FindSplitPoint(points, inds, stIndex, enIndex, axis);
// int splitPoint = Random.Range(stIndex, enIndex);
Vector3 pivot = points[inds[splitPoint]];
SwapElements(inds, stIndex, splitPoint);
int currPt = stIndex + 1;
int endPt = enIndex;
while (currPt <= endPt)
{
Vector3 curr = points[inds[currPt]];
if ((curr[axis] > pivot[axis]))
{
SwapElements(inds, currPt, endPt);
endPt--;
}
else
{
SwapElements(inds, currPt - 1, currPt);
currPt++;
}
}
return currPt - 1;
}
public static int[] Iota(int num)
{
int[] result = new int[num];
for (int i = 0; i < num; i++)
{
result[i] = i;
}
return result;
}
// Find the nearest point in the set to the supplied point.
public int FindNearest(Vector3 pt)
{
float bestSqDist = 1000000000f;
int bestIndex = -1;
Search(pt, ref bestSqDist, ref bestIndex);
return bestIndex;
}
// Recursively search the tree.
void Search(Vector3 pt, ref float bestSqSoFar, ref int bestIndex)
{
float mySqDist = (pivot - pt).sqrMagnitude;
if (mySqDist < bestSqSoFar)
{
bestSqSoFar = mySqDist;
bestIndex = pivotIndex;
}
float planeDist = pt[axis] - pivot[axis]; //DistFromSplitPlane(pt, pivot, axis);
int selector = planeDist <= 0 ? 0 : 1;
if (lr[selector] != null)
{
lr[selector].Search(pt, ref bestSqSoFar, ref bestIndex);
}
selector = (selector + 1) % 2;
float sqPlaneDist = planeDist * planeDist;
if ((lr[selector] != null) && (bestSqSoFar > sqPlaneDist))
{
lr[selector].Search(pt, ref bestSqSoFar, ref bestIndex);
}
}
// Get a point's distance from an axis-aligned plane.
float DistFromSplitPlane(Vector3 pt, Vector3 planePt, int axis)
{
return pt[axis] - planePt[axis];
}
// Simple output of tree structure - mainly useful for getting a rough
// idea of how deep the tree is (and therefore how well the splitting
// heuristic is performing).
public string Dump(int level)
{
string result = pivotIndex.ToString().PadLeft(level) + "\n";
if (lr[0] != null)
{
result += lr[0].Dump(level + 2);
}
if (lr[1] != null)
{
result += lr[1].Dump(level + 2);
}
return result;
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: d9a1cf7ede4d947249edafbcf3c2bbed
timeCreated: 1447935924
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,247 @@
using System;
using UnityEngine;
namespace Com.LuisPedroFonseca.ProCamera2D
{
public struct RaycastOrigins
{
public Vector3 TopRight;
public Vector3 TopLeft;
public Vector3 BottomRight;
public Vector3 BottomLeft;
}
public struct CameraCollisionState
{
public bool VTopLeft;
public bool HTopLeft;
public bool VTopRight;
public bool HTopRight;
public bool VBottomLeft;
public bool HBottomLeft;
public bool VBottomRight;
public bool HBottomRight;
}
public class MoveInColliderBoundaries
{
Func<Vector3, float> Vector3H;
Func<Vector3, float> Vector3V;
Func<float, float, Vector3> VectorHV;
const float Offset = .2f;
const float RaySizeCompensation = .2f;
public Transform CameraTransform;
public Vector2 CameraSize;
public LayerMask CameraCollisionMask;
public int TotalHorizontalRays = 3;
public int TotalVerticalRays = 3;
public RaycastOrigins RaycastOrigins { get { return _raycastOrigins; } }
RaycastOrigins _raycastOrigins;
public CameraCollisionState CameraCollisionState { get { return _cameraCollisionState; } }
CameraCollisionState _cameraCollisionState;
RaycastHit _raycastHit;
float _verticalDistanceBetweenRays;
float _horizontalDistanceBetweenRays;
ProCamera2D _proCamera2D;
public MoveInColliderBoundaries(ProCamera2D proCamera2D)
{
_proCamera2D = proCamera2D;
switch (_proCamera2D.Axis)
{
case MovementAxis.XY:
Vector3H = vector => vector.x;
Vector3V = vector => vector.y;
VectorHV = (h, v) => new Vector3(h, v, 0);
break;
case MovementAxis.XZ:
Vector3H = vector => vector.x;
Vector3V = vector => vector.z;
VectorHV = (h, v) => new Vector3(h, 0, v);
break;
case MovementAxis.YZ:
Vector3H = vector => vector.z;
Vector3V = vector => vector.y;
VectorHV = (h, v) => new Vector3(0, v, h);
break;
}
}
public Vector3 Move(Vector3 deltaMovement)
{
// Update raycasts origins
UpdateRaycastOrigins();
// Shoot corner rays to calculate offset and force movement if needed
GetOffsetAndForceMovement(_raycastOrigins.BottomLeft, ref deltaMovement, ref _cameraCollisionState.HBottomLeft, ref _cameraCollisionState.VBottomLeft, -1f, -1f);
GetOffsetAndForceMovement(_raycastOrigins.BottomRight, ref deltaMovement, ref _cameraCollisionState.HBottomRight, ref _cameraCollisionState.VBottomRight, 1f, -1f);
GetOffsetAndForceMovement(_raycastOrigins.TopLeft, ref deltaMovement, ref _cameraCollisionState.HTopLeft, ref _cameraCollisionState.VTopLeft, -1f, 1f);
GetOffsetAndForceMovement(_raycastOrigins.TopRight, ref deltaMovement, ref _cameraCollisionState.HTopRight, ref _cameraCollisionState.VTopRight, 1f, 1f);
// Check movement in the horizontal dir
float h = 0f;
if (Vector3H(deltaMovement) != 0)
h = MoveInAxis(Vector3H(deltaMovement), true);
// Check movement in the vertical dir
float v = 0f;
if (Vector3V(deltaMovement) != 0)
v = MoveInAxis(Vector3V(deltaMovement), false);
// Return updated movement
return VectorHV(h, v);
}
void UpdateRaycastOrigins()
{
_raycastOrigins.BottomRight = VectorHV(Vector3H(CameraTransform.localPosition) + (CameraSize.x / 2), Vector3V(CameraTransform.localPosition) - (CameraSize.y / 2));
_raycastOrigins.BottomLeft = VectorHV(Vector3H(CameraTransform.localPosition) - (CameraSize.x / 2), Vector3V(CameraTransform.localPosition) - (CameraSize.y / 2));
_raycastOrigins.TopRight = VectorHV(Vector3H(CameraTransform.localPosition) + (CameraSize.x / 2), Vector3V(CameraTransform.localPosition) + (CameraSize.y / 2));
_raycastOrigins.TopLeft = VectorHV(Vector3H(CameraTransform.localPosition) - (CameraSize.x / 2), Vector3V(CameraTransform.localPosition) + (CameraSize.y / 2));
_horizontalDistanceBetweenRays = CameraSize.x / (TotalVerticalRays - 1);
_verticalDistanceBetweenRays = CameraSize.y / (TotalHorizontalRays - 1);
}
void GetOffsetAndForceMovement(Vector3 rayTargetPos, ref Vector3 deltaMovement, ref bool horizontalCheck, ref bool verticalCheck, float hSign, float vSign)
{
Vector3 rayOrigin = VectorHV(Vector3H(CameraTransform.localPosition), Vector3V(CameraTransform.localPosition));
Vector3 rayDirection = (rayTargetPos - rayOrigin).normalized;
float raySize = (rayTargetPos - rayOrigin).magnitude + .01f + .5f;
DrawRay(rayOrigin, rayDirection * raySize, Color.yellow);
if (Physics.Raycast(rayOrigin, rayDirection, out _raycastHit, raySize, CameraCollisionMask))
{
if (Mathf.Abs(Vector3H(_raycastHit.normal)) > Mathf.Abs(Vector3V(_raycastHit.normal)))
{
horizontalCheck = !verticalCheck;
if (Vector3H(deltaMovement) == 0)
{
var deltaMovH = .1f * hSign;
deltaMovement = VectorHV(deltaMovH, Vector3V(deltaMovement));
var h = MoveInAxis(Vector3H(deltaMovement), true);
deltaMovement = VectorHV(h, Vector3V(deltaMovement));
}
}
else
{
verticalCheck = !horizontalCheck;
if (Vector3V(deltaMovement) == 0)
{
var deltaMovV = .1f * vSign;
deltaMovement = VectorHV(Vector3H(deltaMovement), deltaMovV);
var v = MoveInAxis(Vector3V(deltaMovement), false);
deltaMovement = VectorHV(Vector3H(deltaMovement), v);
}
}
}
else
{
horizontalCheck = false;
verticalCheck = false;
}
}
float MoveInAxis(float deltaMovement, bool isHorizontal)
{
bool isPositiveDirection = deltaMovement > 0;
float rayDistance = Mathf.Abs(deltaMovement) + RaySizeCompensation;
Vector3 rayDirection;
Vector3 initialRayOrigin;
if (isHorizontal)
{
rayDirection = isPositiveDirection ? CameraTransform.right : -CameraTransform.right;
initialRayOrigin = isPositiveDirection ? _raycastOrigins.BottomRight : _raycastOrigins.BottomLeft;
}
else
{
rayDirection = isPositiveDirection ? CameraTransform.up : -CameraTransform.up;
initialRayOrigin = isPositiveDirection ? _raycastOrigins.TopLeft : _raycastOrigins.BottomLeft;
}
float raycastHitPos = Mathf.NegativeInfinity;
bool hasRayHit = false;
var totalRays = isHorizontal ? TotalHorizontalRays : TotalVerticalRays;
for (int i = 0; i < totalRays; i++)
{
float rayH = isHorizontal ? Vector3H(initialRayOrigin) : Vector3H(initialRayOrigin) + i * _horizontalDistanceBetweenRays;
float rayV = isHorizontal ? Vector3V(initialRayOrigin) + i * _verticalDistanceBetweenRays : Vector3V(initialRayOrigin);
// Add a small offset to avoid collisions at "zero"
if (isHorizontal)
{
if ((isPositiveDirection && _cameraCollisionState.VBottomRight && i == 0) ||
(!isPositiveDirection && _cameraCollisionState.VBottomLeft && i == 0))
rayV += Offset;
if ((isPositiveDirection && _cameraCollisionState.VTopRight && i == totalRays - 1) ||
(!isPositiveDirection && _cameraCollisionState.VTopLeft && i == totalRays - 1))
rayV -= Offset;
}
else
{
if ((isPositiveDirection && _cameraCollisionState.HTopLeft && i == 0) ||
(!isPositiveDirection && _cameraCollisionState.HBottomLeft && i == 0))
rayH += Offset;
if ((isPositiveDirection && _cameraCollisionState.HTopRight && i == totalRays - 1) ||
(!isPositiveDirection && _cameraCollisionState.HBottomRight && i == totalRays - 1))
rayH -= Offset;
}
Vector3 ray = VectorHV(rayH, rayV);
// Raycast
if (Physics.Raycast(ray, rayDirection, out _raycastHit, rayDistance, CameraCollisionMask))
{
DrawRay(ray, rayDirection * rayDistance, Color.red);
if (isHorizontal &&
hasRayHit &&
(isPositiveDirection && raycastHitPos <= Vector3H(_raycastHit.point)) ||
(!isPositiveDirection && raycastHitPos >= Vector3H(_raycastHit.point)))
continue;
else if (hasRayHit &&
(isPositiveDirection && raycastHitPos <= Vector3V(_raycastHit.point)) ||
(!isPositiveDirection && raycastHitPos >= Vector3V(_raycastHit.point)))
continue;
hasRayHit = true;
deltaMovement = isHorizontal ? Vector3H(_raycastHit.point) - Vector3H(ray) + (isPositiveDirection ? -RaySizeCompensation : RaySizeCompensation) :
Vector3V(_raycastHit.point) - Vector3V(ray) + (isPositiveDirection ? -RaySizeCompensation : RaySizeCompensation);
raycastHitPos = isHorizontal ? Vector3H(_raycastHit.point) : Vector3V(_raycastHit.point);
}
else
{
DrawRay(ray, rayDirection * rayDistance, Color.cyan);
}
}
return deltaMovement;
}
private void DrawRay(Vector3 start, Vector3 dir, Color color, float duration = 0)
{
if (duration != 0)
Debug.DrawRay(start, dir, color, duration);
else
Debug.DrawRay(start, dir, color);
}
}
}

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 51b351be489d24540af410c7fc90e168
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

View File

@@ -0,0 +1,32 @@
using UnityEngine;
namespace Com.LuisPedroFonseca.ProCamera2D
{
[System.Serializable]
[CreateAssetMenu(menuName = "ProCamera2D/Shake Preset")]
public class ShakePreset : ScriptableObject
{
public Vector3 Strength = new Vector2(10, 10);
[Range(.02f, 3f)]
public float Duration = .5f;
[Range(1, 100)]
public int Vibrato = 10;
[Range(0f, 1f)]
public float Randomness = .1f;
[Range(0f, .5f)]
public float Smoothness = .1f;
public bool UseRandomInitialAngle = true;
[Range(0f, 360f)]
public float InitialAngle;
public Vector3 Rotation;
public bool IgnoreTimeScale;
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: cbf2b71a297b84564b930517da7ba2d8
timeCreated: 1487290733
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: c7c50ff96274b40608e26e241ae15e11
folderAsset: yes
timeCreated: 1432929171
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,776 @@
// Helper class derived from:
// http://wiki.unity3d.com/index.php/ArrayPrefs2
#if UNITY_EDITOR
using UnityEditor;
#endif
using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
namespace Com.LuisPedroFonseca.ProCamera2D
{
public static class EditorPrefsX
{
static private int endianDiff1;
static private int endianDiff2;
static private int idx;
static private byte[] byteBlock;
enum ArrayType
{
Float,
Int32,
Bool,
String,
Vector2,
Vector3,
Quaternion,
Color
}
public static bool SetBool(String name, bool value)
{
#if UNITY_EDITOR
try
{
EditorPrefs.SetInt(name, value ? 1 : 0);
}
catch
{
return false;
}
#endif
return true;
}
public static bool GetBool(String name)
{
#if UNITY_EDITOR
return EditorPrefs.GetInt(name) == 1;
#else
return true;
#endif
}
public static bool GetBool(String name, bool defaultValue)
{
#if UNITY_EDITOR
return (1 == EditorPrefs.GetInt(name, defaultValue ? 1 : 0));
#else
return true;
#endif
}
public static long GetLong(string key, long defaultValue)
{
#if UNITY_EDITOR
int lowBits, highBits;
SplitLong(defaultValue, out lowBits, out highBits);
lowBits = EditorPrefs.GetInt(key + "_lowBits", lowBits);
highBits = EditorPrefs.GetInt(key + "_highBits", highBits);
// unsigned, to prevent loss of sign bit.
ulong ret = (uint)highBits;
ret = (ret << 32);
return (long)(ret | (ulong)(uint)lowBits);
#else
return 0;
#endif
}
public static long GetLong(string key)
{
#if UNITY_EDITOR
int lowBits = EditorPrefs.GetInt(key + "_lowBits");
int highBits = EditorPrefs.GetInt(key + "_highBits");
// unsigned, to prevent loss of sign bit.
ulong ret = (uint)highBits;
ret = (ret << 32);
return (long)(ret | (ulong)(uint)lowBits);
#else
return 0;
#endif
}
private static void SplitLong(long input, out int lowBits, out int highBits)
{
// unsigned everything, to prevent loss of sign bit.
lowBits = (int)(uint)(ulong)input;
highBits = (int)(uint)(input >> 32);
}
public static void SetLong(string key, long value)
{
#if UNITY_EDITOR
int lowBits, highBits;
SplitLong(value, out lowBits, out highBits);
EditorPrefs.SetInt(key + "_lowBits", lowBits);
EditorPrefs.SetInt(key + "_highBits", highBits);
#endif
}
public static bool SetVector2(String key, Vector2 vector)
{
return SetFloatArray(key, new float[]{ vector.x, vector.y });
}
static Vector2 GetVector2(String key)
{
var floatArray = GetFloatArray(key);
if (floatArray.Length < 2)
{
return Vector2.zero;
}
return new Vector2(floatArray[0], floatArray[1]);
}
public static Vector2 GetVector2(String key, Vector2 defaultValue)
{
#if UNITY_EDITOR
if (EditorPrefs.HasKey(key))
{
return GetVector2(key);
}
return defaultValue;
#else
return Vector2.zero;
#endif
}
public static bool SetVector3(String key, Vector3 vector)
{
return SetFloatArray(key, new float []{ vector.x, vector.y, vector.z });
}
public static Vector3 GetVector3(String key)
{
var floatArray = GetFloatArray(key);
if (floatArray.Length < 3)
{
return Vector3.zero;
}
return new Vector3(floatArray[0], floatArray[1], floatArray[2]);
}
public static Vector3 GetVector3(String key, Vector3 defaultValue)
{
#if UNITY_EDITOR
if (EditorPrefs.HasKey(key))
{
return GetVector3(key);
}
return defaultValue;
#else
return Vector3.zero;
#endif
}
public static bool SetQuaternion(String key, Quaternion vector)
{
return SetFloatArray(key, new float[]{ vector.x, vector.y, vector.z, vector.w });
}
public static Quaternion GetQuaternion(String key)
{
var floatArray = GetFloatArray(key);
if (floatArray.Length < 4)
{
return Quaternion.identity;
}
return new Quaternion(floatArray[0], floatArray[1], floatArray[2], floatArray[3]);
}
public static Quaternion GetQuaternion(String key, Quaternion defaultValue)
{
#if UNITY_EDITOR
if (EditorPrefs.HasKey(key))
{
return GetQuaternion(key);
}
return defaultValue;
#else
return Quaternion.identity;
#endif
}
public static bool SetColor(String key, Color color)
{
return SetFloatArray(key, new float[]{ color.r, color.g, color.b, color.a });
}
public static Color GetColor(String key)
{
var floatArray = GetFloatArray(key);
if (floatArray.Length < 4)
{
return new Color(0.0f, 0.0f, 0.0f, 0.0f);
}
return new Color(floatArray[0], floatArray[1], floatArray[2], floatArray[3]);
}
public static Color GetColor(String key, Color defaultValue)
{
#if UNITY_EDITOR
if (EditorPrefs.HasKey(key))
{
return GetColor(key);
}
return defaultValue;
#else
return Color.white;
#endif
}
public static bool SetBoolArray(String key, bool[] boolArray)
{
// Make a byte array that's a multiple of 8 in length, plus 5 bytes to store the number of entries as an int32 (+ identifier)
// We have to store the number of entries, since the boolArray length might not be a multiple of 8, so there could be some padded zeroes
var bytes = new byte[(boolArray.Length + 7) / 8 + 5];
bytes[0] = System.Convert.ToByte(ArrayType.Bool); // Identifier
int mask = 1;
int targetIndex = 5;
for (int i = 0; i < boolArray.Length; i++)
{
if (boolArray[i])
bytes[targetIndex] |= (byte)mask;
mask <<= 1;
if (mask > 128)
{
mask = 1;
targetIndex++;
}
}
Initialize();
ConvertInt32ToBytes(boolArray.Length, bytes); // The number of entries in the boolArray goes in the first 4 bytes
return SaveBytes(key, bytes);
}
public static bool[] GetBoolArray(String key)
{
if (PlayerPrefs.HasKey(key))
{
var bytes = System.Convert.FromBase64String(PlayerPrefs.GetString(key));
if (bytes.Length < 5)
{
Debug.LogError("Corrupt preference file for " + key);
return new bool[0];
}
if ((ArrayType)bytes[0] != ArrayType.Bool)
{
Debug.LogError(key + " is not a boolean array");
return new bool[0];
}
Initialize();
int count = ConvertBytesToInt32(bytes);
var boolArray = new bool[count];
int mask = 1;
int targetIndex = 5;
for (int i = 0; i < boolArray.Length; i++)
{
boolArray[i] = (bytes[targetIndex] & (byte)mask) != 0;
mask <<= 1;
if (mask > 128)
{
mask = 1;
targetIndex++;
}
}
return boolArray;
}
return new bool[0];
}
public static bool[] GetBoolArray(String key, bool defaultValue, int defaultSize)
{
#if UNITY_EDITOR
if (EditorPrefs.HasKey(key))
{
return GetBoolArray(key);
}
var boolArray = new bool[defaultSize];
for (int i = 0; i < defaultSize; i++)
{
boolArray[i] = defaultValue;
}
return boolArray;
#else
return new bool[0];
#endif
}
public static bool SetStringArray(String key, String[] stringArray)
{
#if UNITY_EDITOR
var bytes = new byte[stringArray.Length + 1];
bytes[0] = System.Convert.ToByte(ArrayType.String); // Identifier
Initialize();
// Store the length of each string that's in stringArray, so we can extract the correct strings in GetStringArray
for (var i = 0; i < stringArray.Length; i++)
{
if (stringArray[i] == null)
{
Debug.LogError("Can't save null entries in the string array when setting " + key);
return false;
}
if (stringArray[i].Length > 255)
{
Debug.LogError("Strings cannot be longer than 255 characters when setting " + key);
return false;
}
bytes[idx++] = (byte)stringArray[i].Length;
}
try
{
EditorPrefs.SetString(key, System.Convert.ToBase64String(bytes) + "|" + String.Join("", stringArray));
}
catch
{
return false;
}
#endif
return true;
}
public static String[] GetStringArray(String key)
{
#if UNITY_EDITOR
if (EditorPrefs.HasKey(key))
{
var completeString = EditorPrefs.GetString(key);
var separatorIndex = completeString.IndexOf("|"[0]);
if (separatorIndex < 4)
{
Debug.LogError("Corrupt preference file for " + key);
return new String[0];
}
var bytes = System.Convert.FromBase64String(completeString.Substring(0, separatorIndex));
if ((ArrayType)bytes[0] != ArrayType.String)
{
Debug.LogError(key + " is not a string array");
return new String[0];
}
Initialize();
var numberOfEntries = bytes.Length - 1;
var stringArray = new String[numberOfEntries];
var stringIndex = separatorIndex + 1;
for (var i = 0; i < numberOfEntries; i++)
{
int stringLength = bytes[idx++];
if (stringIndex + stringLength > completeString.Length)
{
Debug.LogError("Corrupt preference file for " + key);
return new String[0];
}
stringArray[i] = completeString.Substring(stringIndex, stringLength);
stringIndex += stringLength;
}
return stringArray;
}
#endif
return new String[0];
}
public static String[] GetStringArray(String key, String defaultValue, int defaultSize)
{
#if UNITY_EDITOR
if (EditorPrefs.HasKey(key))
{
return GetStringArray(key);
}
var stringArray = new String[defaultSize];
for (int i = 0; i < defaultSize; i++)
{
stringArray[i] = defaultValue;
}
return stringArray;
#else
return new String[0];
#endif
}
public static bool SetIntArray(String key, int[] intArray)
{
return SetValue(key, intArray, ArrayType.Int32, 1, ConvertFromInt);
}
public static bool SetFloatArray(String key, float[] floatArray)
{
return SetValue(key, floatArray, ArrayType.Float, 1, ConvertFromFloat);
}
public static bool SetVector2Array(String key, Vector2[] vector2Array)
{
return SetValue(key, vector2Array, ArrayType.Vector2, 2, ConvertFromVector2);
}
public static bool SetVector3Array(String key, Vector3[] vector3Array)
{
return SetValue(key, vector3Array, ArrayType.Vector3, 3, ConvertFromVector3);
}
public static bool SetQuaternionArray(String key, Quaternion[] quaternionArray)
{
return SetValue(key, quaternionArray, ArrayType.Quaternion, 4, ConvertFromQuaternion);
}
public static bool SetColorArray(String key, Color[] colorArray)
{
return SetValue(key, colorArray, ArrayType.Color, 4, ConvertFromColor);
}
private static bool SetValue<T>(String key, T array, ArrayType arrayType, int vectorNumber, Action<T, byte[],int> convert) where T : IList
{
var bytes = new byte[(4 * array.Count) * vectorNumber + 1];
bytes[0] = System.Convert.ToByte(arrayType); // Identifier
Initialize();
for (var i = 0; i < array.Count; i++)
{
convert(array, bytes, i);
}
return SaveBytes(key, bytes);
}
private static void ConvertFromInt(int[] array, byte[] bytes, int i)
{
ConvertInt32ToBytes(array[i], bytes);
}
private static void ConvertFromFloat(float[] array, byte[] bytes, int i)
{
ConvertFloatToBytes(array[i], bytes);
}
private static void ConvertFromVector2(Vector2[] array, byte[] bytes, int i)
{
ConvertFloatToBytes(array[i].x, bytes);
ConvertFloatToBytes(array[i].y, bytes);
}
private static void ConvertFromVector3(Vector3[] array, byte[] bytes, int i)
{
ConvertFloatToBytes(array[i].x, bytes);
ConvertFloatToBytes(array[i].y, bytes);
ConvertFloatToBytes(array[i].z, bytes);
}
private static void ConvertFromQuaternion(Quaternion[] array, byte[] bytes, int i)
{
ConvertFloatToBytes(array[i].x, bytes);
ConvertFloatToBytes(array[i].y, bytes);
ConvertFloatToBytes(array[i].z, bytes);
ConvertFloatToBytes(array[i].w, bytes);
}
private static void ConvertFromColor(Color[] array, byte[] bytes, int i)
{
ConvertFloatToBytes(array[i].r, bytes);
ConvertFloatToBytes(array[i].g, bytes);
ConvertFloatToBytes(array[i].b, bytes);
ConvertFloatToBytes(array[i].a, bytes);
}
public static int[] GetIntArray(String key)
{
var intList = new List<int>();
GetValue(key, intList, ArrayType.Int32, 1, ConvertToInt);
return intList.ToArray();
}
public static int[] GetIntArray(String key, int defaultValue, int defaultSize)
{
#if UNITY_EDITOR
if (EditorPrefs.HasKey(key))
{
return GetIntArray(key);
}
var intArray = new int[defaultSize];
for (int i = 0; i < defaultSize; i++)
{
intArray[i] = defaultValue;
}
return intArray;
#else
return new int[0];
#endif
}
public static float[] GetFloatArray(String key)
{
var floatList = new List<float>();
GetValue(key, floatList, ArrayType.Float, 1, ConvertToFloat);
return floatList.ToArray();
}
public static float[] GetFloatArray(String key, float defaultValue, int defaultSize)
{
#if UNITY_EDITOR
if (EditorPrefs.HasKey(key))
{
return GetFloatArray(key);
}
var floatArray = new float[defaultSize];
for (int i = 0; i < defaultSize; i++)
{
floatArray[i] = defaultValue;
}
return floatArray;
#else
return new float[0];
#endif
}
public static Vector2[] GetVector2Array(String key)
{
var vector2List = new List<Vector2>();
GetValue(key, vector2List, ArrayType.Vector2, 2, ConvertToVector2);
return vector2List.ToArray();
}
public static Vector2[] GetVector2Array(String key, Vector2 defaultValue, int defaultSize)
{
#if UNITY_EDITOR
if (EditorPrefs.HasKey(key))
{
return GetVector2Array(key);
}
var vector2Array = new Vector2[defaultSize];
for (int i = 0; i < defaultSize; i++)
{
vector2Array[i] = defaultValue;
}
return vector2Array;
#else
return new Vector2[0];
#endif
}
public static Vector3[] GetVector3Array(String key)
{
var vector3List = new List<Vector3>();
GetValue(key, vector3List, ArrayType.Vector3, 3, ConvertToVector3);
return vector3List.ToArray();
}
public static Vector3[] GetVector3Array(String key, Vector3 defaultValue, int defaultSize)
{
#if UNITY_EDITOR
if (EditorPrefs.HasKey(key))
{
return GetVector3Array(key);
}
var vector3Array = new Vector3[defaultSize];
for (int i = 0; i < defaultSize; i++)
{
vector3Array[i] = defaultValue;
}
return vector3Array;
#else
return new Vector3[0];
#endif
}
public static Quaternion[] GetQuaternionArray(String key)
{
var quaternionList = new List<Quaternion>();
GetValue(key, quaternionList, ArrayType.Quaternion, 4, ConvertToQuaternion);
return quaternionList.ToArray();
}
public static Quaternion[] GetQuaternionArray(String key, Quaternion defaultValue, int defaultSize)
{
#if UNITY_EDITOR
if (EditorPrefs.HasKey(key))
{
return GetQuaternionArray(key);
}
var quaternionArray = new Quaternion[defaultSize];
for (int i = 0; i < defaultSize; i++)
{
quaternionArray[i] = defaultValue;
}
return quaternionArray;
#else
return new Quaternion[0];
#endif
}
public static Color[] GetColorArray(String key)
{
var colorList = new List<Color>();
GetValue(key, colorList, ArrayType.Color, 4, ConvertToColor);
return colorList.ToArray();
}
public static Color[] GetColorArray(String key, Color defaultValue, int defaultSize)
{
#if UNITY_EDITOR
if (EditorPrefs.HasKey(key))
{
return GetColorArray(key);
}
var colorArray = new Color[defaultSize];
for (int i = 0; i < defaultSize; i++)
{
colorArray[i] = defaultValue;
}
return colorArray;
#else
return new Color[0];
#endif
}
private static void GetValue<T>(String key, T list, ArrayType arrayType, int vectorNumber, Action<T, byte[]> convert) where T : IList
{
#if UNITY_EDITOR
if (EditorPrefs.HasKey(key))
{
var bytes = System.Convert.FromBase64String(EditorPrefs.GetString(key));
if ((bytes.Length - 1) % (vectorNumber * 4) != 0)
{
Debug.LogError("Corrupt preference file for " + key);
return;
}
if ((ArrayType)bytes[0] != arrayType)
{
Debug.LogError(key + " is not a " + arrayType.ToString() + " array");
return;
}
Initialize();
var end = (bytes.Length - 1) / (vectorNumber * 4);
for (var i = 0; i < end; i++)
{
convert(list, bytes);
}
}
#endif
}
private static void ConvertToInt(List<int> list, byte[] bytes)
{
list.Add(ConvertBytesToInt32(bytes));
}
private static void ConvertToFloat(List<float> list, byte[] bytes)
{
list.Add(ConvertBytesToFloat(bytes));
}
private static void ConvertToVector2(List<Vector2> list, byte[] bytes)
{
list.Add(new Vector2(ConvertBytesToFloat(bytes), ConvertBytesToFloat(bytes)));
}
private static void ConvertToVector3(List<Vector3> list, byte[] bytes)
{
list.Add(new Vector3(ConvertBytesToFloat(bytes), ConvertBytesToFloat(bytes), ConvertBytesToFloat(bytes)));
}
private static void ConvertToQuaternion(List<Quaternion> list, byte[] bytes)
{
list.Add(new Quaternion(ConvertBytesToFloat(bytes), ConvertBytesToFloat(bytes), ConvertBytesToFloat(bytes), ConvertBytesToFloat(bytes)));
}
private static void ConvertToColor(List<Color> list, byte[] bytes)
{
list.Add(new Color(ConvertBytesToFloat(bytes), ConvertBytesToFloat(bytes), ConvertBytesToFloat(bytes), ConvertBytesToFloat(bytes)));
}
public static void ShowArrayType(String key)
{
#if UNITY_EDITOR
var bytes = System.Convert.FromBase64String(EditorPrefs.GetString(key));
if (bytes.Length > 0)
{
ArrayType arrayType = (ArrayType)bytes[0];
Debug.Log(key + " is a " + arrayType.ToString() + " array");
}
#endif
}
private static void Initialize()
{
if (System.BitConverter.IsLittleEndian)
{
endianDiff1 = 0;
endianDiff2 = 0;
}
else
{
endianDiff1 = 3;
endianDiff2 = 1;
}
if (byteBlock == null)
{
byteBlock = new byte[4];
}
idx = 1;
}
private static bool SaveBytes(String key, byte[] bytes)
{
#if UNITY_EDITOR
try
{
EditorPrefs.SetString(key, System.Convert.ToBase64String(bytes));
}
catch
{
return false;
}
#endif
return true;
}
private static void ConvertFloatToBytes(float f, byte[] bytes)
{
byteBlock = System.BitConverter.GetBytes(f);
ConvertTo4Bytes(bytes);
}
private static float ConvertBytesToFloat(byte[] bytes)
{
ConvertFrom4Bytes(bytes);
return System.BitConverter.ToSingle(byteBlock, 0);
}
private static void ConvertInt32ToBytes(int i, byte[] bytes)
{
byteBlock = System.BitConverter.GetBytes(i);
ConvertTo4Bytes(bytes);
}
private static int ConvertBytesToInt32(byte[] bytes)
{
ConvertFrom4Bytes(bytes);
return System.BitConverter.ToInt32(byteBlock, 0);
}
private static void ConvertTo4Bytes(byte[] bytes)
{
bytes[idx] = byteBlock[endianDiff1];
bytes[idx + 1] = byteBlock[1 + endianDiff2];
bytes[idx + 2] = byteBlock[2 - endianDiff2];
bytes[idx + 3] = byteBlock[3 - endianDiff1];
idx += 4;
}
private static void ConvertFrom4Bytes(byte[] bytes)
{
byteBlock[endianDiff1] = bytes[idx];
byteBlock[1 + endianDiff2] = bytes[idx + 1];
byteBlock[2 - endianDiff2] = bytes[idx + 2];
byteBlock[3 - endianDiff1] = bytes[idx + 3];
idx += 4;
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 0cc1f1523bb654cfa9771ed42e226719
timeCreated: 1432894729
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,18 @@
// https://gist.github.com/frarees/9791517
using UnityEngine;
namespace Com.LuisPedroFonseca.ProCamera2D
{
public class MinMaxSliderAttribute : PropertyAttribute
{
public readonly float max;
public readonly float min;
public MinMaxSliderAttribute(float min, float max)
{
this.min = min;
this.max = max;
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 43e42d399775d409e8b8cd61655066a7
timeCreated: 1487610127
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,84 @@
using UnityEngine;
namespace Com.LuisPedroFonseca.ProCamera2D
{
public static class PrefsData
{
// ProCamera2D
public static string NumericBoundariesColorKey = "Numeric Boundaries";
public static Color NumericBoundariesColorValue = Color.white;
public static string TargetsMidPointColorKey = "Targets Mid Point";
public static Color TargetsMidPointColorValue = Color.yellow;
public static string InfluencesColorKey = "Influences Sum";
public static Color InfluencesColorValue = Color.red;
public static string ShakeInfluenceColorKey = "Shake Influence";
public static Color ShakeInfluenceColorValue = Color.red;
public static string OverallOffsetColorKey = "Overall Offset";
public static Color OverallOffsetColorValue = Color.yellow;
public static string CamDistanceColorKey = "Camera Distance Limit";
public static Color CamDistanceColorValue = Color.red;
public static string CamTargetPositionColorKey = "Camera Target Position";
public static Color CamTargetPositionColorValue = new Color(.3f, .3f, .1f);
public static string CamTargetPositionSmoothedColorKey = "Camera Target Position Smoothed";
public static Color CamTargetPositionSmoothedColorValue = new Color(.5f, .3f, .1f);
public static string CurrentCameraPositionColorKey = "Current Camera Position";
public static Color CurrentCameraPositionColorValue = new Color(.8f, .3f, .1f);
public static string CameraWindowColorKey = "Camera Window";
public static Color CameraWindowColorValue = Color.red;
// Forward Focus
public static string ForwardFocusColorKey = "Forward Focus";
public static Color ForwardFocusColorValue = Color.red;
// Zoom To Fit
public static string ZoomToFitColorKey = "Zoom To Fit";
public static Color ZoomToFitColorValue = Color.magenta;
// Boundaries Trigger
public static string BoundariesTriggerColorKey = "Trigger Boundaries";
public static Color BoundariesTriggerColorValue = new Color(Color.cyan.r, Color.cyan.g, Color.cyan.b, .3f);
// Influence Trigger
public static string InfluenceTriggerColorKey = "Trigger Influence";
public static Color InfluenceTriggerColorValue = new Color(Color.cyan.r, Color.cyan.g, Color.cyan.b, .3f);
// Zoom Trigger
public static string ZoomTriggerColorKey = "Trigger Zoom";
public static Color ZoomTriggerColorValue = new Color(Color.cyan.r, Color.cyan.g, Color.cyan.b, .3f);
// Trigger shape
public static string TriggerShapeColorKey = "Trigger Shape";
public static Color TriggerShapeColorValue = new Color(Color.cyan.r, Color.cyan.g, Color.cyan.b, .3f);
// Rails
public static string RailsColorKey = "Rails";
public static Color RailsColorValue = Color.white;
public static float RailsSnapping = .1f;
// Pan Edges
public static string PanEdgesColorKey = "Pan Edges";
public static Color PanEdgesColorValue = Color.red;
// Rooms
public static string RoomsColorKey = "Rooms";
public static Color RoomsColorValue = Color.red;
public static float RoomsSnapping = .1f;
// Content Fitter
public static string FitterFillColorKey = "Fitter Fill";
public static Color FitterFillColorValue = new Color(1f, 1f, 1f, 0.1f);
public static string FitterLineColorKey = "Fitter Line";
public static Color FitterLineColorValue = new Color(1f, 1f, 1f, 0.6f);
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 223eb64f1d6c540d3a207a36649b582f
timeCreated: 1432929192
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,161 @@
using System.Collections.Generic;
using UnityEngine;
namespace Com.LuisPedroFonseca.ProCamera2D
{
public enum EaseType
{
EaseInOut,
EaseOut,
EaseIn,
Linear
}
public static class Utils
{
public static float EaseFromTo(float start, float end, float value, EaseType type = EaseType.EaseInOut)
{
value = Mathf.Clamp01(value);
switch (type)
{
case EaseType.EaseInOut:
return Mathf.Lerp(start, end, value * value * (3.0f - 2.0f * value));
case EaseType.EaseOut:
return Mathf.Lerp(start, end, Mathf.Sin(value * Mathf.PI * 0.5f));
case EaseType.EaseIn:
return Mathf.Lerp(start, end, 1.0f - Mathf.Cos(value * Mathf.PI * 0.5f));
default:
return Mathf.Lerp(start, end, value);
}
}
public static float SmoothApproach(float pastPosition, float pastTargetPosition, float targetPosition, float speed, float deltaTime)
{
float t = deltaTime * speed;
float v = (targetPosition - pastTargetPosition) / t;
float f = pastPosition - pastTargetPosition + v;
return targetPosition - v + f * Mathf.Exp(-t);
}
public static float Remap(this float value, float from1, float to1, float from2, float to2)
{
return Mathf.Clamp((value - from1) / (to1 - from1) * (to2 - from2) + from2, from2, to2);
}
public static void DrawArrowForGizmo(Vector3 pos, Vector3 direction, float arrowHeadLength = 0.25f, float arrowHeadAngle = 20.0f)
{
Gizmos.DrawRay(pos, direction);
DrawArrowEnd(true, pos, direction, Gizmos.color, arrowHeadLength, arrowHeadAngle);
}
public static void DrawArrowForGizmo(Vector3 pos, Vector3 direction, Color color, float arrowHeadLength = 0.25f, float arrowHeadAngle = 20.0f)
{
Gizmos.DrawRay(pos, direction);
DrawArrowEnd(true, pos, direction, color, arrowHeadLength, arrowHeadAngle);
}
public static void DrawArrowForDebug(Vector3 pos, Vector3 direction, float arrowHeadLength = 0.25f, float arrowHeadAngle = 20.0f)
{
Debug.DrawRay(pos, direction);
DrawArrowEnd(false, pos, direction, Gizmos.color, arrowHeadLength, arrowHeadAngle);
}
public static void DrawArrowForDebug(Vector3 pos, Vector3 direction, Color color, float arrowHeadLength = 0.25f, float arrowHeadAngle = 20.0f)
{
Debug.DrawRay(pos, direction, color);
DrawArrowEnd(false, pos, direction, color, arrowHeadLength, arrowHeadAngle);
}
static void DrawArrowEnd(bool gizmos, Vector3 pos, Vector3 direction, Color color, float arrowHeadLength = 0.25f, float arrowHeadAngle = 20.0f)
{
if (direction == Vector3.zero)
return;
Vector3 right = Quaternion.LookRotation(direction) * Quaternion.Euler(arrowHeadAngle, 0, 0) * Vector3.back;
Vector3 left = Quaternion.LookRotation(direction) * Quaternion.Euler(-arrowHeadAngle, 0, 0) * Vector3.back;
Vector3 up = Quaternion.LookRotation(direction) * Quaternion.Euler(0, arrowHeadAngle, 0) * Vector3.back;
Vector3 down = Quaternion.LookRotation(direction) * Quaternion.Euler(0, -arrowHeadAngle, 0) * Vector3.back;
if (gizmos)
{
Gizmos.color = color;
Gizmos.DrawRay(pos + direction, right * arrowHeadLength);
Gizmos.DrawRay(pos + direction, left * arrowHeadLength);
Gizmos.DrawRay(pos + direction, up * arrowHeadLength);
Gizmos.DrawRay(pos + direction, down * arrowHeadLength);
}
else
{
Debug.DrawRay(pos + direction, right * arrowHeadLength, color);
Debug.DrawRay(pos + direction, left * arrowHeadLength, color);
Debug.DrawRay(pos + direction, up * arrowHeadLength, color);
Debug.DrawRay(pos + direction, down * arrowHeadLength, color);
}
}
public static bool AreNearlyEqual(float a, float b, float tolerance = .02f)
{
return Mathf.Abs(a - b) < tolerance;
}
public static Vector2 GetScreenSizeInWorldCoords(Camera gameCamera, float distance = 10f)
{
float width = 0f;
float height = 0f;
if (gameCamera.orthographic)
{
if (gameCamera.orthographicSize <= .001f)
return Vector2.zero;
var p1 = gameCamera.ViewportToWorldPoint(new Vector3(0, 0, gameCamera.nearClipPlane));
var p2 = gameCamera.ViewportToWorldPoint(new Vector3(1, 0, gameCamera.nearClipPlane));
var p3 = gameCamera.ViewportToWorldPoint(new Vector3(1, 1, gameCamera.nearClipPlane));
width = (p2 - p1).magnitude;
height = (p3 - p2).magnitude;
}
else
{
height = 2.0f * Mathf.Abs(distance) * Mathf.Tan(gameCamera.fieldOfView * 0.5f * Mathf.Deg2Rad);
width = height * gameCamera.aspect;
}
return new Vector2(width, height);
}
public static Vector3 GetVectorsSum(IList<Vector3> input)
{
Vector3 output = Vector3.zero;
for (int i = 0; i < input.Count; i++)
{
output += input[i];
}
return output;
}
public static float AlignToGrid(float input, float gridSize)
{
return Mathf.Round((Mathf.Round(input / gridSize) * gridSize) / gridSize) * gridSize;
}
public static bool IsInsideRectangle(float x, float y, float width, float height, float pointX, float pointY)
{
if (pointX >= x - width * .5f &&
pointX <= x + width * .5f &&
pointY >= y - height * .5f &&
pointY <= y + height * .5f)
return true;
return false;
}
public static bool IsInsideCircle(float x, float y, float radius, float pointX, float pointY)
{
return (pointX - x) * (pointX - x) + (pointY - y) * (pointY - y) < radius * radius;
}
}
}

View File

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

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 041eec9152e8f436fa64dd847cea420a
folderAsset: yes
timeCreated: 1430940085
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,96 @@
using UnityEngine;
namespace Com.LuisPedroFonseca.ProCamera2D
{
[HelpURLAttribute("http://www.procamera2d.com/user-guide/extension-camera-window/")]
public class ProCamera2DCameraWindow : BasePC2D, IPositionDeltaChanger
{
public static string ExtensionName = "Camera Window";
public Rect CameraWindowRect = new Rect(0f, 0f, .3f, .3f);
Rect _cameraWindowRectInWorldCoords;
public bool IsRelativeSizeAndPosition = true;
protected override void Awake()
{
base.Awake();
ProCamera2D.AddPositionDeltaChanger(this);
}
protected override void OnDestroy()
{
base.OnDestroy();
if(ProCamera2D)
ProCamera2D.RemovePositionDeltaChanger(this);
}
#region IPositionDeltaChanger implementation
public Vector3 AdjustDelta(float deltaTime, Vector3 originalDelta)
{
if (!enabled)
return originalDelta;
// Calculate the window rect
_cameraWindowRectInWorldCoords = GetRectAroundTransf(CameraWindowRect, ProCamera2D.ScreenSizeInWorldCoordinates, _transform, IsRelativeSizeAndPosition);
// If camera final horizontal position outside camera window rect
var horizontalDeltaMovement = 0f;
if (ProCamera2D.CameraTargetPositionSmoothed.x >= _cameraWindowRectInWorldCoords.x + _cameraWindowRectInWorldCoords.width)
{
horizontalDeltaMovement = ProCamera2D.CameraTargetPositionSmoothed.x - (Vector3H(_transform.localPosition) + _cameraWindowRectInWorldCoords.width / 2 + CameraWindowRect.x * (IsRelativeSizeAndPosition ? ProCamera2D.ScreenSizeInWorldCoordinates.x : 1f));
}
else if (ProCamera2D.CameraTargetPositionSmoothed.x <= _cameraWindowRectInWorldCoords.x)
{
horizontalDeltaMovement = ProCamera2D.CameraTargetPositionSmoothed.x - (Vector3H(_transform.localPosition) - _cameraWindowRectInWorldCoords.width / 2 + CameraWindowRect.x * (IsRelativeSizeAndPosition ? ProCamera2D.ScreenSizeInWorldCoordinates.x : 1f));
}
// If camera final vertical position outside camera window rect
var verticalDeltaMovement = 0f;
if (ProCamera2D.CameraTargetPositionSmoothed.y >= _cameraWindowRectInWorldCoords.y + _cameraWindowRectInWorldCoords.height)
{
verticalDeltaMovement = ProCamera2D.CameraTargetPositionSmoothed.y - (Vector3V(_transform.localPosition) + _cameraWindowRectInWorldCoords.height / 2 + CameraWindowRect.y * (IsRelativeSizeAndPosition ? ProCamera2D.ScreenSizeInWorldCoordinates.y : 1f));
}
else if (ProCamera2D.CameraTargetPositionSmoothed.y <= _cameraWindowRectInWorldCoords.y)
{
verticalDeltaMovement = ProCamera2D.CameraTargetPositionSmoothed.y - (Vector3V(_transform.localPosition) - _cameraWindowRectInWorldCoords.height / 2 + CameraWindowRect.y * (IsRelativeSizeAndPosition ? ProCamera2D.ScreenSizeInWorldCoordinates.y : 1f));
}
return VectorHV(horizontalDeltaMovement, verticalDeltaMovement);
}
public int PDCOrder { get { return _pdcOrder; } set { _pdcOrder = value; } }
int _pdcOrder = 0;
#endregion
Rect GetRectAroundTransf(Rect rectNormalized, Vector2 rectSize, Transform transf, bool isRelative)
{
var finalRectSize = Vector2.Scale(new Vector2(rectNormalized.width, rectNormalized.height), isRelative ? rectSize : Vector2.one);
var rectPositionX = Vector3H(transf.localPosition) - finalRectSize.x / 2 + rectNormalized.x * (isRelative ? rectSize.x : 1f);
var rectPositionY = Vector3V(transf.localPosition) - finalRectSize.y / 2 + rectNormalized.y * (isRelative ? rectSize.y : 1f);
return new Rect(rectPositionX, rectPositionY, finalRectSize.x, finalRectSize.y);
}
#if UNITY_EDITOR
override protected void DrawGizmos()
{
base.DrawGizmos();
var gameCamera = ProCamera2D.GetComponent<Camera>();
var cameraDimensions = gameCamera.orthographic ? Utils.GetScreenSizeInWorldCoords(gameCamera) : Utils.GetScreenSizeInWorldCoords(gameCamera, Mathf.Abs(Vector3D(transform.localPosition)));
float cameraDepthOffset = Vector3D(ProCamera2D.transform.localPosition) + Mathf.Abs(Vector3D(transform.localPosition)) * Vector3D(ProCamera2D.transform.forward);
// Draw camera window
Gizmos.color = EditorPrefsX.GetColor(PrefsData.CameraWindowColorKey, PrefsData.CameraWindowColorValue);
var cameraRect = GetRectAroundTransf(CameraWindowRect, cameraDimensions, transform, IsRelativeSizeAndPosition);
Gizmos.DrawWireCube(VectorHVD(cameraRect.x + cameraRect.width / 2, cameraRect.y + cameraRect.height / 2, cameraDepthOffset), VectorHV(cameraRect.width, cameraRect.height));
}
#endif
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: d7b9c22c96ab04d479afeb29c7b9bfc4
timeCreated: 1454606401
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,520 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
using System.Linq;
using UnityEngine.Events;
namespace Com.LuisPedroFonseca.ProCamera2D
{
[Serializable]
public class CinematicTarget
{
public Transform TargetTransform;
public float EaseInDuration = 1f;
public float HoldDuration = 1f;
public float Zoom = 1f;
public EaseType EaseType = EaseType.EaseOut;
public string SendMessageName;
public string SendMessageParam;
}
[Serializable]
public class CinematicEvent : UnityEvent<int>
{
}
[HelpURLAttribute("http://www.procamera2d.com/user-guide/extension-cinematics/")]
public class ProCamera2DCinematics : BasePC2D, IPositionOverrider, ISizeOverrider
{
public static string ExtensionName = "Cinematics";
public UnityEvent OnCinematicStarted = new UnityEvent();
public CinematicEvent OnCinematicTargetReached = new CinematicEvent();
public UnityEvent OnCinematicFinished = new UnityEvent();
bool _isPlaying;
public bool IsPlaying { get { return _isPlaying; } }
public List<CinematicTarget> CinematicTargets = new List<CinematicTarget>();
public float EndDuration = 1f;
public EaseType EndEaseType = EaseType.EaseOut;
public bool UseNumericBoundaries;
public bool UseLetterbox = true;
[Range(0f, .5f)]
public float LetterboxAmount = .1f;
public float LetterboxAnimDuration = 1f;
public Color LetterboxColor = Color.black;
float _initialCameraSize;
ProCamera2DNumericBoundaries _numericBoundaries;
bool _numericBoundariesPreviousState;
ProCamera2DLetterbox _letterbox;
Coroutine _startCinematicRoutine;
Coroutine _goToCinematicRoutine;
Coroutine _endCinematicRoutine;
bool _skipTarget;
Vector3 _newPos;
Vector3 _originalPos;
Vector3 _startPos;
float _newSize;
bool _paused;
override protected void Awake()
{
base.Awake();
if (UseLetterbox)
SetupLetterbox();
ProCamera2D.AddPositionOverrider(this);
ProCamera2D.AddSizeOverrider(this);
}
protected override void OnDestroy()
{
base.OnDestroy();
if(ProCamera2D == null) return;
ProCamera2D.RemovePositionOverrider(this);
ProCamera2D.RemoveSizeOverrider(this);
}
#region IPositionOverrider implementation
public Vector3 OverridePosition(float deltaTime, Vector3 originalPosition)
{
if (!enabled)
return originalPosition;
_originalPos = originalPosition;
if (_isPlaying)
return _newPos;
else
return originalPosition;
}
public int POOrder { get { return _poOrder; } set { _poOrder = value; } }
int _poOrder = 0;
#endregion
#region ISizeOverrider implementation
public float OverrideSize(float deltaTime, float originalSize)
{
if (!enabled)
return originalSize;
if (_isPlaying)
return _newSize;
else
return originalSize;
}
public int SOOrder { get { return _soOrder; } set { _soOrder = value; } }
int _soOrder = 3000;
#endregion
/// <summary>Play the cinematic.</summary>
public void Play()
{
if (_isPlaying)
return;
_paused = false;
if (CinematicTargets.Count == 0)
{
Debug.LogWarning("No cinematic targets added to the list");
return;
}
_initialCameraSize = ProCamera2D.ScreenSizeInWorldCoordinates.y * .5f;
if (_numericBoundaries == null)
_numericBoundaries = ProCamera2D.GetComponentInChildren<ProCamera2DNumericBoundaries>();
if (_numericBoundaries == null)
_numericBoundaries = FindObjectOfType<ProCamera2DNumericBoundaries>();
if (_numericBoundaries == null)
UseNumericBoundaries = false;
else
{
_numericBoundariesPreviousState = _numericBoundaries.enabled;
_numericBoundaries.enabled = false;
}
_isPlaying = true;
if (_endCinematicRoutine != null)
{
StopCoroutine(_endCinematicRoutine);
_endCinematicRoutine = null;
}
if (_startCinematicRoutine == null)
_startCinematicRoutine = StartCoroutine(StartCinematicRoutine());
}
/// <summary>Stop the cinematic.</summary>
public void Stop()
{
if (!_isPlaying)
return;
if (_startCinematicRoutine != null)
{
StopCoroutine(_startCinematicRoutine);
_startCinematicRoutine = null;
}
if (_goToCinematicRoutine != null)
{
StopCoroutine(_goToCinematicRoutine);
_goToCinematicRoutine = null;
}
if (_endCinematicRoutine == null)
_endCinematicRoutine = StartCoroutine(EndCinematicRoutine());
}
/// <summary>If the cinematic is stopped, it plays it. If it's playing, it stops it.</summary>
public void Toggle()
{
if (_isPlaying)
Stop();
else
Play();
}
/// <summary>Goes to the next cinematic target</summary>
public void GoToNextTarget()
{
_skipTarget = true;
}
/// <summary>Pauses the cinematic</summary>
public void Pause()
{
_paused = true;
}
/// <summary>Unpauses the cinematic</summary>
public void Unpause()
{
_paused = false;
}
/// <summary>Goes to the next cinematic target</summary>
/// <param name="targetTransform">The Transform component of the target</param>
/// <param name="easeInDuration">The time it takes for the camera to reach the target</param>
/// <param name="holdDuration">The time the camera follows the target. If below 0, youll have to manually move to the next target by using the GoToNextTarget method</param>
/// <param name="zoom">The zoom the camera should make while following the target. Use 1 for no zoom</param>
/// <param name="easeType">The animation type of the camera movement to reach the target</param>
/// <param name="sendMessageName">The method name that will be called when the target is reached</param>
/// <param name="sendMessageParam">The parameter that will be sent when the above method is called</param>
/// <param name="index">The position in the targets list. Use -1 to put in last and 0 for first</param>
public void AddCinematicTarget(Transform targetTransform, float easeInDuration = 1f, float holdDuration = 1f, float zoom = 1f, EaseType easeType = EaseType.EaseOut, string sendMessageName = "", string sendMessageParam = "", int index = -1)
{
var newCinematicTarget = new CinematicTarget()
{
TargetTransform = targetTransform,
EaseInDuration = easeInDuration,
HoldDuration = holdDuration,
Zoom = zoom,
EaseType = easeType,
SendMessageName = sendMessageName,
SendMessageParam = sendMessageParam
};
if (index == -1 || index > CinematicTargets.Count)
CinematicTargets.Add(newCinematicTarget);
else
CinematicTargets.Insert(index, newCinematicTarget);
}
// <summary>Remove a cinematic target</summary>
/// <param name="targetTransform">The Transform component of the target</param>
public void RemoveCinematicTarget(Transform targetTransform)
{
for (int i = 0; i < CinematicTargets.Count; i++)
{
if (CinematicTargets[i].TargetTransform.GetInstanceID() == targetTransform.GetInstanceID())
{
CinematicTargets.Remove(CinematicTargets[i]);
}
}
}
IEnumerator StartCinematicRoutine()
{
if (OnCinematicStarted != null)
OnCinematicStarted.Invoke();
_startPos = ProCamera2D.LocalPosition;
_newPos = ProCamera2D.LocalPosition;
_newSize = ProCamera2D.ScreenSizeInWorldCoordinates.y * .5f;
if (UseLetterbox)
{
if (_letterbox == null)
SetupLetterbox();
_letterbox.Color = LetterboxColor;
_letterbox.TweenTo(LetterboxAmount, LetterboxAnimDuration);
}
var count = -1;
while (count < CinematicTargets.Count - 1)
{
count++;
_skipTarget = false;
_goToCinematicRoutine = StartCoroutine(GoToCinematicTargetRoutine(CinematicTargets[count], count));
yield return _goToCinematicRoutine;
}
Stop();
}
IEnumerator GoToCinematicTargetRoutine(CinematicTarget cinematicTarget, int targetIndex)
{
if (cinematicTarget.TargetTransform == null)
yield break;
var initialPosH = Vector3H(ProCamera2D.LocalPosition);
var initialPosV = Vector3V(ProCamera2D.LocalPosition);
var currentCameraSize = ProCamera2D.ScreenSizeInWorldCoordinates.y * .5f;
// Ease in
var t = 0f;
if (cinematicTarget.EaseInDuration > 0)
{
while (t <= 1.0f)
{
if (!_paused)
{
t += ProCamera2D.DeltaTime / cinematicTarget.EaseInDuration;
var newPosH = Utils.EaseFromTo(initialPosH, Vector3H(cinematicTarget.TargetTransform.position) - Vector3H(ProCamera2D.ParentPosition), t, cinematicTarget.EaseType);
var newPosV = Utils.EaseFromTo(initialPosV, Vector3V(cinematicTarget.TargetTransform.position) - Vector3V(ProCamera2D.ParentPosition), t, cinematicTarget.EaseType);
if (UseNumericBoundaries)
LimitToNumericBoundaries(ref newPosH, ref newPosV);
_newPos = VectorHVD(newPosH, newPosV, 0);
_newSize = Utils.EaseFromTo(currentCameraSize, _initialCameraSize / cinematicTarget.Zoom, t, cinematicTarget.EaseType);
if (_skipTarget)
yield break;
}
yield return ProCamera2D.GetYield();
}
}
else
{
var newPosH = Vector3H(cinematicTarget.TargetTransform.position) - Vector3H(ProCamera2D.ParentPosition);
var newPosV = Vector3V(cinematicTarget.TargetTransform.position) - Vector3V(ProCamera2D.ParentPosition);
_newPos = VectorHVD(newPosH, newPosV, 0);
_newSize = _initialCameraSize / cinematicTarget.Zoom;
}
// Dispatch target reached event
if (OnCinematicTargetReached != null)
OnCinematicTargetReached.Invoke(targetIndex);
// Send target reached message
if (!string.IsNullOrEmpty(cinematicTarget.SendMessageName))
{
cinematicTarget.TargetTransform.SendMessage(cinematicTarget.SendMessageName, cinematicTarget.SendMessageParam, SendMessageOptions.DontRequireReceiver);
}
// Hold
t = 0f;
while (cinematicTarget.HoldDuration < 0 || t <= cinematicTarget.HoldDuration)
{
if (!_paused)
{
t += ProCamera2D.DeltaTime;
var newPosH = Vector3H(cinematicTarget.TargetTransform.position) - Vector3H(ProCamera2D.ParentPosition);
var newPosV = Vector3V(cinematicTarget.TargetTransform.position) - Vector3V(ProCamera2D.ParentPosition);
if (UseNumericBoundaries)
LimitToNumericBoundaries(ref newPosH, ref newPosV);
_newPos = VectorHVD(newPosH, newPosV, 0);
if (_skipTarget)
yield break;
}
yield return ProCamera2D.GetYield();
}
}
IEnumerator EndCinematicRoutine()
{
if (_letterbox != null && LetterboxAmount > 0)
_letterbox.TweenTo(0f, LetterboxAnimDuration);
var initialPosH = Vector3H(_newPos);
var initialPosV = Vector3V(_newPos);
var currentCameraSize = ProCamera2D.ScreenSizeInWorldCoordinates.y * .5f;
// Ease out
var t = 0f;
while (t <= 1.0f)
{
if (!_paused)
{
t += ProCamera2D.DeltaTime / EndDuration;
var originalPosH = Vector3H(_originalPos);
var originalPosV = Vector3V(_originalPos);
float newPosH = 0f;
float newPosV = 0f;
if (ProCamera2D.CameraTargets.Count > 0)
{
newPosH = Utils.EaseFromTo(initialPosH, originalPosH, t, EndEaseType);
newPosV = Utils.EaseFromTo(initialPosV, originalPosV, t, EndEaseType);
}
else
{
newPosH = Utils.EaseFromTo(initialPosH, Vector3H(_startPos), t, EndEaseType);
newPosV = Utils.EaseFromTo(initialPosV, Vector3V(_startPos), t, EndEaseType);
}
if (_numericBoundariesPreviousState)
LimitToNumericBoundaries(ref newPosH, ref newPosV);
_newPos = VectorHVD(newPosH, newPosV, 0);
_newSize = Utils.EaseFromTo(currentCameraSize, _initialCameraSize, t, EndEaseType);
}
yield return ProCamera2D.GetYield();
}
_isPlaying = false;
if (_numericBoundaries != null)
_numericBoundaries.enabled = _numericBoundariesPreviousState;
if (OnCinematicFinished != null)
OnCinematicFinished.Invoke();
// Ugly hack... but no way around it at the moment
if (ProCamera2D.CameraTargets.Count == 0)
ProCamera2D.Reset(true);
}
void SetupLetterbox()
{
var letterbox = ProCamera2D.gameObject.GetComponentInChildren<ProCamera2DLetterbox>();
if (letterbox == null)
{
var cameras = ProCamera2D.gameObject.GetComponentsInChildren<Camera>();
cameras = cameras.OrderByDescending(c => c.depth).ToArray();
cameras[0].gameObject.AddComponent<ProCamera2DLetterbox>();
}
_letterbox = letterbox;
}
void LimitToNumericBoundaries(ref float horizontalPos, ref float verticalPos)
{
if (_numericBoundaries.UseLeftBoundary && horizontalPos - ProCamera2D.ScreenSizeInWorldCoordinates.x / 2 < _numericBoundaries.LeftBoundary)
horizontalPos = _numericBoundaries.LeftBoundary + ProCamera2D.ScreenSizeInWorldCoordinates.x / 2;
else if (_numericBoundaries.UseRightBoundary && horizontalPos + ProCamera2D.ScreenSizeInWorldCoordinates.x / 2 > _numericBoundaries.RightBoundary)
horizontalPos = _numericBoundaries.RightBoundary - ProCamera2D.ScreenSizeInWorldCoordinates.x / 2;
if (_numericBoundaries.UseBottomBoundary && verticalPos - ProCamera2D.ScreenSizeInWorldCoordinates.y / 2 < _numericBoundaries.BottomBoundary)
verticalPos = _numericBoundaries.BottomBoundary + ProCamera2D.ScreenSizeInWorldCoordinates.y / 2;
else if (_numericBoundaries.UseTopBoundary && verticalPos + ProCamera2D.ScreenSizeInWorldCoordinates.y / 2 > _numericBoundaries.TopBoundary)
verticalPos = _numericBoundaries.TopBoundary - ProCamera2D.ScreenSizeInWorldCoordinates.y / 2;
}
#if UNITY_EDITOR
override protected void DrawGizmos()
{
base.DrawGizmos();
float cameraDepthOffset = Vector3D(ProCamera2D.transform.localPosition) + Mathf.Abs(Vector3D(ProCamera2D.transform.localPosition)) * Vector3D(ProCamera2D.transform.forward);
// Draw cinematic targets
for (int i = 0; i < CinematicTargets.Count; i++)
{
if (CinematicTargets[i].TargetTransform != null)
{
var targetPos = VectorHVD(Vector3H(CinematicTargets[i].TargetTransform.position), Vector3V(CinematicTargets[i].TargetTransform.position), cameraDepthOffset);
Gizmos.DrawIcon(targetPos, "ProCamera2D/gizmo_icon_exclusive_free.png", false);
}
}
}
void OnDrawGizmosSelected()
{
if (ProCamera2D == null)
return;
var gameCamera = ProCamera2D.GetComponent<Camera>();
float cameraDepthOffset = Vector3D(ProCamera2D.transform.localPosition) + Mathf.Abs(Vector3D(ProCamera2D.transform.localPosition)) * Vector3D(ProCamera2D.transform.forward);
var cameraDimensions = Utils.GetScreenSizeInWorldCoords(gameCamera, Mathf.Abs(Vector3D(ProCamera2D.transform.localPosition)));
// Draw cinematic path
GUIStyle style = new GUIStyle();
style.normal.textColor = Color.green;
for (int i = 0; i < CinematicTargets.Count; i++)
{
var targetPos = VectorHVD(Vector3H(CinematicTargets[i].TargetTransform.position), Vector3V(CinematicTargets[i].TargetTransform.position), cameraDepthOffset);
if (i > 0)
{
UnityEditor.Handles.DrawLine(targetPos, VectorHVD(Vector3H(CinematicTargets[i - 1].TargetTransform.position), Vector3V(CinematicTargets[i - 1].TargetTransform.position), cameraDepthOffset));
}
UnityEditor.Handles.color = Color.blue;
if (i < CinematicTargets.Count - 1)
{
var nextTargetPos = VectorHVD(Vector3H(CinematicTargets[i + 1].TargetTransform.position), Vector3V(CinematicTargets[i + 1].TargetTransform.position), cameraDepthOffset);
var arrowSize = cameraDimensions.x * .1f;
if ((nextTargetPos - targetPos).magnitude > arrowSize)
{
UnityEditor.Handles.ArrowHandleCap(
i,
targetPos,
Quaternion.LookRotation(nextTargetPos - targetPos),
cameraDimensions.x * .1f,
EventType.Repaint);
}
}
}
}
#endif
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 963e3a12d9d70497eb85dd9797a55987
timeCreated: 1448054280
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,419 @@
using System;
using System.Collections;
using UnityEngine;
namespace Com.LuisPedroFonseca.ProCamera2D
{
public enum ContentFitterMode
{
AspectRatio,
FixedWidth,
FixedHeight
}
[HelpURLAttribute("http://www.procamera2d.com/user-guide/extension-content-fitter/")]
public class ProCamera2DContentFitter : BasePC2D, ISizeOverrider
{
public static string ExtensionName = "Content Fitter";
public ContentFitterMode ContentFitterMode
{
set
{
_contentFitterMode = value;
ProCamera2D.GameCamera.ResetProjectionMatrix();
if(_contentFitterMode == ContentFitterMode.AspectRatio)
TargetWidth = TargetHeight * TargetAspectRatio;
}
get { return _contentFitterMode; }
}
[SerializeField] private ContentFitterMode _contentFitterMode;
public bool UseLetterOrPillarboxing
{
set
{
_useLetterOrPillarboxing = value;
ToggleLetterPillarboxing(value);
}
get { return _useLetterOrPillarboxing; }
}
[SerializeField] private bool _useLetterOrPillarboxing;
private static float ScreenAspectRatio
{
get { return Screen.width / (float) Screen.height; }
}
public float TargetHeight
{
get { return _targetHeight; }
set
{
_targetHeight = value;
_targetWidth = ContentFitterMode == ContentFitterMode.AspectRatio ? value * TargetAspectRatio : value * ScreenAspectRatio;
}
}
[SerializeField]
private float _targetHeight = 5.625f;
public float TargetWidth
{
get { return _targetWidth; }
set
{
_targetWidth = value;
_targetHeight = ContentFitterMode == ContentFitterMode.AspectRatio ? value / TargetAspectRatio : value / ScreenAspectRatio;
}
}
[SerializeField]
private float _targetWidth = 10;
public float TargetAspectRatio
{
get { return _targetAspectRatio; }
set
{
_targetAspectRatio = value;
_targetWidth = _targetHeight * value;
}
}
[Range(.1f, 3f)]
[SerializeField]
private float _targetAspectRatio = 16 / 9f;
[Range(-1, 1)] public float VerticalAlignment;
[Range(-1, 1)] public float HorizontalAlignment;
private float
_prevTargetHeight,
_prevTargetWidth,
_prevTargetAspectRatio,
_prevAspectRatio,
_prevVerticalAlignment,
_prevHorizontalAlignment;
private bool _prevUseLetterOrPillarboxing;
private Camera _letterPillarboxingCamera;
protected override void Awake()
{
base.Awake();
ProCamera2D.AddSizeOverrider(this);
}
private IEnumerator Start()
{
if (UseLetterOrPillarboxing)
CreateLetterPillarboxingCamera();
yield return null;
if (ContentFitterMode == ContentFitterMode.AspectRatio)
UpdateCameraAlignment(
ProCamera2D.GameCamera,
TargetHeight * .5f > TargetWidth * .5f / ProCamera2D.GameCamera.aspect,
TargetAspectRatio,
HorizontalAlignment,
VerticalAlignment);
}
protected override void OnDestroy()
{
base.OnDestroy();
if(ProCamera2D)
ProCamera2D.RemoveSizeOverrider(this);
}
protected override void OnDisable()
{
base.OnDisable();
ProCamera2D.GameCamera.ResetProjectionMatrix();
}
#if UNITY_EDITOR
protected override void DrawGizmosSelected()
{
base.DrawGizmosSelected();
var fillColor = EditorPrefsX.GetColor(PrefsData.FitterFillColorKey, PrefsData.FitterFillColorValue);
var lineColor = EditorPrefsX.GetColor(PrefsData.FitterLineColorKey, PrefsData.FitterFillColorValue);
Gizmos.color = lineColor;
var camSize =
Utils.GetScreenSizeInWorldCoords(ProCamera2D.GameCamera, Mathf.Abs(Vector3D(transform.localPosition)));
var camPos = VectorHVD(Vector3H(ProCamera2D.transform.position), Vector3V(ProCamera2D.transform.position),
0);
var rectCorners = DrawGizmoRectangle(
Vector3H(ProCamera2D.transform.position),
Vector3V(ProCamera2D.transform.position),
ContentFitterMode != ContentFitterMode.FixedHeight ? TargetWidth : camSize.x,
ContentFitterMode != ContentFitterMode.FixedWidth ? TargetHeight : camSize.y,
fillColor,
lineColor);
if (_contentFitterMode == ContentFitterMode.AspectRatio)
{
if (TargetHeight * .5f > TargetWidth * .5f / ProCamera2D.GameCamera.aspect)
{
DrawGizmoRectangle(
Vector3H(ProCamera2D.transform.position) - HorizontalAlignment * (TargetHeight * ProCamera2D.GameCamera.aspect - TargetWidth) / 2f,
Vector3V(ProCamera2D.transform.position),
TargetHeight * ProCamera2D.GameCamera.aspect,
TargetHeight,
fillColor,
lineColor);
}
else
{
DrawGizmoRectangle(
Vector3H(ProCamera2D.transform.position),
Vector3V(ProCamera2D.transform.position) - VerticalAlignment * (TargetWidth / ProCamera2D.GameCamera.aspect - TargetHeight) / 2f,
TargetWidth,
TargetWidth / ProCamera2D.GameCamera.aspect,
fillColor,
lineColor);
}
Utils.DrawArrowForGizmo(camPos, camPos - rectCorners[0], camSize.y * .03f);
Utils.DrawArrowForGizmo(camPos, camPos - rectCorners[2], camSize.y * .03f);
}
else if (_contentFitterMode == ContentFitterMode.FixedWidth)
{
DrawGizmoRectangle(
Vector3H(ProCamera2D.transform.position),
Vector3V(ProCamera2D.transform.position),
TargetWidth,
TargetWidth / ProCamera2D.GameCamera.aspect,
fillColor,
lineColor);
Utils.DrawArrowForGizmo(camPos, ProCamera2D.transform.right * TargetWidth * .5f, camSize.y * .03f);
Utils.DrawArrowForGizmo(camPos, -ProCamera2D.transform.right * TargetWidth * .5f, camSize.y * .03f);
}
else
{
DrawGizmoRectangle(
Vector3H(ProCamera2D.transform.position),
Vector3V(ProCamera2D.transform.position),
TargetHeight * ProCamera2D.GameCamera.aspect,
TargetHeight,
fillColor,
lineColor);
Utils.DrawArrowForGizmo(camPos, ProCamera2D.transform.up * TargetHeight * .5f, camSize.y * .03f);
Utils.DrawArrowForGizmo(camPos, -ProCamera2D.transform.up * TargetHeight * .5f, camSize.y * .03f);
}
}
#endif
#region ISizeOverrider implementation
public float OverrideSize(float deltaTime, float originalSize)
{
return !enabled ? originalSize : GetSize(ContentFitterMode);
}
public int SOOrder
{
get { return _soOrder; }
set { _soOrder = value; }
}
private int _soOrder = 5000;
#endregion
private float GetSize(ContentFitterMode mode)
{
switch (mode)
{
case ContentFitterMode.FixedHeight:
return TargetHeight * .5f;
case ContentFitterMode.FixedWidth:
return TargetWidth * .5f / ProCamera2D.GameCamera.aspect;
case ContentFitterMode.AspectRatio:
if (_prevTargetWidth != TargetWidth ||
_prevTargetHeight != TargetHeight ||
_prevTargetAspectRatio != TargetAspectRatio ||
_prevAspectRatio != ProCamera2D.GameCamera.aspect ||
_prevVerticalAlignment != VerticalAlignment ||
_prevHorizontalAlignment != HorizontalAlignment ||
_prevUseLetterOrPillarboxing != _useLetterOrPillarboxing)
{
StartCoroutine(UpdateFixedAspectRatio());
}
_prevTargetWidth = TargetWidth;
_prevTargetHeight = TargetHeight;
_prevTargetAspectRatio = TargetAspectRatio;
_prevAspectRatio = ProCamera2D.GameCamera.aspect;
_prevVerticalAlignment = VerticalAlignment;
_prevHorizontalAlignment = HorizontalAlignment;
_prevUseLetterOrPillarboxing = _useLetterOrPillarboxing;
return Mathf.Max(TargetHeight * .5f, TargetWidth * .5f / ProCamera2D.GameCamera.aspect);
default:
throw new ArgumentOutOfRangeException();
}
}
IEnumerator UpdateFixedAspectRatio()
{
var isPillarbox = TargetHeight * .5f > TargetWidth * .5f / ScreenAspectRatio;
if(_prevUseLetterOrPillarboxing != _useLetterOrPillarboxing)
ToggleLetterPillarboxing(_useLetterOrPillarboxing);
if (UseLetterOrPillarboxing)
{
UpdateLetterPillarbox(
ProCamera2D.GameCamera,
isPillarbox,
TargetAspectRatio,
HorizontalAlignment,
VerticalAlignment);
}
yield return new WaitForEndOfFrame();
UpdateCameraAlignment(
ProCamera2D.GameCamera,
isPillarbox,
TargetAspectRatio,
HorizontalAlignment,
VerticalAlignment);
}
private static void UpdateCameraAlignment(
Camera cam,
bool isPillarbox,
float targetAspectRatio,
float horizontalAlignment,
float verticalAlignment)
{
cam.ResetProjectionMatrix();
var horizontalOffset = isPillarbox
? (-.5f + (targetAspectRatio / cam.aspect) * 0.5f) * horizontalAlignment
: 0;
var verticalOffset = !isPillarbox
? (-.5f + (cam.aspect / targetAspectRatio) * 0.5f) * verticalAlignment
: 0;
cam.projectionMatrix = GetScissorRect(
new Rect(
horizontalOffset,
verticalOffset,
1, 1), cam.projectionMatrix);
}
private static Matrix4x4 GetScissorRect(Rect targetScissor, Matrix4x4 camProjectionMatrix)
{
var m2 = Matrix4x4.TRS(
new Vector3((1 / targetScissor.width - 1), (1 / targetScissor.height - 1), 0),
Quaternion.identity,
new Vector3(1 / targetScissor.width, 1 / targetScissor.height, 1));
var m3 = Matrix4x4.TRS(
new Vector3(-targetScissor.x * 2 / targetScissor.width, -targetScissor.y * 2 / targetScissor.height, 0),
Quaternion.identity,
Vector3.one);
return m3 * m2 * camProjectionMatrix;
}
private static void UpdateLetterPillarbox(
Camera cam,
bool isPillarbox,
float targetAspectRatio,
float horizontalAlignment,
float verticalAlignment)
{
if (isPillarbox)
{
var inset = 1.0f - targetAspectRatio / (Screen.width / (float) Screen.height);
cam.rect = new Rect((inset / 2f) + (inset / 2f) * horizontalAlignment, 0.0f, 1.0f - inset, 1.0f);
}
else
{
var inset = 1.0f - (Screen.width / (float) Screen.height) / targetAspectRatio;
cam.rect = new Rect(0.0f, (inset / 2f) + (inset / 2f) * verticalAlignment, 1.0f, 1.0f - inset);
}
}
private void ToggleLetterPillarboxing(bool value)
{
if (value && _letterPillarboxingCamera == null)
CreateLetterPillarboxingCamera();
if (value)
{
_letterPillarboxingCamera.gameObject.SetActive(true);
UpdateLetterPillarbox(
ProCamera2D.GameCamera,
TargetHeight * .5f > TargetWidth * .5f / ScreenAspectRatio,
TargetAspectRatio,
HorizontalAlignment,
VerticalAlignment);
}
else
{
if (_letterPillarboxingCamera != null)
_letterPillarboxingCamera.gameObject.SetActive(false);
ProCamera2D.GameCamera.rect = new Rect(0, 0, 1, 1);
UpdateCameraAlignment(
ProCamera2D.GameCamera,
TargetHeight * .5f > TargetWidth * .5f / ScreenAspectRatio,
TargetAspectRatio,
HorizontalAlignment,
VerticalAlignment);
}
}
private void CreateLetterPillarboxingCamera()
{
_letterPillarboxingCamera = new GameObject("PC2DBackgroundCamera", typeof(Camera)).GetComponent<Camera>();
_letterPillarboxingCamera.depth = int.MinValue;
_letterPillarboxingCamera.clearFlags = CameraClearFlags.SolidColor;
_letterPillarboxingCamera.backgroundColor = Color.black;
_letterPillarboxingCamera.cullingMask = 0;
_letterPillarboxingCamera.transform.position = new Vector3(10000, 10000, 10000);
_letterPillarboxingCamera.gameObject.hideFlags = HideFlags.HideInHierarchy;
}
private Vector3[] DrawGizmoRectangle(float x, float y, float width, float height, Color fillColor,
Color borderColor)
{
var rect = new Rect(x, y, width, height);
rect.x -= rect.width / 2f;
rect.y -= rect.height / 2f;
Vector3[] rectangleCorners =
{
VectorHVD(rect.position.x, rect.position.y, 0), // Bottom Left
VectorHVD(rect.position.x + rect.width, rect.position.y, 0), // Bottom Right
VectorHVD(rect.position.x + rect.width, rect.position.y + rect.height, 0), // Top Right
VectorHVD(rect.position.x, rect.position.y + rect.height, 0) // Top Left
};
#if UNITY_EDITOR
UnityEditor.Handles.DrawSolidRectangleWithOutline(rectangleCorners, fillColor, borderColor);
#endif
return rectangleCorners;
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 3ba4e7c9ccf634257ad7d8b2a2501c9f
timeCreated: 1506162909
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,242 @@
using System;
using System.Collections;
using UnityEngine;
namespace Com.LuisPedroFonseca.ProCamera2D
{
[HelpURLAttribute("http://www.procamera2d.com/user-guide/extension-forward-focus/")]
public class ProCamera2DForwardFocus : BasePC2D, IPreMover
{
public static string ExtensionName = "Forward Focus";
const float EPSILON = .001f;
public bool Progressive = true;
public float SpeedMultiplier = 1f;
public float TransitionSmoothness = .5f;
public bool MaintainInfluenceOnStop = true;
public Vector2 MovementThreshold = Vector2.zero;
[RangeAttribute(EPSILON, .5f)]
public float LeftFocus = .25f;
[RangeAttribute(EPSILON, .5f)]
public float RightFocus = .25f;
[RangeAttribute(EPSILON, .5f)]
public float TopFocus = .25f;
[RangeAttribute(EPSILON, .5f)]
public float BottomFocus = .25f;
float _hVel;
float _hVelSmooth;
float _vVel;
float _vVelSmooth;
float _targetHVel;
float _targetVVel;
bool _isFirstHorizontalCameraMovement;
bool _isFirstVerticalCameraMovement;
bool __enabled;
override protected void Awake()
{
base.Awake();
StartCoroutine(Enable());
ProCamera2D.AddPreMover(this);
}
protected override void OnDestroy()
{
base.OnDestroy();
if(ProCamera2D)
ProCamera2D.RemovePreMover(this);
}
#region IPreMover implementation
public void PreMove(float deltaTime)
{
if(__enabled && enabled)
ApplyInfluence(deltaTime);
}
public int PrMOrder { get { return _prmOrder; } set { _prmOrder = value; } }
int _prmOrder = 2000;
#endregion
override public void OnReset()
{
_hVel = 0;
_hVelSmooth = 0;
_vVel = 0;
_vVelSmooth = 0;
_targetHVel = 0;
_targetVVel = 0;
_isFirstHorizontalCameraMovement = false;
_isFirstVerticalCameraMovement = false;
__enabled = false;
StartCoroutine(Enable());
}
IEnumerator Enable()
{
yield return new WaitForEndOfFrame();
__enabled = true;
}
void ApplyInfluence(float deltaTime)
{
var currentHVel = Vector3H(ProCamera2D.TargetsMidPoint) - Vector3H(ProCamera2D.PreviousTargetsMidPoint);
if (Mathf.Abs(currentHVel) < MovementThreshold.x)
currentHVel = 0f;
else
currentHVel /= deltaTime;
var currentVVel = Vector3V(ProCamera2D.TargetsMidPoint) - Vector3V(ProCamera2D.PreviousTargetsMidPoint);
if (Mathf.Abs(currentVVel) < MovementThreshold.y)
currentVVel = 0f;
else
currentVVel /= deltaTime;
if (Progressive)
{
currentHVel = Mathf.Clamp(currentHVel * SpeedMultiplier, -LeftFocus * ProCamera2D.ScreenSizeInWorldCoordinates.x, RightFocus * ProCamera2D.ScreenSizeInWorldCoordinates.x);
currentVVel = Mathf.Clamp(currentVVel * SpeedMultiplier, -BottomFocus * ProCamera2D.ScreenSizeInWorldCoordinates.y, TopFocus * ProCamera2D.ScreenSizeInWorldCoordinates.y);
if (MaintainInfluenceOnStop)
{
if ((Mathf.Sign(currentHVel) == 1 && currentHVel < _hVel) ||
(Mathf.Sign(currentHVel) == -1 && currentHVel > _hVel) ||
(Mathf.Abs(currentHVel) < EPSILON))
{
currentHVel = _hVel;
}
if ((Mathf.Sign(currentVVel) == 1 && currentVVel < _vVel) ||
(Mathf.Sign(currentVVel) == -1 && currentVVel > _vVel) ||
(Mathf.Abs(currentVVel) < EPSILON))
{
currentVVel = _vVel;
}
}
}
else
{
if (MaintainInfluenceOnStop)
{
bool switchedHorizontalDirection;
if (!_isFirstHorizontalCameraMovement && !(Mathf.Abs(currentHVel) < EPSILON))
{
_isFirstHorizontalCameraMovement = true;
switchedHorizontalDirection = true;
}
else
{
switchedHorizontalDirection = Mathf.Sign(currentHVel) != Mathf.Sign(_targetHVel);
}
if (!(Mathf.Abs(currentHVel) < EPSILON) && switchedHorizontalDirection)
{
_targetHVel = (currentHVel < 0f ? -LeftFocus : RightFocus) * ProCamera2D.ScreenSizeInWorldCoordinates.x;
}
currentHVel = _targetHVel;
bool switchedVerticalDirection;
if (!_isFirstVerticalCameraMovement && !(Mathf.Abs(currentVVel) < EPSILON))
{
_isFirstVerticalCameraMovement = true;
switchedVerticalDirection = true;
}
else
{
switchedVerticalDirection = Mathf.Sign(currentVVel) != Mathf.Sign(_targetVVel);
}
if (!(Mathf.Abs(currentVVel) < EPSILON) && switchedVerticalDirection)
{
_targetVVel = (currentVVel < 0f ? -BottomFocus : TopFocus) * ProCamera2D.ScreenSizeInWorldCoordinates.y;
}
currentVVel = _targetVVel;
}
else
{
if (!(Mathf.Abs(currentHVel) < EPSILON))
currentHVel = (currentHVel < 0f ? -LeftFocus : RightFocus) * ProCamera2D.ScreenSizeInWorldCoordinates.x;
else
currentHVel = 0;
if (!(Mathf.Abs(currentVVel) < EPSILON))
currentVVel = (currentVVel < 0f ? -BottomFocus : TopFocus) * ProCamera2D.ScreenSizeInWorldCoordinates.y;
else
currentVVel = 0;
}
}
// We need to clamp the values again to account for camera zooms
currentHVel = Mathf.Clamp(currentHVel, -LeftFocus * ProCamera2D.ScreenSizeInWorldCoordinates.x, RightFocus * ProCamera2D.ScreenSizeInWorldCoordinates.x);
currentVVel = Mathf.Clamp(currentVVel, -BottomFocus * ProCamera2D.ScreenSizeInWorldCoordinates.y, TopFocus * ProCamera2D.ScreenSizeInWorldCoordinates.y);
// Smooth the values
_hVel = Mathf.SmoothDamp(_hVel, currentHVel, ref _hVelSmooth, TransitionSmoothness, float.MaxValue, deltaTime);
_vVel = Mathf.SmoothDamp(_vVel, currentVVel, ref _vVelSmooth, TransitionSmoothness, float.MaxValue, deltaTime);
// Apply the influence
ProCamera2D.ApplyInfluence(new Vector2(_hVel, _vVel));
}
#if UNITY_EDITOR
override protected void DrawGizmos()
{
base.DrawGizmos();
var gameCamera = ProCamera2D.GetComponent<Camera>();
var cameraDimensions = gameCamera.orthographic ? Utils.GetScreenSizeInWorldCoords(gameCamera) : Utils.GetScreenSizeInWorldCoords(gameCamera, Mathf.Abs(Vector3D(transform.localPosition)));
float cameraDepthOffset = Vector3D(ProCamera2D.transform.localPosition) + Mathf.Abs(Vector3D(transform.localPosition)) * Vector3D(ProCamera2D.transform.forward);
var cameraCenter = VectorHVD(Vector3H(transform.position), Vector3V(transform.position), cameraDepthOffset);
Gizmos.color = EditorPrefsX.GetColor(PrefsData.ForwardFocusColorKey, PrefsData.ForwardFocusColorValue);
if (LeftFocus > EPSILON)
{
Gizmos.DrawRay(VectorHVD(Vector3H(transform.position) + cameraDimensions.x * LeftFocus, Vector3V(transform.position) - cameraDimensions.y / 2, cameraDepthOffset), transform.up * cameraDimensions.y);
Utils.DrawArrowForGizmo(cameraCenter + VectorHV(cameraDimensions.x * LeftFocus, 0), -transform.right * .3f);
}
if (RightFocus > EPSILON)
{
Gizmos.DrawRay(VectorHVD(Vector3H(transform.position) - cameraDimensions.x * RightFocus, Vector3V(transform.position) - cameraDimensions.y / 2, cameraDepthOffset), transform.up * cameraDimensions.y);
Utils.DrawArrowForGizmo(cameraCenter - VectorHV(cameraDimensions.x * RightFocus, 0), transform.right * .3f);
}
if (TopFocus > EPSILON)
{
Gizmos.DrawRay(VectorHVD(Vector3H(transform.position) - cameraDimensions.x / 2, Vector3V(transform.position) - cameraDimensions.y * TopFocus, cameraDepthOffset), transform.right * cameraDimensions.x);
Utils.DrawArrowForGizmo(cameraCenter - VectorHV(0, cameraDimensions.y * TopFocus), transform.up * .3f);
}
if (BottomFocus > EPSILON)
{
Gizmos.DrawRay(VectorHVD(Vector3H(transform.position) - cameraDimensions.x / 2, Vector3V(transform.position) + cameraDimensions.y * BottomFocus, cameraDepthOffset), transform.right * cameraDimensions.x);
Utils.DrawArrowForGizmo(cameraCenter + VectorHV(0, cameraDimensions.y * BottomFocus), -transform.up * .3f);
}
}
#endif
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: c17020d0b9b514c5ea3b8251d0c4ee6a
timeCreated: 1433375083
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,52 @@
using UnityEngine;
namespace Com.LuisPedroFonseca.ProCamera2D
{
[HelpURLAttribute("http://www.procamera2d.com/user-guide/extension-geometry-boundaries/")]
public class ProCamera2DGeometryBoundaries : BasePC2D, IPositionDeltaChanger
{
public static string ExtensionName = "Geometry Boundaries";
[Tooltip("The layer that contains the (3d) colliders that define the boundaries for the camera")]
public LayerMask BoundariesLayerMask;
public MoveInColliderBoundaries MoveInColliderBoundaries;
override protected void Awake()
{
base.Awake();
MoveInColliderBoundaries = new MoveInColliderBoundaries(ProCamera2D);
MoveInColliderBoundaries.CameraTransform = ProCamera2D.transform;
MoveInColliderBoundaries.CameraCollisionMask = BoundariesLayerMask;
ProCamera2D.AddPositionDeltaChanger(this);
}
protected override void OnDestroy()
{
base.OnDestroy();
if(ProCamera2D)
ProCamera2D.RemovePositionDeltaChanger(this);
}
#region IPositionDeltaChanger implementation
public Vector3 AdjustDelta(float deltaTime, Vector3 originalDelta)
{
if (!enabled)
return originalDelta;
MoveInColliderBoundaries.CameraSize = ProCamera2D.ScreenSizeInWorldCoordinates;
// Apply movement considering the collider boundaries
return MoveInColliderBoundaries.Move(originalDelta);
}
public int PDCOrder { get { return _pdcOrder; } set { _pdcOrder = value; } }
int _pdcOrder = 3000;
#endregion
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: d86bf0beadb1248c2a5d9f2fe72189fa
timeCreated: 1454608357
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,138 @@
using UnityEngine;
namespace Com.LuisPedroFonseca.ProCamera2D
{
[HelpURLAttribute("http://www.procamera2d.com/user-guide/extension-limit-distance/")]
public class ProCamera2DLimitDistance : BasePC2D, IPositionDeltaChanger
{
public static string ExtensionName = "Limit Distance";
public bool UseTargetsPosition = true;
public bool LimitTopCameraDistance = true;
[Range(.1f, 1f)]
public float MaxTopTargetDistance = .8f;
public bool LimitBottomCameraDistance = true;
[Range(.1f, 1f)]
public float MaxBottomTargetDistance = .8f;
public bool LimitLeftCameraDistance = true;
[Range(.1f, 1f)]
public float MaxLeftTargetDistance = .8f;
public bool LimitRightCameraDistance = true;
[Range(.1f, 1f)]
public float MaxRightTargetDistance = .8f;
protected override void Awake()
{
base.Awake();
ProCamera2D.AddPositionDeltaChanger(this);
}
protected override void OnDestroy()
{
base.OnDestroy();
if(ProCamera2D)
ProCamera2D.RemovePositionDeltaChanger(this);
}
#region IPositionDeltaChanger implementation
public Vector3 AdjustDelta(float deltaTime, Vector3 originalDelta)
{
if (!enabled)
return originalDelta;
var horizontalDeltaMovement = Vector3H(originalDelta);
var horizontalExtra = false;
var verticalDeltaMovement = Vector3V(originalDelta);
var verticalExtra = false;
var comparisonPosition = UseTargetsPosition
? new Vector2(Vector3H(ProCamera2D.TargetsMidPoint), Vector3V(ProCamera2D.TargetsMidPoint))
: new Vector2(Vector3H(ProCamera2D.CameraTargetPosition), Vector3V(ProCamera2D.CameraTargetPosition));
// Top
if (LimitTopCameraDistance)
{
var verticalArea = (ProCamera2D.ScreenSizeInWorldCoordinates.y / 2) * MaxTopTargetDistance;
if (comparisonPosition.y > verticalDeltaMovement + Vector3V(ProCamera2D.LocalPosition) + verticalArea)
{
verticalDeltaMovement = comparisonPosition.y - (Vector3V(ProCamera2D.LocalPosition) + verticalArea);
verticalExtra = true;
}
}
// Bottom
if (LimitBottomCameraDistance)
{
var verticalArea = (ProCamera2D.ScreenSizeInWorldCoordinates.y / 2) * MaxBottomTargetDistance;
if (comparisonPosition.y < verticalDeltaMovement + Vector3V(ProCamera2D.LocalPosition) - verticalArea)
{
verticalDeltaMovement = comparisonPosition.y - (Vector3V(ProCamera2D.LocalPosition) - verticalArea);
verticalExtra = true;
}
}
// Left
if (LimitLeftCameraDistance)
{
var horizontalArea = (ProCamera2D.ScreenSizeInWorldCoordinates.x / 2) * MaxLeftTargetDistance;
if (comparisonPosition.x < horizontalDeltaMovement + Vector3H(ProCamera2D.LocalPosition) - horizontalArea)
{
horizontalDeltaMovement = comparisonPosition.x - (Vector3H(ProCamera2D.LocalPosition) - horizontalArea);
horizontalExtra = true;
}
}
// Right
if (LimitRightCameraDistance)
{
var horizontalArea = (ProCamera2D.ScreenSizeInWorldCoordinates.x / 2) * MaxRightTargetDistance;
if (comparisonPosition.x > horizontalDeltaMovement + Vector3H(ProCamera2D.LocalPosition) + horizontalArea)
{
horizontalDeltaMovement = comparisonPosition.x - (Vector3H(ProCamera2D.LocalPosition) + horizontalArea);
horizontalExtra = true;
}
}
var h = horizontalExtra ? ProCamera2D.CameraTargetPositionSmoothed.x + horizontalDeltaMovement - Vector3H(originalDelta) : ProCamera2D.CameraTargetPositionSmoothed.x;
var v = verticalExtra ? ProCamera2D.CameraTargetPositionSmoothed.y + verticalDeltaMovement - Vector3V(originalDelta) : ProCamera2D.CameraTargetPositionSmoothed.y;
ProCamera2D.CameraTargetPositionSmoothed = new Vector2(h, v);
return VectorHV(horizontalDeltaMovement, verticalDeltaMovement);
}
public int PDCOrder { get { return _pdcOrder; } set { _pdcOrder = value; } }
int _pdcOrder = 2000;
#endregion
#if UNITY_EDITOR
protected override void DrawGizmos()
{
base.DrawGizmos();
var gameCamera = ProCamera2D.GetComponent<Camera>();
var cameraDimensions = gameCamera.orthographic ? Utils.GetScreenSizeInWorldCoords(gameCamera) : Utils.GetScreenSizeInWorldCoords(gameCamera, Mathf.Abs(Vector3D(transform.position)));
float cameraDepthOffset = Vector3D(ProCamera2D.transform.localPosition) + Mathf.Abs(Vector3D(transform.localPosition)) * Vector3D(ProCamera2D.transform.forward);
Gizmos.color = EditorPrefsX.GetColor(PrefsData.CamDistanceColorKey, PrefsData.CamDistanceColorValue);
if (LimitTopCameraDistance)
Gizmos.DrawRay(VectorHVD(Vector3H(transform.position) - cameraDimensions.x / 2, Vector3V(transform.position) + (cameraDimensions.y / 2) * MaxTopTargetDistance, cameraDepthOffset), transform.right * cameraDimensions.x);
if (LimitBottomCameraDistance)
Gizmos.DrawRay(VectorHVD(Vector3H(transform.position) - cameraDimensions.x / 2, Vector3V(transform.position) - (cameraDimensions.y / 2) * MaxBottomTargetDistance, cameraDepthOffset), transform.right * cameraDimensions.x);
if (LimitLeftCameraDistance)
Gizmos.DrawRay(VectorHVD(Vector3H(transform.position) - (cameraDimensions.x / 2) * MaxLeftTargetDistance, Vector3V(transform.position) - cameraDimensions.y / 2, cameraDepthOffset), transform.up * cameraDimensions.y);
if (LimitRightCameraDistance)
Gizmos.DrawRay(VectorHVD(Vector3H(transform.position) + (cameraDimensions.x / 2) * MaxRightTargetDistance, Vector3V(transform.position) - cameraDimensions.y / 2, cameraDepthOffset), transform.up * cameraDimensions.y);
}
#endif
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 37203e96e63794cd38c73c6c90eae460
timeCreated: 1455208557
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,67 @@
using UnityEngine;
namespace Com.LuisPedroFonseca.ProCamera2D
{
[HelpURLAttribute("http://www.procamera2d.com/user-guide/extension-limit-speed/")]
public class ProCamera2DLimitSpeed : BasePC2D, IPositionDeltaChanger
{
public static string ExtensionName = "Limit Speed";
public bool LimitHorizontalSpeed = true;
public float MaxHorizontalSpeed = 2f;
public bool LimitVerticalSpeed = true;
public float MaxVerticalSpeed = 2f;
#if UNITY_EDITOR
public float CurrentSpeedHorizontal;
public float CurrentSpeedVertical;
#endif
protected override void Awake()
{
base.Awake();
ProCamera2D.AddPositionDeltaChanger(this);
}
protected override void OnDestroy()
{
base.OnDestroy();
if(ProCamera2D)
ProCamera2D.RemovePositionDeltaChanger(this);
}
#region IPositionDeltaChanger implementation
public Vector3 AdjustDelta(float deltaTime, Vector3 originalDelta)
{
if (!enabled)
return originalDelta;
var fps = 1f / deltaTime;
var newHorizontalDeltaMovement = Vector3H(originalDelta) * fps;
var newVerticalDeltaMovement = Vector3V(originalDelta) * fps;
if (LimitHorizontalSpeed)
newHorizontalDeltaMovement = Mathf.Clamp(newHorizontalDeltaMovement, -MaxHorizontalSpeed, MaxHorizontalSpeed);
if (LimitVerticalSpeed)
newVerticalDeltaMovement = Mathf.Clamp(newVerticalDeltaMovement, -MaxVerticalSpeed, MaxVerticalSpeed);
#if UNITY_EDITOR
CurrentSpeedHorizontal = newHorizontalDeltaMovement;
CurrentSpeedVertical = newVerticalDeltaMovement;
#endif
return VectorHV(newHorizontalDeltaMovement * deltaTime, newVerticalDeltaMovement * deltaTime);
}
public int PDCOrder { get { return _pdcOrder; } set { _pdcOrder = value; } }
int _pdcOrder = 1000;
#endregion
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: f3bb06cc0151646ae82d5728cf6479b9
timeCreated: 1455039902
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,326 @@
using UnityEngine;
using System;
namespace Com.LuisPedroFonseca.ProCamera2D
{
public struct NumericBoundariesSettings
{
public bool UseNumericBoundaries;
public bool UseTopBoundary;
public float TopBoundary;
public bool UseBottomBoundary;
public float BottomBoundary;
public bool UseLeftBoundary;
public float LeftBoundary;
public bool UseRightBoundary;
public float RightBoundary;
}
[HelpURLAttribute("http://www.procamera2d.com/user-guide/extension-numeric-boundaries/")]
public class ProCamera2DNumericBoundaries : BasePC2D, IPositionDeltaChanger, ISizeOverrider
{
public static string ExtensionName = "Numeric Boundaries";
public NumericBoundariesSettings Settings
{
get
{
return new NumericBoundariesSettings()
{
UseNumericBoundaries = UseNumericBoundaries,
UseTopBoundary = UseTopBoundary,
TopBoundary = TopBoundary,
UseBottomBoundary = UseBottomBoundary,
BottomBoundary = BottomBoundary,
UseLeftBoundary = UseLeftBoundary,
LeftBoundary = LeftBoundary,
UseRightBoundary = UseRightBoundary,
RightBoundary = RightBoundary
};
}
set
{
UseNumericBoundaries = value.UseNumericBoundaries;
UseTopBoundary = value.UseTopBoundary;
TopBoundary = value.TopBoundary;
UseBottomBoundary = value.UseBottomBoundary;
BottomBoundary = value.BottomBoundary;
UseLeftBoundary = value.UseLeftBoundary;
LeftBoundary = value.LeftBoundary;
UseRightBoundary = value.UseRightBoundary;
RightBoundary = value.RightBoundary;
}
}
public Action OnBoundariesTransitionStarted;
public Action OnBoundariesTransitionFinished;
public bool UseNumericBoundaries = true;
public bool UseTopBoundary;
public float TopBoundary = 10f;
public float TargetTopBoundary;
public bool UseBottomBoundary = true;
public float BottomBoundary = -10f;
public float TargetBottomBoundary;
public bool UseLeftBoundary;
public float LeftBoundary = -10f;
public float TargetLeftBoundary;
public bool UseRightBoundary;
public float RightBoundary = 10f;
public float TargetRightBoundary;
public bool IsCameraPositionHorizontallyBounded;
public bool IsCameraPositionVerticallyBounded;
public Coroutine TopBoundaryAnimRoutine;
public Coroutine BottomBoundaryAnimRoutine;
public Coroutine LeftBoundaryAnimRoutine;
public Coroutine RightBoundaryAnimRoutine;
public ProCamera2DTriggerBoundaries CurrentBoundariesTrigger;
public Coroutine MoveCameraToTargetRoutine;
public bool HasFiredTransitionStarted;
public bool HasFiredTransitionFinished;
#region Soft Boundaries
public bool UseSoftBoundaries = true;
[Range(0f, 4f)]
public float Softness = .5f;
[Range(0f, .5f)]
public float SoftAreaSize = .1f;
float _smoothnessVelX = 0f;
float _smoothnessVelY = 0f;
public bool UseBoundaryDelayOnEnterScene = false;
public int BoundaryDelayFrames = 10;
int _elapsedBoundaryDelayFrames;
bool _useSoftBoundariesEditorSetting;
#endregion
protected override void Awake()
{
base.Awake();
_useSoftBoundariesEditorSetting = UseSoftBoundaries;
ProCamera2D.AddPositionDeltaChanger(this);
ProCamera2D.AddSizeOverrider(this);
}
protected override void OnEnable()
{
base.OnEnable();
_elapsedBoundaryDelayFrames = 0;
}
protected override void OnDestroy()
{
base.OnDestroy();
if(ProCamera2D == null) return;
ProCamera2D.RemovePositionDeltaChanger(this);
ProCamera2D.RemoveSizeOverrider(this);
}
#region IPositionDeltaChanger implementation
public Vector3 AdjustDelta(float deltaTime, Vector3 originalDelta)
{
if (!enabled || !UseNumericBoundaries)
return originalDelta;
if (UseBoundaryDelayOnEnterScene && _elapsedBoundaryDelayFrames < BoundaryDelayFrames)
{
UseSoftBoundaries = false;
_elapsedBoundaryDelayFrames++;
}
else
UseSoftBoundaries = _useSoftBoundariesEditorSetting;
// Check movement in the horizontal dir
IsCameraPositionHorizontallyBounded = false;
ProCamera2D.IsCameraPositionLeftBounded = false;
ProCamera2D.IsCameraPositionRightBounded = false;
IsCameraPositionVerticallyBounded = false;
ProCamera2D.IsCameraPositionTopBounded = false;
ProCamera2D.IsCameraPositionBottomBounded = false;
var newPosH = Vector3H(ProCamera2D.LocalPosition) + Vector3H(originalDelta);
var newPosV = Vector3V(ProCamera2D.LocalPosition) + Vector3V(originalDelta);
var halfScreenWidth = ProCamera2D.ScreenSizeInWorldCoordinates.x * .5f;
var halfScreenHeight = ProCamera2D.ScreenSizeInWorldCoordinates.y * .5f;
var cushionH = UseSoftBoundaries ? ProCamera2D.ScreenSizeInWorldCoordinates.x * SoftAreaSize : 0f;
var cushionV = UseSoftBoundaries ? ProCamera2D.ScreenSizeInWorldCoordinates.y * SoftAreaSize : 0f;
if (UseLeftBoundary && newPosH - halfScreenWidth < LeftBoundary + cushionH)
{
if (UseSoftBoundaries)
{
if (Vector3H(originalDelta) <= 0f)
newPosH = Mathf.SmoothDamp(
Mathf.Max(LeftBoundary + halfScreenWidth, Vector3H(ProCamera2D.LocalPosition)),
Mathf.Max(LeftBoundary + halfScreenWidth, newPosH),
ref _smoothnessVelX,
(((LeftBoundary + halfScreenWidth) - Vector3H(ProCamera2D.LocalPosition) + cushionH) / cushionH) * Softness, float.MaxValue, deltaTime);
else
newPosH = Mathf.Max(LeftBoundary + halfScreenWidth, newPosH);
}
else
newPosH = LeftBoundary + halfScreenWidth;
IsCameraPositionHorizontallyBounded = true;
ProCamera2D.IsCameraPositionLeftBounded = true;
}
if (UseRightBoundary && newPosH + halfScreenWidth > RightBoundary - cushionH)
{
if (UseSoftBoundaries)
{
if (Vector3H(originalDelta) >= 0f)
newPosH = Mathf.SmoothDamp(
Mathf.Min(RightBoundary - halfScreenWidth, Vector3H(ProCamera2D.LocalPosition)),
Mathf.Min(RightBoundary - halfScreenWidth, newPosH),
ref _smoothnessVelX,
((Vector3H(ProCamera2D.LocalPosition) - (RightBoundary - halfScreenWidth) + cushionH) / cushionH) * Softness, float.MaxValue, deltaTime);
else
newPosH = Mathf.Min(RightBoundary - halfScreenWidth, newPosH);
}
else
newPosH = RightBoundary - halfScreenWidth;
IsCameraPositionHorizontallyBounded = true;
ProCamera2D.IsCameraPositionRightBounded = true;
}
// Check movement in the vertical dir
if (UseBottomBoundary && newPosV - halfScreenHeight < BottomBoundary + cushionV)
{
if (UseSoftBoundaries)
{
if (Vector3V(originalDelta) <= 0f)
newPosV = Mathf.SmoothDamp(
Mathf.Max(BottomBoundary + halfScreenHeight, Vector3V(ProCamera2D.LocalPosition)),
Mathf.Max(BottomBoundary + halfScreenHeight, newPosV),
ref _smoothnessVelY,
(((BottomBoundary + halfScreenHeight) + cushionV - Vector3V(ProCamera2D.LocalPosition)) / cushionH) * Softness, float.MaxValue, deltaTime);
else
newPosV = Mathf.Max(BottomBoundary + halfScreenHeight, newPosV);
}
else
newPosV = BottomBoundary + halfScreenHeight;
IsCameraPositionVerticallyBounded = true;
ProCamera2D.IsCameraPositionBottomBounded = true;
}
if (UseTopBoundary && newPosV + halfScreenHeight > TopBoundary - cushionV)
{
if (UseSoftBoundaries)
{
if (Vector3V(originalDelta) >= 0f)
newPosV = Mathf.SmoothDamp(
Mathf.Min(TopBoundary - halfScreenHeight, Vector3V(ProCamera2D.LocalPosition)),
Mathf.Min(TopBoundary - halfScreenHeight, newPosV),
ref _smoothnessVelY,
((Vector3V(ProCamera2D.LocalPosition) - (TopBoundary - halfScreenHeight) + cushionV) / cushionH) * Softness, float.MaxValue, deltaTime);
else
newPosV = Mathf.Min(TopBoundary - halfScreenHeight, newPosV);
}
else
newPosV = TopBoundary - halfScreenHeight;
IsCameraPositionVerticallyBounded = true;
ProCamera2D.IsCameraPositionTopBounded = true;
}
// Return the new delta
return VectorHV(newPosH - Vector3H(ProCamera2D.LocalPosition), newPosV - Vector3V(ProCamera2D.LocalPosition));
}
public int PDCOrder { get { return _pdcOrder; } set { _pdcOrder = value; } }
int _pdcOrder = 4000;
#endregion
#region ISizeOverrider implementation
public float OverrideSize(float deltaTime, float originalSize)
{
if (!enabled || !UseNumericBoundaries)
return originalSize;
var newSize = originalSize;
// Set new size if outside boundaries
var cameraMaxSize = new Vector2(RightBoundary - LeftBoundary, TopBoundary - BottomBoundary);
if (UseRightBoundary && UseLeftBoundary && originalSize * ProCamera2D.GameCamera.aspect * 2f > cameraMaxSize.x)
{
newSize = cameraMaxSize.x / ProCamera2D.GameCamera.aspect * .5f;
}
if (UseTopBoundary && UseBottomBoundary && newSize * 2f > cameraMaxSize.y)
{
newSize = cameraMaxSize.y * .5f;
}
return newSize;
}
public int SOOrder { get { return _soOrder; } set { _soOrder = value; } }
int _soOrder = 2000;
#endregion
#if UNITY_EDITOR
override protected void DrawGizmos()
{
base.DrawGizmos();
if (UseNumericBoundaries)
{
var gameCamera = ProCamera2D.GetComponent<Camera>();
var cameraDimensions = gameCamera.orthographic ? Utils.GetScreenSizeInWorldCoords(gameCamera) : Utils.GetScreenSizeInWorldCoords(gameCamera, Mathf.Abs(Vector3D(transform.localPosition)));
float cameraDepthOffset = Vector3D(ProCamera2D.transform.localPosition) + Mathf.Abs(Vector3D(transform.localPosition)) * Vector3D(ProCamera2D.transform.forward);
Gizmos.color = EditorPrefsX.GetColor(PrefsData.NumericBoundariesColorKey, PrefsData.NumericBoundariesColorValue);
if (UseTopBoundary)
Gizmos.DrawRay(VectorHVD(Vector3H(transform.localPosition) - cameraDimensions.x * .5f, TopBoundary, cameraDepthOffset), transform.right * cameraDimensions.x);
if (UseBottomBoundary)
Gizmos.DrawRay(VectorHVD(Vector3H(transform.localPosition) - cameraDimensions.x * .5f, BottomBoundary, cameraDepthOffset), transform.right * cameraDimensions.x);
if (UseRightBoundary)
Gizmos.DrawRay(VectorHVD(RightBoundary, Vector3V(transform.localPosition) - cameraDimensions.y * .5f, cameraDepthOffset), transform.up * cameraDimensions.y);
if (UseLeftBoundary)
Gizmos.DrawRay(VectorHVD(LeftBoundary, Vector3V(transform.localPosition) - cameraDimensions.y * .5f, cameraDepthOffset), transform.up * cameraDimensions.y);
if (UseSoftBoundaries)
{
Gizmos.color = new Color(Gizmos.color.r, Gizmos.color.g, Gizmos.color.b, Gizmos.color.a * .3f);
if (UseTopBoundary)
Gizmos.DrawRay(VectorHVD(Vector3H(transform.localPosition) - cameraDimensions.x * .5f, TopBoundary - cameraDimensions.y * SoftAreaSize, cameraDepthOffset), transform.right * cameraDimensions.x);
if (UseBottomBoundary)
Gizmos.DrawRay(VectorHVD(Vector3H(transform.localPosition) - cameraDimensions.x * .5f, BottomBoundary + cameraDimensions.y * SoftAreaSize, cameraDepthOffset), transform.right * cameraDimensions.x);
if (UseRightBoundary)
Gizmos.DrawRay(VectorHVD(RightBoundary - cameraDimensions.x * SoftAreaSize, Vector3V(transform.localPosition) - cameraDimensions.y * .5f, cameraDepthOffset), transform.up * cameraDimensions.y);
if (UseLeftBoundary)
Gizmos.DrawRay(VectorHVD(LeftBoundary + cameraDimensions.x * SoftAreaSize, Vector3V(transform.localPosition) - cameraDimensions.y * .5f, cameraDepthOffset), transform.up * cameraDimensions.y);
}
}
}
#endif
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 6903f12ac8ae44a41ba2a44700ec60ed
timeCreated: 1454606401
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,643 @@
using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems;
using System;
namespace Com.LuisPedroFonseca.ProCamera2D
{
[HelpURLAttribute("http://www.procamera2d.com/user-guide/extension-pan-and-zoom/")]
public class ProCamera2DPanAndZoom : BasePC2D, IPreMover
{
public enum MouseButton
{
Left = 0,
Right = 1,
Middle = 2
}
public static string ExtensionName = "Pan And Zoom";
// Events
public Action OnPanStarted;
public Action OnPanFinished;
// Input
public bool AutomaticInputDetection = true;
public bool UseMouseInput;
public bool UseTouchInput;
public bool DisableOverUGUI = true;
// Zoom
public bool AllowZoom = true;
public float MouseZoomSpeed = 10f;
public float PinchZoomSpeed = 50f;
[Range(0, 2f)]
public float ZoomSmoothness = .2f;
public float MaxZoomInAmount = 2f;
public float MaxZoomOutAmount = 2f;
public bool ZoomToInputCenter = true;
[HideInInspector]
public bool IsZooming;
float _zoomAmount;
float _initialCamSize;
bool _zoomStarted;
float _origFollowSmoothnessX;
float _origFollowSmoothnessY;
float _prevZoomAmount;
float _zoomVelocity;
Vector3 _zoomPoint;
float _touchZoomTime;
// Pan
public bool AllowPan = true;
public bool UsePanByDrag = true;
[Range(0f, 1f)]
public float StopSpeedOnDragStart = .95f;
public Rect DraggableAreaRect = new Rect(0f, 0f, 1f, 1f);
public Vector2 DragPanSpeedMultiplier = new Vector2(1f, 1f);
public bool UsePanByMoveToEdges = false;
public Vector2 EdgesPanSpeed = new Vector2(2f, 2f);
[Range(0, .99f)]
public float TopPanEdge = .9f;
[Range(0, .99f)]
public float BottomPanEdge = .9f;
[Range(0, .99f)]
public float LeftPanEdge = .9f;
[Range(0, .99f)]
public float RightPanEdge = .9f;
public MouseButton PanMouseButton;
public float MinPanAmount = .05f;
[HideInInspector]
public bool ResetPrevPanPoint;
[HideInInspector]
public bool IsPanning;
Vector2 _panDelta;
Transform _panTarget;
Vector3 _prevMousePosition;
Vector3 _prevTouchPosition;
int _prevTouchId;
bool _onMaxZoom;
bool _onMinZoom;
EventSystem _eventSystem;
bool _skip;
Vector3 _startPanWorldPos;
protected override void Awake()
{
base.Awake();
if (AutomaticInputDetection)
{
UseMouseInput = !Input.touchSupported;
UseTouchInput = Input.touchSupported;
}
UpdateCurrentFollowSmoothness();
_eventSystem = EventSystem.current;
_panTarget = new GameObject("PC2DPanTarget").transform;
ProCamera2D.AddPreMover(this);
}
protected override void OnDestroy()
{
base.OnDestroy();
if(ProCamera2D)
ProCamera2D.RemovePreMover(this);
}
IEnumerator Start()
{
_initialCamSize = ProCamera2D.ScreenSizeInWorldCoordinates.y * .5f;
yield return null;
if(gameObject.scene.buildIndex == -1)
DontDestroyOnLoad(_panTarget.gameObject);
}
protected override void OnEnable()
{
base.OnEnable();
_initialCamSize = ProCamera2D.ScreenSizeInWorldCoordinates.y * .5f;
ProCamera2D.AddCameraTarget(_panTarget);
CenterPanTargetOnCamera();
}
protected override void OnDisable()
{
base.OnDisable();
ResetPrevPanPoint = true;
_onMaxZoom = false;
_onMinZoom = false;
ProCamera2D.RemoveCameraTarget(_panTarget);
}
#region IPreMover implementation
public void PreMove(float deltaTime)
{
// Detect if the user is pointing over an UI element
if (UseTouchInput)
{
_skip = DisableOverUGUI && _eventSystem;
if (_skip)
{
_skip = false;
for (int i = 0; i < Input.touchCount; i++)
{
if (_eventSystem.IsPointerOverGameObject(Input.GetTouch(i).fingerId))
{
_skip = true;
break;
}
}
}
if (_skip)
{
_prevTouchPosition = new Vector3(Input.GetTouch(0).position.x, Input.GetTouch(0).position.y, Mathf.Abs(Vector3D(ProCamera2D.LocalPosition)));
CancelZoom();
}
}
if (UseMouseInput)
{
_skip = DisableOverUGUI && _eventSystem && _eventSystem.IsPointerOverGameObject();
if (_skip)
{
_prevMousePosition = new Vector3(Input.mousePosition.x, Input.mousePosition.y, Mathf.Abs(Vector3D(ProCamera2D.LocalPosition)));
CancelZoom();
}
}
IsZooming = false;
if (enabled && AllowPan && !_skip)
Pan(deltaTime);
if (enabled && AllowZoom && !_skip)
Zoom(deltaTime);
}
public int PrMOrder { get { return _prmOrder; } set { _prmOrder = value; } }
int _prmOrder = 0;
#endregion
void Pan(float deltaTime)
{
_panDelta = Vector2.zero;
if (UseTouchInput)
{
// Time since zoom
if (Time.time - _touchZoomTime < .1f)
{
if (Input.touchCount > 0)
_prevTouchPosition = new Vector3(Input.GetTouch(0).position.x, Input.GetTouch(0).position.y, Mathf.Abs(Vector3D(ProCamera2D.LocalPosition)));
return;
}
// Touch delta
if (AllowZoom && Input.touchCount == 1 ||
!AllowZoom && Input.touchCount > 0)
{
var touch = Input.GetTouch(Input.touchCount - 1);
if (touch.phase == TouchPhase.Began)
{
_prevTouchId = touch.fingerId;
_prevTouchPosition = new Vector3(touch.position.x, touch.position.y, Mathf.Abs(Vector3D(ProCamera2D.LocalPosition)));
_startPanWorldPos = ProCamera2D.GameCamera.ScreenToWorldPoint(_prevTouchPosition);
}
// Ignore if using different finger or touch not moving
if (touch.fingerId != _prevTouchId || touch.phase != TouchPhase.Moved)
return;
var touchPos = new Vector3(touch.position.x, touch.position.y, Mathf.Abs(Vector3D(ProCamera2D.LocalPosition)));
var normalizedTouchPos = new Vector2(touch.position.x / ProCamera2D.GameCamera.pixelWidth, touch.position.y / ProCamera2D.GameCamera.pixelHeight);
if (ProCamera2D.GameCamera.pixelRect.Contains(touchPos) && InsideDraggableArea(normalizedTouchPos))
{
var prevTouchPositionWorldCoord = ProCamera2D.GameCamera.ScreenToWorldPoint(_prevTouchPosition);
var currentTouchPositionWorldCoord = ProCamera2D.GameCamera.ScreenToWorldPoint(touchPos);
if (IsPanning)
{
if (ResetPrevPanPoint)
{
prevTouchPositionWorldCoord = ProCamera2D.GameCamera.ScreenToWorldPoint(touchPos);
ResetPrevPanPoint = false;
}
var panDelta = prevTouchPositionWorldCoord - currentTouchPositionWorldCoord;
_panDelta = new Vector2(Vector3H(panDelta), Vector3V(panDelta));
}
else
{
// Detect pan start
var screenSize = (ProCamera2D.ScreenSizeInWorldCoordinates.x + ProCamera2D.ScreenSizeInWorldCoordinates.y) / 2;
var dragDistancePerc = Vector3.Distance(currentTouchPositionWorldCoord, _startPanWorldPos) / screenSize;
if (dragDistancePerc > MinPanAmount)
{
CenterPanTargetOnCamera(StopSpeedOnDragStart);
StartPanning();
}
}
}
_prevTouchPosition = touchPos;
}
if (IsPanning && Input.touchCount == 0)
StopPanning();
}
var panSpeed = DragPanSpeedMultiplier;
if (UseMouseInput)
{
var mousePos = new Vector3(Input.mousePosition.x, Input.mousePosition.y,
Mathf.Abs(Vector3D(ProCamera2D.LocalPosition)));
if (Input.GetMouseButtonDown((int) PanMouseButton))
{
_startPanWorldPos = ProCamera2D.GameCamera.ScreenToWorldPoint(mousePos);
}
// Detect pan start
if (UsePanByDrag && Input.GetMouseButton((int)PanMouseButton) && !IsPanning)
{
var mousePosWorldCoord = ProCamera2D.GameCamera.ScreenToWorldPoint(mousePos);
var screenSize = (ProCamera2D.ScreenSizeInWorldCoordinates.x + ProCamera2D.ScreenSizeInWorldCoordinates.y) / 2;
var dragDistancePerc = Vector3.Distance(mousePosWorldCoord, _startPanWorldPos) / screenSize;
if (dragDistancePerc > MinPanAmount)
{
CenterPanTargetOnCamera(StopSpeedOnDragStart);
StartPanning();
}
}
// Mouse drag delta
if (IsPanning && UsePanByDrag && Input.GetMouseButton((int)PanMouseButton))
{
var normalizedMousePos = new Vector2(Input.mousePosition.x / ProCamera2D.GameCamera.pixelWidth, Input.mousePosition.y / ProCamera2D.GameCamera.pixelHeight);
if (ProCamera2D.GameCamera.pixelRect.Contains(mousePos) && InsideDraggableArea(normalizedMousePos))
{
var prevMousePositionWorldCoord = ProCamera2D.GameCamera.ScreenToWorldPoint(_prevMousePosition);
if (ResetPrevPanPoint)
{
prevMousePositionWorldCoord = ProCamera2D.GameCamera.ScreenToWorldPoint(mousePos);
ResetPrevPanPoint = false;
}
var panDelta = prevMousePositionWorldCoord - ProCamera2D.GameCamera.ScreenToWorldPoint(mousePos);
_panDelta = new Vector2(Vector3H(panDelta), Vector3V(panDelta));
}
}
// Move to edges delta
else if (UsePanByMoveToEdges && !Input.GetMouseButton((int)PanMouseButton))
{
var normalizedMousePosX = (-Screen.width * .5f + Input.mousePosition.x) / Screen.width;
var normalizedMousePosY = (-Screen.height * .5f + Input.mousePosition.y) / Screen.height;
if (normalizedMousePosX < 0)
normalizedMousePosX = normalizedMousePosX.Remap(-.5f, -LeftPanEdge * .5f, -.5f, 0f);
else if (normalizedMousePosX > 0)
normalizedMousePosX = normalizedMousePosX.Remap(RightPanEdge * .5f, .5f, 0f, .5f);
if (normalizedMousePosY < 0)
normalizedMousePosY = normalizedMousePosY.Remap(-.5f, -BottomPanEdge * .5f, -.5f, 0f);
else if (normalizedMousePosY > 0)
normalizedMousePosY = normalizedMousePosY.Remap(TopPanEdge * .5f, .5f, 0f, .5f);
_panDelta = new Vector2(normalizedMousePosX, normalizedMousePosY) * deltaTime;
if (_panDelta != Vector2.zero)
panSpeed = EdgesPanSpeed;
}
if (IsPanning && UsePanByDrag && !Input.GetMouseButton((int)PanMouseButton))
StopPanning();
// Prevent unintentional pans when outside of the GameView on the editor
#if UNITY_EDITOR
Rect screenRect = new Rect(0, 0, Screen.width, Screen.height);
if (screenRect.Contains(Input.mousePosition) == false ||
screenRect.Contains(_prevMousePosition) == false)
{
_panDelta = Vector2.zero;
}
#endif
_prevMousePosition = mousePos;
}
// Move
if(_panDelta != Vector2.zero)
{
var delta = VectorHV(_panDelta.x * panSpeed.x, _panDelta.y * panSpeed.y);
_panTarget.Translate(delta);
}
// Check if target is outside of bounds
if ((ProCamera2D.IsCameraPositionLeftBounded && Vector3H(_panTarget.position) < Vector3H(ProCamera2D.LocalPosition)) ||
(ProCamera2D.IsCameraPositionRightBounded && Vector3H(_panTarget.position) > Vector3H(ProCamera2D.LocalPosition)))
_panTarget.position = VectorHVD(
Vector3H(ProCamera2D.LocalPosition) - ProCamera2D.GetOffsetX() * 0.9999f, // The multiplier avoids floating-point comparison errors
Vector3V(_panTarget.position),
Vector3D(_panTarget.position));
if ((ProCamera2D.IsCameraPositionBottomBounded && Vector3V(_panTarget.position) < Vector3V(ProCamera2D.LocalPosition)) ||
(ProCamera2D.IsCameraPositionTopBounded && Vector3V(_panTarget.position) > Vector3V(ProCamera2D.LocalPosition)))
_panTarget.position = VectorHVD(
Vector3H(_panTarget.position),
Vector3V(ProCamera2D.LocalPosition) - ProCamera2D.GetOffsetY() * 0.9999f, // The multiplier avoids floating-point comparison errors
Vector3D(_panTarget.position));
}
void StartPanning()
{
IsPanning = true;
RestoreFollowSmoothness();
if (OnPanStarted != null)
OnPanStarted();
}
void StopPanning()
{
IsPanning = false;
if (OnPanFinished != null)
OnPanFinished();
}
void Zoom(float deltaTime)
{
var zoomInput = 0f;
if (UseTouchInput)
{
if (Input.touchCount == 2)
{
var touchZero = Input.GetTouch(0);
var touchOne = Input.GetTouch(1);
var touchZeroPrevPos = touchZero.position - new Vector2(touchZero.deltaPosition.x / Screen.width, touchZero.deltaPosition.y / Screen.height);
var touchOnePrevPos = touchOne.position - new Vector2(touchOne.deltaPosition.x / Screen.width, touchOne.deltaPosition.y / Screen.height);
var prevTouchDeltaMag = (touchZeroPrevPos - touchOnePrevPos).magnitude;
var touchDeltaMag = (touchZero.position - touchOne.position).magnitude;
// Zoom input
zoomInput = prevTouchDeltaMag - touchDeltaMag;
// Zoom point
var midTouch = Vector2.Lerp(touchZero.position, touchOne.position, .5f);
_zoomPoint = new Vector3(midTouch.x, midTouch.y, Mathf.Abs(Vector3D(ProCamera2D.LocalPosition)));
// Smoothness to 0
if (!_zoomStarted)
{
_zoomStarted = true;
_panTarget.position = ProCamera2D.LocalPosition - ProCamera2D.InfluencesSum;
UpdateCurrentFollowSmoothness();
RemoveFollowSmoothness();
}
// Save time
_touchZoomTime = Time.time;
}
else
{
// Reset smoothness
if (_zoomStarted && Mathf.Abs(_zoomAmount) < .001f)
{
RestoreFollowSmoothness();
_zoomStarted = false;
}
}
}
if(UseMouseInput)
{
// Zoom input
zoomInput = Input.GetAxis("Mouse ScrollWheel");
// Zoom point
_zoomPoint = new Vector3(Input.mousePosition.x, Input.mousePosition.y, Mathf.Abs(Vector3D(ProCamera2D.LocalPosition)));
}
// Stop zoom if zoomPoint not on this camera
if (!ProCamera2D.GameCamera.pixelRect.Contains(_zoomPoint))
return;
// Different zoom speed according to the platform
var zoomSpeed = UseTouchInput ? PinchZoomSpeed * 10f : MouseZoomSpeed;
// Cancel zoom if max/min reached
if ((_onMaxZoom && zoomInput * zoomSpeed < 0) || (_onMinZoom && zoomInput * zoomSpeed > 0))
{
CancelZoom();
return;
}
// Zoom amount
_zoomAmount = Mathf.SmoothDamp(_prevZoomAmount, zoomInput * zoomSpeed, ref _zoomVelocity, ZoomSmoothness, float.MaxValue, deltaTime);
if (UseMouseInput)
{
// Reset smoothness once zoom stops
if (Mathf.Abs(_zoomAmount) <= .0001f)
{
if (_zoomStarted)
RestoreFollowSmoothness();
_zoomStarted = false;
_prevZoomAmount = 0;
return;
}
// Smoothness to 0
if (!_zoomStarted)
{
_zoomStarted = true;
_panTarget.position = ProCamera2D.LocalPosition - ProCamera2D.InfluencesSum;
UpdateCurrentFollowSmoothness();
RemoveFollowSmoothness();
}
}
// Clamp zoom amount
var targetSize = (ProCamera2D.ScreenSizeInWorldCoordinates.y / 2) + _zoomAmount;
var minScreenSize = _initialCamSize / MaxZoomInAmount;
var maxScreenSize = MaxZoomOutAmount * _initialCamSize;
_onMaxZoom = false;
_onMinZoom = false;
if (targetSize < minScreenSize)
{
_zoomAmount -= targetSize - minScreenSize;
_onMaxZoom = true;
}
else if (targetSize > maxScreenSize)
{
_zoomAmount -= targetSize - maxScreenSize;
_onMinZoom = true;
}
// Save previous zoom amount
_prevZoomAmount = _zoomAmount;
// Move camera towards zoom point
if (ZoomToInputCenter && _zoomAmount != 0)
{
var multiplier = _zoomAmount / (ProCamera2D.ScreenSizeInWorldCoordinates.y / 2);
_panTarget.position += ((_panTarget.position - ProCamera2D.GameCamera.ScreenToWorldPoint(_zoomPoint)) * multiplier);
}
// Zoom
ProCamera2D.Zoom(_zoomAmount);
IsZooming = true;
}
/// <summary>
/// Call this method after manually updating the camera follow smoothness
/// </summary>
public void UpdateCurrentFollowSmoothness()
{
_origFollowSmoothnessX = ProCamera2D.HorizontalFollowSmoothness;
_origFollowSmoothnessY = ProCamera2D.VerticalFollowSmoothness;
}
/// <summary>
/// Use this method to center the pan target on the current camera position.
/// Useful for situations where you controlled the camera using other methods (like cinematics)
/// </summary>
public void CenterPanTargetOnCamera(float interpolant = 1f)
{
if (_panTarget != null)
_panTarget.position = Vector3.Lerp(
_panTarget.position,
VectorHV(Vector3H(ProCamera2D.LocalPosition) - ProCamera2D.GetOffsetX(), Vector3V(ProCamera2D.LocalPosition) - ProCamera2D.GetOffsetY()),
interpolant);
}
void CancelZoom()
{
_zoomAmount = 0f;
_prevZoomAmount = 0f;
_zoomVelocity = 0f;
}
void RestoreFollowSmoothness()
{
ProCamera2D.HorizontalFollowSmoothness = _origFollowSmoothnessX;
ProCamera2D.VerticalFollowSmoothness = _origFollowSmoothnessY;
}
void RemoveFollowSmoothness()
{
ProCamera2D.HorizontalFollowSmoothness = 0;
ProCamera2D.VerticalFollowSmoothness = 0;
}
bool InsideDraggableArea(Vector2 normalizedInput)
{
if (DraggableAreaRect.x == 0 &&
DraggableAreaRect.y == 0 &&
DraggableAreaRect.width == 1 &&
DraggableAreaRect.height == 1)
return true;
if (normalizedInput.x > DraggableAreaRect.x + (1 - DraggableAreaRect.width) / 2 &&
normalizedInput.x < DraggableAreaRect.x + DraggableAreaRect.width + (1 - DraggableAreaRect.width) / 2 &&
normalizedInput.y > DraggableAreaRect.y + (1 - DraggableAreaRect.height) / 2 &&
normalizedInput.y < DraggableAreaRect.y + DraggableAreaRect.height + (1 - DraggableAreaRect.height) / 2)
return true;
return false;
}
#if UNITY_EDITOR
protected override void DrawGizmos()
{
base.DrawGizmos();
Gizmos.color = EditorPrefsX.GetColor(PrefsData.PanEdgesColorKey, PrefsData.PanEdgesColorValue);
var gameCamera = ProCamera2D.GetComponent<Camera>();
var cameraDimensions = gameCamera.orthographic ? Utils.GetScreenSizeInWorldCoords(gameCamera) : Utils.GetScreenSizeInWorldCoords(gameCamera, Mathf.Abs(Vector3D(transform.localPosition)));
float cameraDepthOffset = Vector3D(ProCamera2D.transform.localPosition) + Mathf.Abs(Vector3D(transform.localPosition)) * Vector3D(ProCamera2D.transform.forward);
if (UsePanByMoveToEdges)
{
Gizmos.DrawWireCube(
VectorHVD(
Vector3H(ProCamera2D.transform.localPosition) - (LeftPanEdge * cameraDimensions.x / 4f) + (RightPanEdge * cameraDimensions.x / 4f),
Vector3V(ProCamera2D.transform.localPosition) - (BottomPanEdge * cameraDimensions.y / 4f) + (TopPanEdge * cameraDimensions.y / 4f),
cameraDepthOffset),
VectorHV(
cameraDimensions.x * ((LeftPanEdge + RightPanEdge) / 2f),
cameraDimensions.y * ((TopPanEdge + BottomPanEdge) / 2f)));
}
if (UsePanByDrag)
{
if (DraggableAreaRect.x != 0 ||
DraggableAreaRect.y != 0 ||
DraggableAreaRect.width != 1 ||
DraggableAreaRect.height != 1)
Gizmos.DrawWireCube(
VectorHVD(ProCamera2D.transform.localPosition.x + DraggableAreaRect.x * cameraDimensions.x, ProCamera2D.transform.localPosition.y + DraggableAreaRect.y * cameraDimensions.y, cameraDepthOffset),
VectorHV(DraggableAreaRect.width * cameraDimensions.x, DraggableAreaRect.height * cameraDimensions.y));
}
}
#endif
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: e1f4d7058517540a6926e80c9fef48db
timeCreated: 1455023230
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,212 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Com.LuisPedroFonseca.ProCamera2D
{
[System.Serializable]
public class ProCamera2DParallaxLayer
{
public Camera ParallaxCamera;
[Range(0, 5)]
public float Speed = 1.0f;
[Range(0, 5)]
public float SpeedX = 1.0f;
[Range(0, 5)]
public float SpeedY = 1.0f;
public LayerMask LayerMask;
[HideInInspector][System.NonSerialized]
public Transform CameraTransform;
}
[HelpURLAttribute("http://www.procamera2d.com/user-guide/extension-parallax/")]
[ExecuteInEditMode]
public class ProCamera2DParallax : BasePC2D, IPostMover
{
public static string ExtensionName = "Parallax";
public List<ProCamera2DParallaxLayer> ParallaxLayers = new List<ProCamera2DParallaxLayer>();
public bool ParallaxHorizontal = true;
public bool ParallaxVertical = true;
public bool ParallaxZoom = true;
public Vector3 RootPosition = Vector3.zero;
public int FrontDepthStart = 1;
public int BackDepthStart = -1;
public bool UseIndependentAxisSpeeds;
public bool AutomaticallyConfigureCameraClearFlags = true;
float _initialOrtographicSize;
float[] _initialSpeeds;
Coroutine _animateCoroutine;
protected override void Awake()
{
base.Awake();
if (ProCamera2D == null)
return;
if (Application.isPlaying)
CalculateParallaxObjectsOffset();
foreach (var layer in ParallaxLayers)
{
if (layer.ParallaxCamera != null)
{
layer.CameraTransform = layer.ParallaxCamera.transform;
}
}
// We need this so we can toggle on/off the parallax
_initialSpeeds = new float[ParallaxLayers.Count];
for (int i = 0; i < _initialSpeeds.Length; i++)
{
_initialSpeeds[i] = ParallaxLayers[i].Speed;
}
// Disable the extension if the camera is not in orthographic projection
if (ProCamera2D.GameCamera != null)
{
_initialOrtographicSize = ProCamera2D.GameCamera.orthographicSize;
if (!ProCamera2D.GameCamera.orthographic)
enabled = false;
}
ProCamera2D.AddPostMover(this);
}
protected override void OnDestroy()
{
base.OnDestroy();
if(ProCamera2D)
ProCamera2D.RemovePostMover(this);
}
#region IPostMover implementation
public void PostMove(float deltaTime)
{
if(enabled)
Move();
}
public int PMOrder { get { return _pmOrder; } set { _pmOrder = value; } }
int _pmOrder = 1000;
#endregion
#if UNITY_EDITOR
void LateUpdate()
{
if(!Application.isPlaying)
Move();
}
#endif
public void CalculateParallaxObjectsOffset()
{
// Find all parallax objects
var parallaxObjs = FindObjectsOfType<ProCamera2DParallaxObject>();
// Create dictionary that links Unity layers to ProCamera2D parallax layers
var layersDic = new Dictionary<int, ProCamera2DParallaxLayer>();
for (int i = 0; i <= 31; i++)
{
foreach (var parallaxLayer in ParallaxLayers)
{
if (parallaxLayer.LayerMask == (parallaxLayer.LayerMask | (1 << i)))
{
layersDic[i] = parallaxLayer;
}
}
}
// Apply offset to parallax objects according to the parallax layer they're part of
for (int i = 0; i < parallaxObjs.Length; i++)
{
// Position
var parallaxObjPosition = parallaxObjs[i].transform.position - RootPosition;
var x = Vector3H(parallaxObjPosition) * (UseIndependentAxisSpeeds ? layersDic[parallaxObjs[i].gameObject.layer].SpeedX : layersDic[parallaxObjs[i].gameObject.layer].Speed);
var y = Vector3V(parallaxObjPosition) * (UseIndependentAxisSpeeds ? layersDic[parallaxObjs[i].gameObject.layer].SpeedY : layersDic[parallaxObjs[i].gameObject.layer].Speed);
parallaxObjs[i].transform.position = VectorHVD(x, y, Vector3D(parallaxObjPosition)) + RootPosition;
}
}
void Move()
{
var rootOffset = _transform.position - RootPosition;
for (int i = 0; i < ParallaxLayers.Count; i++)
{
if (ParallaxLayers[i].CameraTransform != null)
{
// Rect
ParallaxLayers[i].ParallaxCamera.rect = ProCamera2D.GameCamera.rect;
// Position
float x = ParallaxHorizontal ? Vector3H(rootOffset) * (UseIndependentAxisSpeeds ? ParallaxLayers[i].SpeedX : ParallaxLayers[i].Speed) : Vector3H(rootOffset);
float y = ParallaxVertical ? Vector3V(rootOffset) * (UseIndependentAxisSpeeds ? ParallaxLayers[i].SpeedY : ParallaxLayers[i].Speed) : Vector3V(rootOffset);
ParallaxLayers[i].CameraTransform.position = RootPosition + VectorHVD(x, y, Vector3D(_transform.position));
// Zoom
if (ParallaxZoom)
{
ParallaxLayers[i].ParallaxCamera.orthographicSize = _initialOrtographicSize + (ProCamera2D.GameCamera.orthographicSize - _initialOrtographicSize) * ParallaxLayers[i].Speed;
}
}
}
}
/// <summary>
/// Enable or disable parallaxing.
/// </summary>
/// <param name="value">On or off</param>
/// <param name="duration">Duration.</param>
/// <param name="easeType">Ease type.</param>
public void ToggleParallax(bool value, float duration = 2f, EaseType easeType = EaseType.EaseInOut)
{
if (_initialSpeeds == null)
return;
if (_animateCoroutine != null)
StopCoroutine(_animateCoroutine);
_animateCoroutine = StartCoroutine(Animate(value, duration, easeType));
}
IEnumerator Animate(bool value, float duration, EaseType easeType)
{
var currentSpeeds = new float[ParallaxLayers.Count];
for (int i = 0; i < currentSpeeds.Length; i++)
{
currentSpeeds[i] = ParallaxLayers[i].Speed;
}
var t = 0f;
while (t <= 1.0f)
{
t += ProCamera2D.DeltaTime / duration;
for (int i = 0; i < ParallaxLayers.Count; i++)
{
if (value)
ParallaxLayers[i].Speed = Utils.EaseFromTo(currentSpeeds[i], _initialSpeeds[i], t, easeType);
else
ParallaxLayers[i].Speed = Utils.EaseFromTo(currentSpeeds[i], 1, t, easeType);
}
yield return ProCamera2D.GetYield();
}
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 2744f1f739b1144e291cf00c8531e49c
timeCreated: 1455022402
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,203 @@
using UnityEngine;
namespace Com.LuisPedroFonseca.ProCamera2D
{
public enum AutoScaleMode
{
None,
Floor,
Ceil,
Round
}
[HelpURLAttribute("http://www.procamera2d.com/user-guide/extension-pixel-perfect/")]
public class ProCamera2DPixelPerfect : BasePC2D, IPositionOverrider
{
public static string ExtensionName = "Pixel Perfect";
public float PixelsPerUnit = 32;
public AutoScaleMode ViewportAutoScale = AutoScaleMode.Round;
public Vector2 TargetViewportSizeInPixels = new Vector2(80.0f, 50.0f);
public int Zoom
{
get { return _zoom; }
set
{
_zoom = value;
ResizeCameraToPixelPerfect();
}
}
[Range(1, 32)]
[SerializeField]
private int _zoom = 1;
public bool SnapMovementToGrid;
public bool SnapCameraToGrid = true;
public bool DrawGrid;
public Color GridColor = new Color(1f, 0f, 0f, .1f);
public float GridDensity;
/// <summary>
/// Returns the current viewport scale. This can be useful for other components (like a CanvasScaler for example)
/// </summary>
public float ViewportScale { get; private set; }
public float PixelStep
{
get
{
#if UNITY_EDITOR
if (!Application.isPlaying && _pixelStep < 0)
ResizeCameraToPixelPerfect();
#endif
return _pixelStep;
}
}
float _pixelStep = -1;
Transform _parent;
override protected void Awake()
{
base.Awake();
if (!ProCamera2D.GameCamera.orthographic)
{
enabled = false;
return;
}
ResizeCameraToPixelPerfect();
ProCamera2D.AddPositionOverrider(this);
}
protected override void OnDestroy()
{
base.OnDestroy();
if(ProCamera2D)
ProCamera2D.RemovePositionOverrider(this);
}
#region IPositionOverrider implementation
public Vector3 OverridePosition(float deltaTime, Vector3 originalPosition)
{
if (!enabled)
return originalPosition;
// We do this so we can have the camera movement not snapping to the grid, while the sprites are
var cameraPixelStep = _pixelStep;
if (SnapMovementToGrid && !SnapCameraToGrid)
cameraPixelStep = 1f / (PixelsPerUnit * (ViewportScale + Zoom - 1));
// If shaking, align the shake parent position to pixel-perfect
_parent = _transform.parent;
if (_parent != null && _parent.position != Vector3.zero)
_parent.position = VectorHVD(Utils.AlignToGrid(Vector3H(_parent.position), cameraPixelStep), Utils.AlignToGrid(Vector3V(_parent.position), cameraPixelStep), Vector3D(_parent.position));
return VectorHVD(Utils.AlignToGrid(Vector3H(originalPosition), cameraPixelStep), Utils.AlignToGrid(Vector3V(originalPosition), cameraPixelStep), 0);
}
public int POOrder { get { return _poOrder; } set { _poOrder = value; } }
int _poOrder = 2000;
#endregion
#if UNITY_EDITOR
void LateUpdate()
{
if (!Application.isPlaying)
ResizeCameraToPixelPerfect();
}
#endif
/// <summary>
/// Resizes the camera to a pixel perfect size
/// </summary>
public void ResizeCameraToPixelPerfect()
{
ViewportScale = CalculateViewportScale();
_pixelStep = CalculatePixelStep(ViewportScale);
var newSize = ((ProCamera2D.GameCamera.pixelHeight * .5f) * (1f / PixelsPerUnit)) / (ViewportScale + Zoom - 1);
ProCamera2D.UpdateScreenSize(newSize);
}
public float CalculateViewportScale()
{
if (ViewportAutoScale == AutoScaleMode.None)
return 1;
float percentageX = ProCamera2D.GameCamera.pixelWidth / TargetViewportSizeInPixels.x;
float percentageY = ProCamera2D.GameCamera.pixelHeight / TargetViewportSizeInPixels.y;
float viewportScale = percentageX > percentageY ? percentageY : percentageX;
switch (ViewportAutoScale)
{
case AutoScaleMode.Floor:
viewportScale = Mathf.Floor(viewportScale);
break;
case AutoScaleMode.Ceil:
viewportScale = Mathf.Ceil(viewportScale);
break;
case AutoScaleMode.Round:
viewportScale = Mathf.Round(viewportScale);
break;
}
if (viewportScale < 1)
viewportScale = 1;
return viewportScale;
}
float CalculatePixelStep(float viewportScale)
{
return SnapMovementToGrid ? 1f / PixelsPerUnit : 1f / (PixelsPerUnit * (viewportScale + Zoom - 1));
}
#if UNITY_EDITOR
override protected void DrawGizmos()
{
base.DrawGizmos();
if (DrawGrid)
{
Gizmos.color = GridColor;
var gridW = ProCamera2D.ScreenSizeInWorldCoordinates.x / 2;
var gridH = ProCamera2D.ScreenSizeInWorldCoordinates.y / 2;
float step = 1 / PixelsPerUnit;
GridDensity = ProCamera2D.GameCamera.pixelWidth / (gridW * 2 / step);
if (GridDensity < 4)
return;
Vector3 origin = transform.localPosition + 1 * transform.forward - VectorHV(gridW, -gridH);
origin = VectorHVD(Utils.AlignToGrid(Vector3H(origin), step), Utils.AlignToGrid(Vector3V(origin), step), Vector3D(origin));
for (float i = 0; i <= 2 * gridW; i += step)
{
Gizmos.DrawLine(origin + VectorHV(i, 0), origin + VectorHV(i, -2 * gridH));
}
for (float j = 0; j <= 2 * gridH; j += step)
{
Gizmos.DrawLine(origin + VectorHV(0, -j), origin + VectorHV(2 * gridW, -j));
}
}
}
#endif
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 17577239430844efcbdda516df8c1f8e
timeCreated: 1455023231
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,68 @@
using UnityEngine;
namespace Com.LuisPedroFonseca.ProCamera2D
{
[HelpURLAttribute("http://www.procamera2d.com/user-guide/extension-pointer-influence/")]
public class ProCamera2DPointerInfluence : BasePC2D, IPreMover
{
public static string ExtensionName = "Pointer Influence";
public float MaxHorizontalInfluence = 3f;
public float MaxVerticalInfluence = 2f;
public float InfluenceSmoothness = .2f;
Vector2 _influence;
Vector2 _velocity;
protected override void Awake()
{
base.Awake();
ProCamera2D.AddPreMover(this);
}
protected override void OnDestroy()
{
base.OnDestroy();
if(ProCamera2D)
ProCamera2D.RemovePreMover(this);
}
override public void OnReset()
{
_influence = Vector2.zero;
_velocity = Vector2.zero;
}
#region IPreMover implementation
public void PreMove(float deltaTime)
{
if(enabled)
ApplyInfluence(deltaTime);
}
public int PrMOrder { get { return _prmOrder; } set { _prmOrder = value; } }
int _prmOrder = 3000;
#endregion
void ApplyInfluence(float deltaTime)
{
var mousePosViewport = ProCamera2D.GameCamera.ScreenToViewportPoint(Input.mousePosition);
var mousePosViewportH = mousePosViewport.x.Remap(0, 1, -1, 1);
var mousePosViewportV = mousePosViewport.y.Remap(0, 1, -1, 1);
var hInfluence = mousePosViewportH * MaxHorizontalInfluence;
var vInfluence = mousePosViewportV * MaxVerticalInfluence;
_influence = Vector2.SmoothDamp(_influence, new Vector2(hInfluence, vInfluence), ref _velocity, InfluenceSmoothness, Mathf.Infinity, deltaTime);
ProCamera2D.ApplyInfluence(_influence);
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: e424e3d1203784bf28130fc345b6577b
timeCreated: 1436383658
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,274 @@
using UnityEngine;
using System.Collections.Generic;
namespace Com.LuisPedroFonseca.ProCamera2D
{
public enum FollowMode
{
BothAxis,
HorizontalAxis,
VerticalAxis
}
[HelpURLAttribute("http://www.procamera2d.com/user-guide/extension-rails/")]
public class ProCamera2DRails : BasePC2D, IPreMover
{
public static string ExtensionName = "Rails";
[HideInInspector]
public List<Vector3> RailNodes = new List<Vector3>();
public FollowMode FollowMode;
public List<CameraTarget> CameraTargets = new List<CameraTarget>();
Dictionary<CameraTarget, Transform> _cameraTargetsOnRails = new Dictionary<CameraTarget, Transform>();
List<CameraTarget> _tempCameraTargets = new List<CameraTarget>();
KDTree _kdTree;
override protected void Awake()
{
base.Awake();
_kdTree = KDTree.MakeFromPoints(RailNodes.ToArray());
for (int i = 0; i < CameraTargets.Count; i++)
{
var railTransform = new GameObject(CameraTargets[i].TargetTransform.name + "_OnRails").transform;
_cameraTargetsOnRails.Add(
CameraTargets[i],
railTransform
);
var cameraTarget = ProCamera2D.AddCameraTarget(railTransform);
cameraTarget.TargetOffset = CameraTargets[i].TargetOffset;
}
if (CameraTargets.Count == 0)
enabled = false;
ProCamera2D.AddPreMover(this);
Step();
}
protected override void OnDestroy()
{
base.OnDestroy();
if(ProCamera2D)
ProCamera2D.RemovePreMover(this);
}
#region IPreMover implementation
public void PreMove(float deltaTime)
{
if (enabled)
Step();
}
public int PrMOrder { get { return _prmOrder; } set { _prmOrder = value; } }
int _prmOrder = 1000;
#endregion
void Step()
{
var pos = Vector3.zero;
for (int i = 0; i < CameraTargets.Count; i++)
{
switch (FollowMode)
{
case FollowMode.HorizontalAxis:
pos = VectorHVD(
Vector3H(CameraTargets[i].TargetPosition) * CameraTargets[i].TargetInfluenceH,
Vector3V(ProCamera2D.LocalPosition),
0);
break;
case FollowMode.VerticalAxis:
pos = VectorHVD(
Vector3H(ProCamera2D.LocalPosition),
Vector3V(CameraTargets[i].TargetPosition) * CameraTargets[i].TargetInfluenceV,
0);
break;
case FollowMode.BothAxis:
pos = VectorHVD(
Vector3H(CameraTargets[i].TargetPosition) * CameraTargets[i].TargetInfluenceH,
Vector3V(CameraTargets[i].TargetPosition) * CameraTargets[i].TargetInfluenceV,
0);
break;
}
_cameraTargetsOnRails[CameraTargets[i]].position = GetPositionOnRail(pos);
}
}
/// <summary>Add a target for the camera to follow on rails.</summary>
/// <param name="targetTransform">The Transform of the target</param>
/// <param name="targetInfluenceH">The influence this target horizontal position should have when calculating the average position of all the targets</param>
/// <param name="targetInfluenceV">The influence this target vertical position should have when calculating the average position of all the targets</param>
/// <param name="targetOffset">A vector that offsets the target position that the camera will follow</param>
/// <param name="duration">The time it takes for this target to reach it's influence. Use for a more progressive transition.</param>
public void AddRailsTarget(Transform targetTransform, float targetInfluenceH = 1f, float targetInfluenceV = 1f, Vector2 targetOffset = default(Vector2), float duration = 0f)
{
if (GetRailsTarget(targetTransform) != null)
return;
var newCameraTarget = new CameraTarget()
{
TargetTransform = targetTransform,
TargetInfluenceH = targetInfluenceH,
TargetInfluenceV = targetInfluenceV,
TargetOffset = targetOffset
};
CameraTargets.Add(newCameraTarget);
var railTransform = new GameObject(targetTransform.name + "_OnRails").transform;
_cameraTargetsOnRails.Add(
newCameraTarget,
railTransform
);
ProCamera2D.AddCameraTarget(railTransform, targetInfluenceH, targetInfluenceV, duration, targetOffset);
enabled = true;
}
/// <summary>Removes a target from being followed on the rails</summary>
/// <param name="targetTransform">The Transform of the target</param>
public void RemoveRailsTarget(Transform targetTransform)
{
var cameraTarget = GetRailsTarget(targetTransform);
if (cameraTarget != null)
{
CameraTargets.Remove(cameraTarget);
ProCamera2D.RemoveCameraTarget(_cameraTargetsOnRails[cameraTarget]);
Destroy(_cameraTargetsOnRails[cameraTarget].gameObject);
}
}
/// <summary>Gets the corresponding CameraTarget from an object's transform.</summary>
/// <param name="targetTransform">The Transform of the target</param>
public CameraTarget GetRailsTarget(Transform targetTransform)
{
for (int i = 0; i < CameraTargets.Count; i++)
{
if (CameraTargets[i].TargetTransform.GetInstanceID() == targetTransform.GetInstanceID())
{
return CameraTargets[i];
}
}
return null;
}
/// <summary>Disables the rails targets. This method is used by the Rails trigger</summary>
/// <param name="transitionDuration">The time it takes to disable the targets</param>
public void DisableTargets(float transitionDuration = 0f)
{
if(_tempCameraTargets.Count != 0)
return;
for (int i = 0; i < _cameraTargetsOnRails.Count; i++)
{
ProCamera2D.RemoveCameraTarget(_cameraTargetsOnRails[CameraTargets[i]], transitionDuration);
_tempCameraTargets.Add(ProCamera2D.AddCameraTarget(CameraTargets[i].TargetTransform, CameraTargets[i].TargetInfluenceH, CameraTargets[i].TargetInfluenceV, transitionDuration, CameraTargets[i].TargetOffset));
}
}
/// <summary>Enables the rails targets. This method is used by the Rails trigger</summary>
/// <param name="transitionDuration">The time it takes to enable the targets</param>
public void EnableTargets(float transitionDuration = 0f)
{
for (int i = 0; i < _tempCameraTargets.Count; i++)
{
ProCamera2D.RemoveCameraTarget(_tempCameraTargets[i].TargetTransform, transitionDuration);
ProCamera2D.AddCameraTarget(_cameraTargetsOnRails[CameraTargets[i]], 1, 1, transitionDuration);
}
_tempCameraTargets.Clear();
}
Vector3 GetPositionOnRail(Vector3 pos)
{
var closestNode = _kdTree.FindNearest(pos);
if (closestNode == 0)
{
return GetPositionOnRailSegment(RailNodes[0], RailNodes[1], pos);
}
else if (closestNode == RailNodes.Count - 1)
{
return GetPositionOnRailSegment(RailNodes[RailNodes.Count - 1], RailNodes[RailNodes.Count - 2], pos);
}
else
{
var leftSeg = GetPositionOnRailSegment(RailNodes[closestNode - 1], RailNodes[closestNode], pos);
var rightSeg = GetPositionOnRailSegment(RailNodes[closestNode + 1], RailNodes[closestNode], pos);
if ((pos - leftSeg).sqrMagnitude <= (pos - rightSeg).sqrMagnitude)
return leftSeg;
else
return rightSeg;
}
}
Vector3 GetPositionOnRailSegment(Vector3 node1, Vector3 node2, Vector3 pos)
{
var node1ToPos = pos - node1;
var segmentDirection = (node2 - node1).normalized;
float node1Dot = Vector3.Dot(segmentDirection, node1ToPos);
if (node1Dot < 0f)
{
return node1;
}
else if (node1Dot * node1Dot > (node2 - node1).sqrMagnitude)
{
return node2;
}
else
{
var fromNode1 = segmentDirection * node1Dot;
return node1 + fromNode1;
}
}
#if UNITY_EDITOR
override protected void DrawGizmos()
{
base.DrawGizmos();
var cameraDimensions = Utils.GetScreenSizeInWorldCoords(ProCamera2D.GameCamera, Mathf.Abs(Vector3D(transform.localPosition)));
Gizmos.color = EditorPrefsX.GetColor(PrefsData.RailsColorKey, PrefsData.RailsColorValue);
if(_tempCameraTargets.Count > 0)
Gizmos.color = Gizmos.color * .7f;
// Rails nodes
for (int i = 0; i < RailNodes.Count; i++)
{
Gizmos.DrawWireCube(RailNodes[i], cameraDimensions * .01f);
}
// Rails path
if (RailNodes.Count >= 2)
{
for (int i = 0; i < RailNodes.Count - 1; i++)
{
Gizmos.DrawLine(RailNodes[i], RailNodes[i + 1]);
}
}
}
#endif
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 270fcd4170a9e48c68cb78c7df1f5b56
timeCreated: 1447857655
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,341 @@
using UnityEngine;
using System.Collections.Generic;
using System;
namespace Com.LuisPedroFonseca.ProCamera2D
{
[HelpURLAttribute("http://www.procamera2d.com/user-guide/extension-repeater/")]
public class ProCamera2DRepeater : BasePC2D, IPostMover
{
public static string ExtensionName = "Repeater";
public Transform ObjectToRepeat;
public Vector2 ObjectSize = new Vector2(2f, 2f);
public Vector2 ObjectBottomLeft = Vector2.zero;
public bool ObjectOnStage = true;
public bool RepeatHorizontal
{
get{ return _repeatHorizontal; }
set
{
_repeatHorizontal = value;
Refresh();
}
}
public bool _repeatHorizontal = true;
public bool RepeatVertical
{
get{ return _repeatVertical; }
set
{
_repeatVertical = value;
Refresh();
}
}
public bool _repeatVertical = true;
public Camera CameraToUse;
Transform _cameraToUseTransform;
Vector3 _objStartPosition;
private List<RepeatedObject> _allRepeatedObjects;
private Queue<RepeatedObject> _inactiveRepeatedObjects;
IntPoint _prevStartIndex;
IntPoint _prevEndIndex;
private Dictionary<IntPoint, bool> _occupiedIndices;
protected override void Awake()
{
base.Awake();
SetRepeatingObject(ObjectToRepeat, ObjectOnStage);
_cameraToUseTransform = CameraToUse.transform;
ProCamera2D.AddPostMover(this);
}
protected override void OnDestroy()
{
base.OnDestroy();
if(ProCamera2D)
ProCamera2D.RemovePostMover(this);
}
#region IPostMover implementation
public void PostMove(float deltaTime)
{
if(!enabled)
return;
// Get screen size at the object depth
var cameraSize = Utils.GetScreenSizeInWorldCoords(CameraToUse, Vector3D(ProCamera2D.LocalPosition - _objStartPosition));
// Find indices
var cameraPos = _cameraToUseTransform.position;
var camBottomLeft = new Vector2(
Vector3H(cameraPos) - cameraSize.x / 2,
Vector3V(cameraPos) - cameraSize.y / 2);
var camOffset = new Vector2(
camBottomLeft.x - _objStartPosition.x - ObjectBottomLeft.x,
camBottomLeft.y - _objStartPosition.y - ObjectBottomLeft.y);
var startIndex = new IntPoint(
Mathf.FloorToInt(camOffset.x / ObjectSize.x),
Mathf.FloorToInt(camOffset.y / ObjectSize.y));
var copiesNeeded = new IntPoint(
Mathf.CeilToInt(cameraSize.x / ObjectSize.x),
Mathf.CeilToInt(cameraSize.y / ObjectSize.y));
var endIndex = new IntPoint(
startIndex.X + copiesNeeded.X,
startIndex.Y + copiesNeeded.Y);
// If the indices change
if (!startIndex.Equals(_prevStartIndex) || !endIndex.Equals(_prevEndIndex))
{
// Free out of range objects
FreeOutOfRangeObjects(startIndex, endIndex);
// Fill the grid
FillGrid(startIndex, endIndex);
}
_prevStartIndex = startIndex;
_prevEndIndex = endIndex;
}
public int PMOrder { get { return _pmOrder; } set { _pmOrder = value; } }
int _pmOrder = 2000;
#endregion
public void SetRepeatingObject(Transform objectToRepeat, bool isExistingObject)
{
ObjectToRepeat = objectToRepeat;
if (ObjectToRepeat == null)
{
Debug.LogWarning("ProCamera2D Repeater extension - No ObjectToRepeat defined!");
return;
}
_objStartPosition = new Vector3(
Vector3H(ObjectToRepeat.position),
Vector3V(ObjectToRepeat.position),
Vector3D(ObjectToRepeat.position));
if (_allRepeatedObjects != null && _allRepeatedObjects.Count > 0)
{
for (var i = 0; i < _allRepeatedObjects.Count; i++)
{
Destroy(_allRepeatedObjects[i].Transform.gameObject);
}
}
_allRepeatedObjects = new List<RepeatedObject>();
_inactiveRepeatedObjects = new Queue<RepeatedObject>();
_occupiedIndices = new Dictionary<IntPoint, bool>();
_prevStartIndex = new IntPoint();
_prevEndIndex = new IntPoint();
if(isExistingObject)
InitCopy(ObjectToRepeat);
}
void FreeOutOfRangeObjects(IntPoint startIndex, IntPoint endIndex)
{
//Go through the objects list and make them inactive if possible
for (int i = 0; i < _allRepeatedObjects.Count; i++)
{
var repeatedObject = _allRepeatedObjects[i];
if ((repeatedObject.GridPos.X != int.MaxValue && (repeatedObject.GridPos.X < startIndex.X || repeatedObject.GridPos.X > endIndex.X)) ||
(repeatedObject.GridPos.Y != int.MaxValue && (repeatedObject.GridPos.Y < startIndex.Y || repeatedObject.GridPos.Y > endIndex.Y)))
{
// Set index as unoccupied
_occupiedIndices.Remove(repeatedObject.GridPos);
// Add item to inactive list
_inactiveRepeatedObjects.Enqueue(repeatedObject);
// Position it off-screen (it's faster then disabling it)
PositionObject(repeatedObject, IntPoint.MaxValue);
}
}
}
void FillGrid(IntPoint startIndex, IntPoint endIndex)
{
if (!_repeatHorizontal)
{
startIndex.X = 0;
endIndex.X = 0;
}
if (!_repeatVertical)
{
startIndex.Y = 0;
endIndex.Y = 0;
}
// Cycle horizontally
for (int i = startIndex.X; i <= endIndex.X; i++)
{
// Cycle vertically
for (int j = startIndex.Y; j <= endIndex.Y; j++)
{
// Place the copies on the provided range
var gridPos = new IntPoint(i, j);
var isIndexOccupied = false;
if (!_occupiedIndices.TryGetValue(gridPos, out isIndexOccupied))
{
// Create object copy if needed
if (_inactiveRepeatedObjects.Count == 0)
InitCopy(Instantiate(ObjectToRepeat) as Transform, false);
// Set index as occupied
_occupiedIndices[gridPos] = true;
// Retrieve item from inactive list
var repeatedObject = _inactiveRepeatedObjects.Dequeue();
// Position it on-screen
PositionObject(repeatedObject, gridPos);
}
}
}
}
void InitCopy(Transform newCopy, bool positionOffscreen = true)
{
var repeatedObject = new RepeatedObject
{
Transform = newCopy
};
repeatedObject.Transform.SetParent(ObjectToRepeat.parent);
_allRepeatedObjects.Add(repeatedObject);
_inactiveRepeatedObjects.Enqueue(repeatedObject);
if (positionOffscreen)
PositionObject(repeatedObject, IntPoint.MaxValue);
}
void PositionObject(RepeatedObject obj, IntPoint index)
{
obj.GridPos = index;
obj.Transform.position = VectorHVD(
_objStartPosition.x + index.X * ObjectSize.x,
_objStartPosition.y + index.Y * ObjectSize.y,
_objStartPosition.z);
}
void Refresh()
{
// Free out of range objects
FreeOutOfRangeObjects(IntPoint.MaxValue, IntPoint.MaxValue);
// Fill the grid
FillGrid(_prevStartIndex, _prevEndIndex);
}
#if UNITY_EDITOR
void OnDrawGizmosSelected()
{
if (Application.isPlaying)
return;
// Don't draw gizmos on other cameras
if (Camera.current != CameraToUse &&
((UnityEditor.SceneView.lastActiveSceneView != null && Camera.current != UnityEditor.SceneView.lastActiveSceneView.camera) ||
(UnityEditor.SceneView.lastActiveSceneView == null)))
return;
Gizmos.color = Color.red;
// Draw object size and origin
if (ObjectToRepeat != null && ObjectOnStage)
{
var origin = ObjectToRepeat.position + VectorHV(ObjectBottomLeft.x, ObjectBottomLeft.y);
if (_repeatHorizontal)
{
Gizmos.DrawLine(origin, origin + VectorHV(ObjectSize.x, 0));
Utils.DrawArrowForGizmo(origin + VectorHV(ObjectSize.x - ObjectSize.x * .25f, 0), ObjectToRepeat.right * ObjectSize.x * .25f, ObjectSize.x * .25f);
}
if (_repeatVertical)
{
Gizmos.DrawLine(origin, origin + VectorHV(0, ObjectSize.y));
Utils.DrawArrowForGizmo(origin + VectorHV(0, ObjectSize.y - ObjectSize.y * .25f), ObjectToRepeat.up * ObjectSize.y * .25f, ObjectSize.y * .25f);
}
}
}
#endif
}
struct IntPoint: IEquatable<IntPoint>
{
public static IntPoint MaxValue = new IntPoint
{
X = int.MaxValue,
Y = int.MaxValue
};
public int X;
public int Y;
public IntPoint(int x, int y)
{
X = x;
Y = y;
}
public bool IsEqual(IntPoint other)
{
return other.X == X && other.Y == Y;
}
public override string ToString()
{
return string.Format("X: " + X + " - Y: " + Y);
}
#region IEquatable implementation
public bool Equals(IntPoint other)
{
return other.X == X && other.Y == Y;
}
#endregion
public override int GetHashCode()
{
var result = 0;
result = (result * 397) ^ X;
result = (result * 397) ^ Y;
return result;
}
}
class RepeatedObject
{
public IntPoint GridPos;
public Transform Transform;
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 62bcf12df35894d6eb0b4501842b9249
timeCreated: 1455023231
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,548 @@
using UnityEngine;
using System.Collections.Generic;
using System.Collections;
using UnityEngine.Events;
namespace Com.LuisPedroFonseca.ProCamera2D
{
[System.Serializable]
public class Room
{
public string ID = "";
public Rect Dimensions;
[Range(0f, 10f)]
public float TransitionDuration;
public EaseType TransitionEaseType;
public bool ScaleCameraToFit;
public bool Zoom;
[Range(0.1f, 10f)]
public float ZoomScale;
public int InternalID;
public Room(Room otherRoom)
{
Dimensions = otherRoom.Dimensions;
TransitionDuration = otherRoom.TransitionDuration;
TransitionEaseType = otherRoom.TransitionEaseType;
ScaleCameraToFit = otherRoom.ScaleCameraToFit;
Zoom = otherRoom.Zoom;
ZoomScale = otherRoom.ZoomScale;
}
public Room()
{
}
}
[System.Serializable]
public class RoomEvent : UnityEvent<int, int>
{
}
[HelpURLAttribute("http://www.procamera2d.com/user-guide/extension-rooms/")]
public class ProCamera2DRooms : BasePC2D, IPositionOverrider, ISizeOverrider
{
public const string ExtensionName = "Rooms";
public int CurrentRoomIndex
{
get { return _currentRoomIndex; }
}
private int _currentRoomIndex = -1;
public int PreviousRoomIndex
{
get { return _previousRoomIndex; }
}
private int _previousRoomIndex = -1;
public Room CurrentRoom
{
get { return (_currentRoomIndex >= 0 && _currentRoomIndex < Rooms.Count) ? Rooms[_currentRoomIndex] : null; }
}
public float OriginalSize { get; private set; }
public List<Room> Rooms = new List<Room>();
public float UpdateInterval = .1f;
public bool UseTargetsMidPoint = true;
public Transform TriggerTarget;
public bool TransitionInstanlyOnStart = true;
public bool RestoreOnRoomExit;
public float RestoreDuration = 1f;
public EaseType RestoreEaseType = EaseType.EaseInOut;
public bool AutomaticRoomActivation = true;
public bool UseRelativePosition;
public RoomEvent OnStartedTransition = new RoomEvent();
public RoomEvent OnFinishedTransition = new RoomEvent();
public UnityEvent OnExitedAllRooms = new UnityEvent();
ProCamera2DNumericBoundaries _numericBoundaries;
NumericBoundariesSettings _defaultNumericBoundariesSettings;
bool _transitioning;
Vector3 _newPos;
float _newSize;
Coroutine _transitionRoutine;
private int _currentRoomID = -1;
override protected void Awake()
{
base.Awake();
_numericBoundaries = ProCamera2D.GetComponent<ProCamera2DNumericBoundaries>();
_defaultNumericBoundariesSettings = _numericBoundaries.Settings;
OriginalSize = ProCamera2D.ScreenSizeInWorldCoordinates.y / 2;
ProCamera2D.AddPositionOverrider(this);
ProCamera2D.AddSizeOverrider(this);
}
void Start()
{
var instanceID = GetInstanceID();
var count = 0;
foreach (var room in Rooms)
{
room.InternalID = instanceID + count;
count++;
}
StartCoroutine(TestRoomRoutine());
if (TransitionInstanlyOnStart)
{
var targetPos = ProCamera2D.TargetsMidPoint;
if (!UseTargetsMidPoint && TriggerTarget != null)
targetPos = TriggerTarget.position;
var startingRoom = ComputeCurrentRoom(targetPos);
if (startingRoom != -1)
EnterRoom(startingRoom, false);
}
}
protected override void OnDestroy()
{
base.OnDestroy();
if(ProCamera2D == null) return;
ProCamera2D.RemovePositionOverrider(this);
ProCamera2D.RemoveSizeOverrider(this);
}
#region IPositionOverrider implementation
public Vector3 OverridePosition(float deltaTime, Vector3 originalPosition)
{
if (!enabled)
return originalPosition;
return _transitioning ? _newPos : originalPosition;
}
public int POOrder { get { return _poOrder; } set { _poOrder = value; } }
int _poOrder = 1001;
#endregion
#region ISizeOverrider implementation
public float OverrideSize(float deltaTime, float originalSize)
{
if (!enabled)
return originalSize;
return _transitioning ? _newSize : originalSize;
}
public int SOOrder { get { return _soOrder; } set { _soOrder = value; } }
int _soOrder = 3001;
#endregion
/// <summary>
/// Manually test to see if the target(s) is inside a room
/// </summary>
public void TestRoom()
{
var targetPos = ProCamera2D.TargetsMidPoint;
if (!UseTargetsMidPoint && TriggerTarget != null)
targetPos = TriggerTarget.position;
var roomToEnter = ComputeCurrentRoom(targetPos);
if (roomToEnter != -1 && _currentRoomIndex != roomToEnter)
{
EnterRoom(roomToEnter);
}
if (roomToEnter == -1 && _currentRoomIndex != -1)
{
ExitRoom();
}
}
/// <summary>
/// Returns what room the target currently is. Useful for when you set the AutomaticRoomActivation to false
/// </summary>
/// <returns>The current room</returns>
/// <param name="targetPos">Target position</param>
public int ComputeCurrentRoom(Vector3 targetPos)
{
int roomToEnter = -1;
for (int i = 0; i < Rooms.Count; i++)
{
if (Utils.IsInsideRectangle(
Rooms[i].Dimensions.x + (UseRelativePosition ? _transform.position.x : 0),
Rooms[i].Dimensions.y + (UseRelativePosition ? _transform.position.y : 0),
Rooms[i].Dimensions.width,
Rooms[i].Dimensions.height,
Vector3H(targetPos),
Vector3V(targetPos)))
{
roomToEnter = i;
}
}
return roomToEnter;
}
/// <summary>
/// Enter a room. Only use when the AutomaticRoomActivation is set to false.
/// </summary>
/// <param name="roomIndex">The room number on the list</param>
/// <param name="useTransition">Use a camera movement transition</param>
/// <param name="forceEntrance">Forces the transition to the room (even if the current room is the same)</param>
public void EnterRoom(int roomIndex, bool useTransition = true, bool forceEntrance = false)
{
if (roomIndex < 0 || roomIndex > Rooms.Count - 1)
throw new System.Exception("Can't find room with index: " + roomIndex);
if (!forceEntrance && Rooms[roomIndex].InternalID == _currentRoomID)
return;
_previousRoomIndex = _currentRoomIndex;
_currentRoomIndex = roomIndex;
_currentRoomID = Rooms[roomIndex].InternalID;
if (OnStartedTransition != null)
OnStartedTransition.Invoke(roomIndex, _previousRoomIndex);
TransitionToRoom(Rooms[_currentRoomIndex], useTransition);
}
/// <summary>
/// Enter a room. Only use when the AutomaticRoomActivation is set to false.
/// </summary>
/// <param name="roomID">The room ID</param>
/// <param name="useTransition">Use a camera movement transition</param>
/// <param name="forceEntrance">Forces the transition to the room (even if the current room is the same)</param>
public void EnterRoom(string roomID, bool useTransition = true, bool forceEntrance = false)
{
var foundIndex = Rooms.FindIndex(room => room.ID == roomID);
if (foundIndex < 0)
throw new System.Exception("Can't find room with ID: " + roomID);
EnterRoom(foundIndex, useTransition, forceEntrance);
}
/// <summary>
/// Exit current room. Only use when the AutomaticRoomActivation is set to false.
/// </summary>
public void ExitRoom()
{
_currentRoomIndex = -1;
_currentRoomID = -1;
if (RestoreOnRoomExit)
{
if (OnStartedTransition != null)
OnStartedTransition.Invoke(_currentRoomIndex, _previousRoomIndex);
if (_transitionRoutine != null)
StopCoroutine(_transitionRoutine);
ProCamera2D.StopUpdateScreenSizeCoroutine();
_transitionRoutine = StartCoroutine(TransitionRoutine(_defaultNumericBoundariesSettings, OriginalSize, RestoreDuration, RestoreEaseType));
}
if (OnExitedAllRooms != null)
OnExitedAllRooms.Invoke();
}
/// <summary>
/// Add a new room
/// </summary>
/// <param name="roomX">Room horizontal position</param>
/// <param name="roomY">Room vertical position</param>
/// <param name="roomWidth">Room width</param>
/// <param name="roomHeight">Room height</param>
/// <param name="transitionDuration">Transition duration</param>
/// <param name="transitionEaseType">Transition ease type</param>
/// <param name="scaleToFit">If set to <c>true</c> the camera will scale to fit the room</param>
/// <param name="zoom">If set to <c>true</c> the camera will scale to the zoomScale</param>
/// <param name="zoomScale">Zoom scale</param>
public void AddRoom(
float roomX,
float roomY,
float roomWidth,
float roomHeight,
float transitionDuration = 1f,
EaseType transitionEaseType = EaseType.EaseInOut,
bool scaleToFit = false,
bool zoom = false,
float zoomScale = 1.5f,
string id = "")
{
var newRoom = new Room()
{
ID = id,
Dimensions = new Rect(roomX, roomY, roomWidth, roomHeight),
TransitionDuration = transitionDuration,
TransitionEaseType = transitionEaseType,
ScaleCameraToFit = scaleToFit,
Zoom = zoom,
ZoomScale = zoomScale,
InternalID = GetInstanceID() + Rooms.Count
};
Rooms.Add(newRoom);
}
/// <summary>
/// Removes a specific room from the list.
/// </summary>
/// <param name="roomName">Room name / ID</param>
public void RemoveRoom(string roomName)
{
var room = Rooms.Find((Room obj) => obj.ID == roomName);
if (room != null)
Rooms.Remove(room);
else
Debug.LogWarning(roomName + " not found in the Rooms list.");
}
/// <summary>
/// Sets the default numeric boundaries settings (i.e. The boundaries to use when not inside any room).
/// </summary>
/// <param name="settings">The numeric boundaries settings.
/// You can grab them from the NumericBoundaries extension, or manually create them</param>
public void SetDefaultNumericBoundariesSettings(NumericBoundariesSettings settings)
{
_defaultNumericBoundariesSettings = settings;
}
/// <summary>
/// Returns a room by its ID. From this you can get all the room properties such as dimensions, zoom, etc.
/// </summary>
/// <param name="roomID">The room ID</param>
public Room GetRoom(string roomID)
{
return Rooms.Find((Room obj) => obj.ID == roomID);
}
/// <summary>
/// Returns an appropriate camera size for the specified rect representing a room
/// </summary>
/// <param name="roomRect">The room rect</param>
public float GetCameraSizeForRoom(Rect roomRect)
{
var scaleFactorW = roomRect.width / ProCamera2D.ScreenSizeInWorldCoordinates.x;
var scaleFactorH = roomRect.height / ProCamera2D.ScreenSizeInWorldCoordinates.y;
if (scaleFactorW < scaleFactorH)
return roomRect.width / ProCamera2D.GameCamera.aspect / 2f;
else
return roomRect.height / 2f;
}
IEnumerator TestRoomRoutine()
{
yield return new WaitForEndOfFrame();
var waitForSeconds = new WaitForSeconds(UpdateInterval);
var waitForSecondsRealtime = new WaitForSecondsRealtime(UpdateInterval);
while (true)
{
if (AutomaticRoomActivation)
TestRoom();
if(ProCamera2D.IgnoreTimeScale)
yield return waitForSecondsRealtime;
else
yield return waitForSeconds;
}
}
void TransitionToRoom(Room room, bool useTransition = true)
{
// Stop any previous transition
if (_transitionRoutine != null)
StopCoroutine(_transitionRoutine);
ProCamera2D.StopUpdateScreenSizeCoroutine();
// Numeric boundaries
var numericBoundariesSettings = new NumericBoundariesSettings()
{
UseNumericBoundaries = true,
UseTopBoundary = true,
TopBoundary = (room.Dimensions.y + (UseRelativePosition ? _transform.position.y : 0)) + room.Dimensions.height / 2,
UseBottomBoundary = true,
BottomBoundary = (room.Dimensions.y + (UseRelativePosition ? _transform.position.y : 0)) - room.Dimensions.height / 2,
UseLeftBoundary = true,
LeftBoundary = (room.Dimensions.x + (UseRelativePosition ? _transform.position.x : 0)) - room.Dimensions.width / 2,
UseRightBoundary = true,
RightBoundary = (room.Dimensions.x + (UseRelativePosition ? _transform.position.x : 0)) + room.Dimensions.width / 2
};
// Size
var targetSize = ProCamera2D.ScreenSizeInWorldCoordinates.y / 2f;
var cameraSizeForRoom = GetCameraSizeForRoom(room.Dimensions);
if (room.ScaleCameraToFit)
{
targetSize = cameraSizeForRoom;
}
else if (room.Zoom && OriginalSize * room.ZoomScale <= cameraSizeForRoom)
{
targetSize = OriginalSize * room.ZoomScale;
}
else if (cameraSizeForRoom < targetSize)
{
targetSize = cameraSizeForRoom;
}
// Move camera "manually"
_transitionRoutine = StartCoroutine(TransitionRoutine(numericBoundariesSettings, targetSize, useTransition ? room.TransitionDuration : 0f, room.TransitionEaseType));
}
IEnumerator TransitionRoutine(NumericBoundariesSettings numericBoundariesSettings, float targetSize, float transitionDuration = 1f, EaseType transitionEaseType = EaseType.EaseOut)
{
_transitioning = true;
// Disable the current numeric boundaries
_numericBoundaries.UseNumericBoundaries = false;
// Size
var initialSize = ProCamera2D.ScreenSizeInWorldCoordinates.y / 2f;
//Position
var initialCamPosH = Vector3H(ProCamera2D.LocalPosition);
var initialCamPosV = Vector3V(ProCamera2D.LocalPosition);
// Transition
var t = 0f;
while (t <= 1.0f)
{
// Prevents a NaN error on some platforms
if (transitionDuration < float.Epsilon)
t = 1.1f;
else if (ProCamera2D.DeltaTime > float.Epsilon)
t += ProCamera2D.DeltaTime / transitionDuration;
// Size
_newSize = transitionDuration > 0 ? Utils.EaseFromTo(initialSize, targetSize, t, transitionEaseType) : targetSize;
// Position
var targetPosH = ProCamera2D.CameraTargetPositionSmoothed.x;
var targetPosV = ProCamera2D.CameraTargetPositionSmoothed.y;
LimitToNumericBoundaries(
ref targetPosH,
ref targetPosV,
targetSize * ProCamera2D.GameCamera.aspect,
targetSize,
numericBoundariesSettings);
var newPosH = Utils.EaseFromTo(initialCamPosH, targetPosH, t, transitionEaseType);
var newPosV = Utils.EaseFromTo(initialCamPosV, targetPosV, t, transitionEaseType);
_newPos = VectorHVD(newPosH, newPosV, 0);
if(transitionDuration > 0)
yield return ProCamera2D.GetYield();
}
if (transitionDuration == 0)
yield return ProCamera2D.GetYield();
if (ProCamera2D.UpdateType == UpdateType.FixedUpdate && ProCamera2D.IgnoreTimeScale)
yield return new WaitForFixedUpdate();
_transitioning = false;
_numericBoundaries.Settings = numericBoundariesSettings;
_transitionRoutine = null;
if (OnFinishedTransition != null)
OnFinishedTransition.Invoke(_currentRoomIndex, _previousRoomIndex);
_previousRoomIndex = _currentRoomIndex;
}
void LimitToNumericBoundaries(
ref float horizontalPos,
ref float verticalPos,
float halfCameraWidth,
float halfCameraHeight,
NumericBoundariesSettings numericBoundaries)
{
if (numericBoundaries.UseLeftBoundary && horizontalPos - halfCameraWidth < numericBoundaries.LeftBoundary)
horizontalPos = numericBoundaries.LeftBoundary + halfCameraWidth;
else if (numericBoundaries.UseRightBoundary && horizontalPos + halfCameraWidth > numericBoundaries.RightBoundary)
horizontalPos = numericBoundaries.RightBoundary - halfCameraWidth;
if (numericBoundaries.UseBottomBoundary && verticalPos - halfCameraHeight < numericBoundaries.BottomBoundary)
verticalPos = numericBoundaries.BottomBoundary + halfCameraHeight;
else if (numericBoundaries.UseTopBoundary && verticalPos + halfCameraHeight > numericBoundaries.TopBoundary)
verticalPos = numericBoundaries.TopBoundary - halfCameraHeight;
}
#if UNITY_EDITOR
override protected void DrawGizmos()
{
base.DrawGizmos();
UnityEditor.Handles.color = EditorPrefsX.GetColor(PrefsData.RoomsColorKey, PrefsData.RoomsColorValue);
for (int i = 0; i < Rooms.Count; i++)
{
// Room border
var rect = Rooms[i].Dimensions;
rect.x -= rect.width / 2f - (UseRelativePosition ? transform.position.x : 0);
rect.y -= rect.height / 2f - (UseRelativePosition ? transform.position.y : 0);
Vector3[] rectangleCorners =
{
VectorHVD(rect.position.x, rect.position.y, 0), // Bottom Left
VectorHVD(rect.position.x + rect.width, rect.position.y, 0), // Bottom Right
VectorHVD(rect.position.x + rect.width, rect.position.y + rect.height, 0), // Top Right
VectorHVD(rect.position.x, rect.position.y + rect.height, 0) // Top Left
};
UnityEditor.Handles.DrawSolidRectangleWithOutline(rectangleCorners, Color.clear, Color.white);
}
}
#endif
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 30112d3b8decd43b5bf051e67694b027
timeCreated: 1447857655
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,550 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
namespace Com.LuisPedroFonseca.ProCamera2D
{
[HelpURLAttribute("http://www.procamera2d.com/user-guide/extension-shake/")]
public class ProCamera2DShake : BasePC2D
{
public static string ExtensionName = "Shake";
static ProCamera2DShake _instance;
public static ProCamera2DShake Instance
{
get
{
if (Equals(_instance, null))
{
_instance = FindObjectOfType(typeof(ProCamera2DShake)) as ProCamera2DShake;
if (Equals(_instance, null))
throw new UnityException("ProCamera2D does not have a Shake extension.");
}
return _instance;
}
}
/// <summary>Property to know if there's a ProCamera2DShake present</summary>
public static bool Exists { get { return _instance != null; } }
public System.Action OnShakeCompleted;
public List<ShakePreset> ShakePresets = new List<ShakePreset>();
public List<ConstantShakePreset> ConstantShakePresets = new List<ConstantShakePreset>();
public ConstantShakePreset StartConstantShakePreset;
/// <summary>Used internally by the editor</summary>
public ConstantShakePreset CurrentConstantShakePreset;
Transform _shakeParent;
List<Coroutine> _applyInfluencesCoroutines = new List<Coroutine>();
List<Coroutine> _shakeTimedCoroutines = new List<Coroutine>();
Coroutine _shakeCoroutine;
Vector3 _shakeVelocity;
List<Vector3> _shakePositions = new List<Vector3>();
Quaternion _rotationTarget;
Quaternion _originalRotation;
float _rotationTime;
float _rotationVelocity;
List<Vector3> _influences = new List<Vector3>();
Vector3 _influencesSum = Vector3.zero;
Vector3[] _constantShakePositions;
Vector3 _constantShakePosition;
bool _isConstantShaking;
override protected void Awake()
{
base.Awake();
_instance = this;
if (ProCamera2D.transform.parent != null)
{
_shakeParent = new GameObject("ProCamera2DShakeContainer").transform;
_shakeParent.SetParent(ProCamera2D.transform.parent);
_shakeParent.localPosition = Vector3.zero;
ProCamera2D.transform.SetParent(_shakeParent);
}
else
{
var parent = new GameObject("ProCamera2DShakeContainer").transform;
ProCamera2D.transform.SetParent(parent);
_shakeParent = parent;
}
_originalRotation = _transform.localRotation;
}
void Start()
{
if (StartConstantShakePreset != null)
ConstantShake(StartConstantShakePreset);
}
void Update()
{
_influencesSum = Vector3.zero;
if (_influences.Count > 0)
{
_influencesSum = Utils.GetVectorsSum(_influences);
_influences.Clear();
_shakeParent.localPosition = _influencesSum;
}
}
/// <summary>Shakes the camera with the given values.</summary>
/// <param name="duration">The duration of the shake</param>
/// <param name="strength">The shake strength on each axis</param>
/// <param name="vibrato">Indicates how much will the shake vibrate</param>
/// <param name="randomness">Indicates how much random the shake will be</param>
/// <param name="initialAngle">The initial angle of the shake. Use -1 if you want it to be random.</param>
/// <param name="rotation">The maximum rotation the camera can reach during shake</param>
/// <param name="smoothness">How smooth the shake should be, 0 being instant</param>
/// <param name="ignoreTimeScale">If true, the shake will occur even if the timeScale is 0</param>
public void Shake(
float duration,
Vector2 strength,
int vibrato = 10,
float randomness = .1f,
float initialAngle = -1f,
Vector3 rotation = default(Vector3),
float smoothness = .1f,
bool ignoreTimeScale = false)
{
if (!enabled)
return;
vibrato++;
if (vibrato < 2)
vibrato = 2;
// Calculate steps durations
float[] durations = new float[vibrato];
float sum = 0;
for (int i = 0; i < vibrato; ++i)
{
float iterationPerc = (i + 1) / (float)vibrato;
float tDuration = duration * iterationPerc;
sum += tDuration;
durations[i] = tDuration;
}
float tDurationMultiplier = duration / sum;
for (int i = 0; i < vibrato; ++i)
durations[i] = durations[i] * tDurationMultiplier;
float shakeMagnitude = strength.magnitude;
float magnitudeDecay = shakeMagnitude / vibrato;
float ang = initialAngle != -1f ? initialAngle : Random.Range(0f, 360f);
var positions = new Vector2[vibrato];
positions[vibrato - 1] = Vector2.zero;
var rotations = new Quaternion[vibrato];
rotations[vibrato - 1] = _originalRotation;
var rotationQtn = Quaternion.Euler(rotation);
for (int i = 0; i < vibrato - 1; ++i)
{
// Position
if (i > 0)
ang = ang - 180 + Random.Range(-90, 90) * randomness;
Quaternion rndQuaternion = Quaternion.AngleAxis(Random.Range(-90, 90) * randomness, Vector3.up);
float radians = ang * Mathf.Deg2Rad;
var dir = new Vector3(shakeMagnitude * Mathf.Cos(radians), shakeMagnitude * Mathf.Sin(radians), 0);
Vector2 position = rndQuaternion * dir;
position.x = Vector2.ClampMagnitude(position, strength.x).x;
position.y = Vector2.ClampMagnitude(position, strength.y).y;
positions[i] = position;
shakeMagnitude -= magnitudeDecay;
strength = Vector2.ClampMagnitude(strength, shakeMagnitude);
// Rotation
var sign = i % 2 == 0 ? 1 : -1;
var percent = (float)i / (vibrato - 1);
rotations[i] = sign == 1 ? Quaternion.Lerp(rotationQtn, Quaternion.identity, percent) * _originalRotation : Quaternion.Inverse(Quaternion.Lerp(rotationQtn, Quaternion.identity, percent)) * _originalRotation;
}
_applyInfluencesCoroutines.Add(ApplyShakesTimed(positions, rotations, durations, smoothness, ignoreTimeScale));
}
/// <summary>Shakes the camera using the values defined on the provided preset</summary>
/// <param name="presetIndex">The index of the preset</param>
public void Shake(int presetIndex)
{
if (presetIndex <= ShakePresets.Count - 1)
{
Shake(
ShakePresets[presetIndex].Duration,
ShakePresets[presetIndex].Strength,
ShakePresets[presetIndex].Vibrato,
ShakePresets[presetIndex].Randomness,
ShakePresets[presetIndex].UseRandomInitialAngle ? -1 : ShakePresets[presetIndex].InitialAngle,
ShakePresets[presetIndex].Rotation,
ShakePresets[presetIndex].Smoothness,
ShakePresets[presetIndex].IgnoreTimeScale);
}
else
{
Debug.LogWarning("Could not find a shake preset with the index: " + presetIndex);
}
}
/// <summary>Shakes the camera using the values defined on the provided preset</summary>
/// <param name="presetName">The name of the preset</param>
public void Shake(string presetName)
{
for (int i = 0; i < ShakePresets.Count; i++)
{
if (ShakePresets[i].name == presetName)
{
Shake(i);
return;
}
}
Debug.LogWarning("Could not find a shake preset with the name: " + presetName);
}
/// <summary>Shakes the camera using the values defined on the provided preset</summary>
/// <param name="preset">The shake preset</param>
public void Shake(ShakePreset preset)
{
Shake(preset.Duration,
preset.Strength,
preset.Vibrato,
preset.Randomness,
preset.UseRandomInitialAngle ? -1 : preset.InitialAngle,
preset.Rotation,
preset.Smoothness,
preset.IgnoreTimeScale);
}
/// <summary>Stops all current shakes</summary>
public void StopShaking()
{
for (int i = 0; i < _applyInfluencesCoroutines.Count; i++)
{
StopCoroutine(_applyInfluencesCoroutines[i]);
}
for (int i = 0; i < _shakeTimedCoroutines.Count; i++)
{
StopCoroutine(_shakeTimedCoroutines[i]);
}
if (_shakeCoroutine != null)
{
StopCoroutine(_shakeCoroutine);
_shakeCoroutine = null;
}
_shakePositions.Clear();
_shakeVelocity = Vector3.zero;
ShakeCompleted();
}
/// <summary>
/// Constantly shakes the camera until it's explicitly told to stop
/// </summary>
/// <param name="preset">The preset that contains all the constant shake parameters</param>
public void ConstantShake(ConstantShakePreset preset)
{
if (CurrentConstantShakePreset != null)
StopConstantShaking(0);
CurrentConstantShakePreset = preset;
_isConstantShaking = true;
_constantShakePositions = new Vector3[preset.Layers.Count];
for (int i = 0; i < preset.Layers.Count; i++)
{
StartCoroutine(CalculateConstantShakePosition(
i,
preset.Layers[i].Frequency.x,
preset.Layers[i].Frequency.y,
preset.Layers[i].AmplitudeHorizontal,
preset.Layers[i].AmplitudeVertical,
preset.Layers[i].AmplitudeDepth));
}
StartCoroutine(ConstantShakeRoutine(preset.Intensity));
}
/// <summary>
/// Constantly shakes the camera until it's explicitly told to stop
/// </summary>
/// <param name="presetName">The name of the preset. It must be part of the ConstantShakePresets list.</param>
public void ConstantShake(string presetName)
{
for (int i = 0; i < ConstantShakePresets.Count; i++)
{
if (ConstantShakePresets[i].name == presetName)
{
ConstantShake(ConstantShakePresets[i]);
return;
}
}
Debug.LogWarning("Could not find a ConstantShakePreset with the name: " + presetName + ". Remember you need to add it to the ConstantShakePresets list first.");
}
/// <summary>
/// Constantly shakes the camera until it's explicitly told to stop
/// </summary>
/// <param name="presetIndex">The index of the preset. It must be part of the ConstantShakePresets list.</param>
public void ConstantShake(int presetIndex)
{
if (presetIndex <= ConstantShakePresets.Count - 1)
{
ConstantShake(ConstantShakePresets[presetIndex]);
}
else
{
Debug.LogWarning("Could not find a ConstantShakePreset with the index: " + presetIndex + ". Remember you need to add it to the ConstantShakePresets list first.");
}
}
/// <summary>
/// Stops constant shakes
/// </summary>
/// <param name="duration">How long it takes to stop the constant shake</param>
public void StopConstantShaking(float duration = .3f)
{
CurrentConstantShakePreset = null;
_isConstantShaking = false;
if (duration > 0f)
StartCoroutine(StopConstantShakeRoutine(duration));
else
{
StopAllCoroutines();
_constantShakePosition = Vector3.zero;
_influences.Clear();
_influences.Add(_constantShakePosition);
}
}
/// <summary>Apply the given influences to the camera during the corresponding durations.</summary>
/// <param name="shakes">An array of the vectors representing the shakes to be applied</param>
/// <param name="rotations">An array of the rotations to be applied</param>
/// <param name="durations">An array with the durations of the influences to be applied</param>
/// <param name="smoothness">How smooth the shake should be, 0 being instant</param>
/// <param name="ignoreTimeScale">If true, the shake will occur even if the timeScale is 0</param>
public Coroutine ApplyShakesTimed(
Vector2[] shakes,
Vector3[] rotations,
float[] durations,
float smoothness = .1f,
bool ignoreTimeScale = false)
{
if (!enabled)
return null;
var rotationsQtn = new Quaternion[rotations.Length];
for (int i = 0; i < rotations.Length; i++)
rotationsQtn[i] = Quaternion.Euler(rotations[i]) * _originalRotation;
return ApplyShakesTimed(shakes, rotationsQtn, durations);
}
/// <summary>Apply the given influence to the camera during this frame, while ignoring all camera boundaries</summary>
/// <param name="influence">The vector representing the influence to be applied</param>
public void ApplyInfluenceIgnoringBoundaries(Vector2 influence)
{
if (Time.deltaTime < .0001f || float.IsNaN(influence.x) || float.IsNaN(influence.y))
return;
_influences.Add(VectorHV(influence.x, influence.y));
}
Coroutine ApplyShakesTimed(
Vector2[] shakes,
Quaternion[] rotations,
float[] durations,
float smoothness = .1f,
bool ignoreTimeScale = false)
{
var coroutine = StartCoroutine(ApplyShakesTimedRoutine(shakes, rotations, durations, ignoreTimeScale));
if (_shakeCoroutine == null)
_shakeCoroutine = StartCoroutine(ShakeRoutine(smoothness, ignoreTimeScale));
return coroutine;
}
IEnumerator ShakeRoutine(float smoothness, bool ignoreTimeScale = false)
{
while (_shakePositions.Count > 0 ||
Vector3.Distance(_shakeParent.localPosition, _influencesSum) > .01f ||
Quaternion.Angle(_transform.localRotation, _originalRotation) > .01f)
{
var newShakePosition = Utils.GetVectorsSum(_shakePositions) + _influencesSum;
var newShakePositionSmoothed = Vector3.zero;
if (ignoreTimeScale)
newShakePositionSmoothed = Vector3.SmoothDamp(_shakeParent.localPosition, newShakePosition, ref _shakeVelocity, smoothness, float.MaxValue, Time.unscaledDeltaTime);
else if (ProCamera2D.DeltaTime > 0f)
newShakePositionSmoothed = Vector3.SmoothDamp(_shakeParent.localPosition, newShakePosition, ref _shakeVelocity, smoothness);
_shakeParent.localPosition = newShakePositionSmoothed;
_shakePositions.Clear();
if (ignoreTimeScale)
_rotationTime = Mathf.SmoothDamp(_rotationTime, 1f, ref _rotationVelocity, smoothness, float.MaxValue, ProCamera2D.UpdateType == UpdateType.LateUpdate ? Time.unscaledDeltaTime : Time.fixedUnscaledDeltaTime);
else if (ProCamera2D.DeltaTime > 0)
_rotationTime = Mathf.SmoothDamp(_rotationTime, 1f, ref _rotationVelocity, smoothness, float.MaxValue, ProCamera2D.DeltaTime);
var rotationTargetSmoothed = Quaternion.Slerp(_transform.localRotation, _rotationTarget, _rotationTime);
_transform.localRotation = rotationTargetSmoothed;
_rotationTarget = _originalRotation;
yield return ProCamera2D.GetYield();
}
ShakeCompleted();
}
void ShakeCompleted()
{
_shakeParent.localPosition = _influencesSum;
_transform.localRotation = _originalRotation;
_shakeCoroutine = null;
if (OnShakeCompleted != null)
OnShakeCompleted();
}
IEnumerator ApplyShakesTimedRoutine(IList<Vector2> shakes, IList<Quaternion> rotations, float[] durations, bool ignoreTimeScale = false)
{
_shakeTimedCoroutines = new List<Coroutine>();
var count = -1;
while (count < durations.Length - 1)
{
count++;
var duration = durations[count];
var coroutine = StartCoroutine(ApplyShakeTimedRoutine(shakes[count], rotations[count], duration, ignoreTimeScale));
_shakeTimedCoroutines.Add(coroutine);
yield return coroutine;
}
}
IEnumerator ApplyShakeTimedRoutine(Vector2 shake, Quaternion rotation, float duration, bool ignoreTimeScale = false)
{
_rotationTime = 0;
_rotationVelocity = 0;
while (duration > 0)
{
if (ignoreTimeScale)
{
if(ProCamera2D.UpdateType == UpdateType.LateUpdate)
duration -= Time.unscaledDeltaTime;
else if(ProCamera2D.UpdateType == UpdateType.FixedUpdate)
duration -= Time.fixedUnscaledDeltaTime;
}
else
duration -= ProCamera2D.DeltaTime;
_shakePositions.Add(VectorHV(shake.x, shake.y));
_rotationTarget = rotation;
yield return ProCamera2D.GetYield();
}
}
IEnumerator StopConstantShakeRoutine(float duration)
{
var velocity = Vector3.zero;
_influences.Clear();
while (duration >= 0)
{
duration -= ProCamera2D.DeltaTime;
_constantShakePosition = Vector3.SmoothDamp(_constantShakePosition, Vector3.zero, ref velocity, duration, float.MaxValue);
_influences.Add(_constantShakePosition);
yield return ProCamera2D.GetYield();
}
}
IEnumerator CalculateConstantShakePosition(int index, float frequencyMin, float frequencyMax, float amplitudeX, float amplitudeY, float amplitudeZ)
{
while (_isConstantShaking)
{
var randomFrequency = Random.Range(frequencyMin, frequencyMax);
var unitSphere = Random.insideUnitSphere;
var randomAmplitudeX = unitSphere.x * amplitudeX;
var randomAmplitudeY = unitSphere.y * amplitudeY;
var randomAmplitudeZ = unitSphere.z * amplitudeZ;
if(index < _constantShakePositions.Length)
_constantShakePositions[index] = VectorHVD(randomAmplitudeX, randomAmplitudeY, randomAmplitudeZ);
//Debug.DrawLine(transform.localPosition, transform.localPosition + VectorHVD(randomAmplitudeX, randomAmplitudeY, randomAmplitudeZ), Color.green, randomFrequency);
if(ProCamera2D.IgnoreTimeScale)
yield return new WaitForSecondsRealtime(randomFrequency);
else
yield return new WaitForSeconds(randomFrequency);
}
}
IEnumerator ConstantShakeRoutine(float intensity)
{
while (_isConstantShaking)
{
if (ProCamera2D.DeltaTime > 0)
{
var result = Utils.GetVectorsSum(_constantShakePositions) / _constantShakePositions.Length;
_constantShakePosition.Set(Utils.SmoothApproach(_constantShakePosition.x, result.x, result.x, intensity, ProCamera2D.DeltaTime),
Utils.SmoothApproach(_constantShakePosition.y, result.y, result.y, intensity, ProCamera2D.DeltaTime),
Utils.SmoothApproach(_constantShakePosition.z, result.z, result.z, intensity, ProCamera2D.DeltaTime));
_influences.Add(_constantShakePosition);
}
yield return ProCamera2D.GetYield();
}
}
#if UNITY_EDITOR
override protected void DrawGizmos()
{
base.DrawGizmos();
var cameraDimensions = Utils.GetScreenSizeInWorldCoords(ProCamera2D.GameCamera, Mathf.Abs(Vector3D(transform.localPosition)));
if (Application.isPlaying && _shakeParent.localPosition != Vector3.zero)
{
Gizmos.color = EditorPrefsX.GetColor(PrefsData.ShakeInfluenceColorKey, PrefsData.ShakeInfluenceColorValue);
Utils.DrawArrowForGizmo(ProCamera2D.TargetsMidPoint, _shakeParent.localPosition, .04f * cameraDimensions.y);
}
}
#endif
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 9ac0ec3d6ad5f4a3d9d184bc3773a3a7
timeCreated: 1432596595
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,127 @@
using UnityEngine;
namespace Com.LuisPedroFonseca.ProCamera2D
{
[HelpURLAttribute("http://www.procamera2d.com/user-guide/extension-speed-based-zoom/")]
public class ProCamera2DSpeedBasedZoom : BasePC2D, ISizeDeltaChanger
{
public static string ExtensionName = "Speed Based Zoom";
[Tooltip("The speed at which the camera will reach it's max zoom out.")]
public float CamVelocityForZoomOut = 5f;
[Tooltip("Below this speed the camera zooms in. Above this speed the camera will start zooming out.")]
public float CamVelocityForZoomIn = 2f;
[Tooltip("Represents how smooth the zoom in of the camera should be. The lower the number the quickest the zoom is.")]
[Range(0f, 3f)]
public float ZoomInSmoothness = 1f;
[Tooltip("Represents how smooth the zoom out of the camera should be. The lower the number the quickest the zoom is.")]
[Range(0f, 3f)]
public float ZoomOutSmoothness = 1f;
[Tooltip("Represents the maximum amount the camera should zoom in when the camera speed is below SpeedForZoomIn")]
public float MaxZoomInAmount = 2f;
[Tooltip("Represents the maximum amount the camera should zoom out when the camera speed is equal to SpeedForZoomOut")]
public float MaxZoomOutAmount = 2f;
float _zoomVelocity;
float _initialCamSize;
float _previousCamSize;
Vector3 _previousCameraPosition;
[HideInInspector]
public float CurrentVelocity;
override protected void Awake()
{
base.Awake();
if (ProCamera2D == null)
return;
_initialCamSize = ProCamera2D.ScreenSizeInWorldCoordinates.y * .5f;
_previousCamSize = _initialCamSize;
_previousCameraPosition = VectorHV(Vector3H(ProCamera2D.LocalPosition), Vector3V(ProCamera2D.LocalPosition));
ProCamera2D.AddSizeDeltaChanger(this);
}
protected override void OnDestroy()
{
base.OnDestroy();
if(ProCamera2D)
ProCamera2D.RemoveSizeDeltaChanger(this);
}
#region ISizeDeltaChanger implementation
public float AdjustSize(float deltaTime, float originalDelta)
{
if (!enabled)
return originalDelta;
// If the camera is bounded, reset the easing
if (_previousCamSize == ProCamera2D.ScreenSizeInWorldCoordinates.y)
{
_zoomVelocity = 0f;
}
// Get camera velocity
CurrentVelocity = (_previousCameraPosition - VectorHV(Vector3H(ProCamera2D.LocalPosition), Vector3V(ProCamera2D.LocalPosition))).magnitude / deltaTime;
_previousCameraPosition = VectorHV(Vector3H(ProCamera2D.LocalPosition), Vector3V(ProCamera2D.LocalPosition));
var currentSize = ProCamera2D.ScreenSizeInWorldCoordinates.y * 0.5f;
var targetSize = currentSize;
// Zoom out
if (CurrentVelocity > CamVelocityForZoomIn)
{
var speedPercentage = (CurrentVelocity - CamVelocityForZoomIn) / (CamVelocityForZoomOut - CamVelocityForZoomIn);
var newSize = _initialCamSize * (1 + MaxZoomOutAmount - 1) * Mathf.Clamp01(speedPercentage);
if (newSize > currentSize)
targetSize = newSize;
}
// Zoom in
else
{
var speedPercentage = (1 - (CurrentVelocity / CamVelocityForZoomIn)).Remap(0.0f, 1.0f, 0.5f, 1.0f);
var newSize = _initialCamSize / (MaxZoomInAmount * speedPercentage);
if (newSize < currentSize)
targetSize = newSize;
}
if (Mathf.Abs(currentSize - targetSize) > .0001f)
{
float smoothness = (targetSize < currentSize) ? ZoomInSmoothness : ZoomOutSmoothness;
targetSize = Mathf.SmoothDamp(currentSize, targetSize, ref _zoomVelocity, smoothness, Mathf.Infinity, deltaTime);
}
var zoomAmount = targetSize - (ProCamera2D.ScreenSizeInWorldCoordinates.y / 2);
// Detect if the camera size is bounded
_previousCamSize = ProCamera2D.ScreenSizeInWorldCoordinates.y;
// Return the zoom delta - delta already factored in by SmoothDamp
return originalDelta + zoomAmount;
}
public int SDCOrder { get { return _sdcOrder; } set { _sdcOrder = value; } }
int _sdcOrder = 1000;
#endregion
override public void OnReset()
{
_previousCamSize = _initialCamSize;
_previousCameraPosition = VectorHV(Vector3H(ProCamera2D.LocalPosition), Vector3V(ProCamera2D.LocalPosition));
_zoomVelocity = 0;
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 852aabd699fd842b392ca48e4955f079
timeCreated: 1448053454
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,310 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
namespace Com.LuisPedroFonseca.ProCamera2D
{
public enum TransitionsFXShaders
{
Fade,
Circle,
Shutters,
Wipe,
Blinds,
Texture
}
public enum TransitionFXSide
{
Left = 0,
Right = 1,
Up = 2,
Down = 3
}
public enum TransitionFXDirection
{
Horizontal = 0,
Vertical = 1
}
[HelpURLAttribute("http://www.procamera2d.com/user-guide/extension-transitions-fx/")]
public class ProCamera2DTransitionsFX : BasePC2D
{
public static string ExtensionName = "TransitionsFX";
/// <summary>Fires whenever a TransitionEnter starts</summary>
public Action OnTransitionEnterStarted;
/// <summary>Fires whenever a TransitionEnter ends</summary>
public Action OnTransitionEnterEnded;
/// <summary>Fires whenever a TransitionExit starts</summary>
public Action OnTransitionExitStarted;
/// <summary>Fires whenever a TransitionExit ends</summary>
public Action OnTransitionExitEnded;
/// <summary>Fires whenever a TransitionEnter or a TransitionExit starts</summary>
public Action OnTransitionStarted;
/// <summary>Fires whenever a TransitionEnter or a TransitionExit ends</summary>
public Action OnTransitionEnded;
static ProCamera2DTransitionsFX _instance;
public static ProCamera2DTransitionsFX Instance
{
get
{
if (Equals(_instance, null))
{
_instance = ProCamera2D.Instance.GetComponent<ProCamera2DTransitionsFX>();
if (Equals(_instance, null))
throw new UnityException("ProCamera2D does not have a TransitionFX extension.");
}
return _instance;
}
}
public TransitionsFXShaders TransitionShaderEnter = TransitionsFXShaders.Fade;
public float DurationEnter = .5f;
public float DelayEnter = 0f;
public EaseType EaseTypeEnter = EaseType.EaseOut;
public Color BackgroundColorEnter = Color.black;
public TransitionFXSide SideEnter = TransitionFXSide.Left;
public TransitionFXDirection DirectionEnter = TransitionFXDirection.Horizontal;
[Range(2, 128)]
public int BlindsEnter = 16;
public Texture TextureEnter;
[Range(0, 1)]
public float TextureSmoothingEnter = .2f;
public TransitionsFXShaders TransitionShaderExit = TransitionsFXShaders.Fade;
public float DurationExit = .5f;
public float DelayExit = 0f;
public EaseType EaseTypeExit = EaseType.EaseOut;
public Color BackgroundColorExit = Color.black;
public TransitionFXSide SideExit = TransitionFXSide.Left;
public TransitionFXDirection DirectionExit = TransitionFXDirection.Horizontal;
[Range(2, 128)]
public int BlindsExit = 16;
public Texture TextureExit;
[Range(0, 1)]
public float TextureSmoothingExit = .2f;
public bool StartSceneOnEnterState = true;
Coroutine _transitionCoroutine;
float _step;
Material _transitionEnterMaterial;
Material _transitionExitMaterial;
BasicBlit _blit;
int _material_StepID;
int _material_BackgroundColorID;
string _previousEnterShader = "";
string _previousExitShader = "";
protected override void Awake()
{
base.Awake();
_instance = this;
_material_StepID = Shader.PropertyToID("_Step");
_material_BackgroundColorID = Shader.PropertyToID("_BackgroundColor");
_blit = gameObject.AddComponent<BasicBlit>();
_blit.enabled = false;
UpdateTransitionsShaders();
UpdateTransitionsProperties();
UpdateTransitionsColor();
if (StartSceneOnEnterState)
{
_step = 1f;
_blit.CurrentMaterial = _transitionEnterMaterial;
_blit.CurrentMaterial.SetFloat(_material_StepID, _step);
_blit.enabled = true;
}
}
/// <summary>
/// Transition enter
/// </summary>
public void TransitionEnter()
{
Transition(_transitionEnterMaterial, DurationEnter, DelayEnter, 1f, 0f, EaseTypeEnter);
}
/// <summary>
/// Transition exit
/// </summary>
public void TransitionExit()
{
Transition(_transitionExitMaterial, DurationExit, DelayExit, 0f, 1f, EaseTypeExit);
}
/// <summary>
/// Updates the transitions shaders.
/// Use only if you change the selected Enter/Exit shaders during runtime.
/// </summary>
public void UpdateTransitionsShaders()
{
string shaderEnter = TransitionShaderEnter.ToString();
if (!_previousEnterShader.Equals(shaderEnter))
{
_transitionEnterMaterial = new Material(Shader.Find("Hidden/ProCamera2D/TransitionsFX/" + shaderEnter));
_previousEnterShader = shaderEnter;
}
string shaderExit = TransitionShaderExit.ToString();
if (!_previousExitShader.Equals(shaderExit))
{
_transitionExitMaterial = new Material(Shader.Find("Hidden/ProCamera2D/TransitionsFX/" + shaderExit));
_previousExitShader = shaderExit;
}
}
/// <summary>
/// Updates the transitions properties.
/// Use only if you changed the following properties during runtime: Direction, Side, Blinds, Texture, Texture Smoothing.
/// For updating the background color, use the method UpdateTransitionsColor
/// </summary>
public void UpdateTransitionsProperties()
{
// Enter
if (TransitionShaderEnter == TransitionsFXShaders.Wipe || TransitionShaderEnter == TransitionsFXShaders.Blinds)
{
_transitionEnterMaterial.SetInt("_Direction", (int)SideEnter);
_transitionEnterMaterial.SetInt("_Blinds", BlindsEnter);
}
else if (TransitionShaderEnter == TransitionsFXShaders.Shutters)
{
_transitionEnterMaterial.SetInt("_Direction", (int)DirectionEnter);
}
else if (TransitionShaderEnter == TransitionsFXShaders.Texture)
{
_transitionEnterMaterial.SetTexture("_TransitionTex", TextureEnter);
_transitionEnterMaterial.SetFloat("_Smoothing", TextureSmoothingEnter);
}
// Exit
if (TransitionShaderExit == TransitionsFXShaders.Wipe || TransitionShaderExit == TransitionsFXShaders.Blinds)
{
_transitionExitMaterial.SetInt("_Direction", (int)SideExit);
_transitionExitMaterial.SetInt("_Blinds", BlindsExit);
}
else if (TransitionShaderExit == TransitionsFXShaders.Shutters)
{
_transitionExitMaterial.SetInt("_Direction", (int)DirectionExit);
}
else if (TransitionShaderExit == TransitionsFXShaders.Texture)
{
_transitionExitMaterial.SetTexture("_TransitionTex", TextureExit);
_transitionExitMaterial.SetFloat("_Smoothing", TextureSmoothingExit);
}
}
/// <summary>
/// Updates the transitions color.
/// Use only if you changed the BackgroundColorEnter or BackgroundColorExit during runtime.
/// </summary>
public void UpdateTransitionsColor()
{
_transitionEnterMaterial.SetColor(_material_BackgroundColorID, BackgroundColorEnter);
_transitionExitMaterial.SetColor(_material_BackgroundColorID, BackgroundColorExit);
}
/// <summary>
/// Clears the current transition
/// </summary>
public void Clear()
{
_blit.enabled = false;
}
void Transition(Material material, float duration, float delay, float startValue, float endValue, EaseType easeType)
{
if (_transitionEnterMaterial == null)
{
Debug.LogWarning("TransitionsFX not initialized yet. You're probably calling TransitionEnter/Exit from an Awake method. Please call it from a Start method instead.");
return;
}
if (_transitionCoroutine != null)
StopCoroutine(_transitionCoroutine);
_transitionCoroutine = StartCoroutine(TransitionRoutine(material, duration, delay, startValue, endValue, easeType));
}
IEnumerator TransitionRoutine(Material material, float duration, float delay, float startValue, float endValue, EaseType easeType)
{
_blit.enabled = true;
_step = startValue;
_blit.CurrentMaterial = material;
_blit.CurrentMaterial.SetFloat(_material_StepID, _step);
if (endValue == 0)
{
if (OnTransitionEnterStarted != null)
OnTransitionEnterStarted();
}
else if (endValue == 1)
{
if (OnTransitionExitStarted != null)
OnTransitionExitStarted();
}
if (OnTransitionStarted != null)
OnTransitionStarted();
if (delay > 0)
{
if(ProCamera2D.IgnoreTimeScale)
yield return new WaitForSecondsRealtime(delay);
else
yield return new WaitForSeconds(delay);
}
var t = 0f;
while (t <= 1.0f)
{
t += ProCamera2D.DeltaTime / duration;
_step = Utils.EaseFromTo(startValue, endValue, t, easeType);
material.SetFloat(_material_StepID, _step);
yield return null;
}
_step = endValue;
material.SetFloat(_material_StepID, _step);
if (endValue == 0)
{
if (OnTransitionEnterEnded != null)
OnTransitionEnterEnded();
}
else if (endValue == 1)
{
if (OnTransitionExitEnded != null)
OnTransitionExitEnded();
}
if (OnTransitionEnded != null)
OnTransitionEnded();
if(endValue == 0)
_blit.enabled = false;
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: d1eca57db7d394266ae024997acf4456
timeCreated: 1456045262
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,200 @@
using System;
using UnityEngine;
namespace Com.LuisPedroFonseca.ProCamera2D
{
[HelpURLAttribute("http://www.procamera2d.com/user-guide/extension-zoom-to-fit/")]
public class ProCamera2DZoomToFitTargets : BasePC2D, ISizeOverrider
{
public static string ExtensionName = "Zoom To Fit";
public float ZoomOutBorder = .6f;
public float ZoomInBorder = .4f;
public float ZoomInSmoothness = 2f;
public float ZoomOutSmoothness = 1f;
public float MaxZoomInAmount = 2f;
public float MaxZoomOutAmount = 4f;
public bool DisableWhenOneTarget = true;
public bool CompensateForCameraPosition;
float _zoomVelocity;
float _previousCamSize;
float _targetCamSize;
float _targetCamSizeSmoothed;
float _minCameraSize;
float _maxCameraSize;
override protected void Awake()
{
base.Awake();
if (ProCamera2D == null)
return;
_targetCamSize = ProCamera2D.StartScreenSizeInWorldCoordinates.y * .5f;
_targetCamSizeSmoothed = _targetCamSize;
ProCamera2D.AddSizeOverrider(this);
}
protected override void OnDestroy()
{
base.OnDestroy();
if(ProCamera2D)
ProCamera2D.RemoveSizeOverrider(this);
}
#region ISizeOverrider implementation
public float OverrideSize(float deltaTime, float originalSize)
{
if (!enabled)
return originalSize;
_targetCamSizeSmoothed = ProCamera2D.ScreenSizeInWorldCoordinates.y * .5f;
if (DisableWhenOneTarget && ProCamera2D.CameraTargets.Count <= 1)
_targetCamSize = ProCamera2D.StartScreenSizeInWorldCoordinates.y * .5f;
else
{
if (_previousCamSize == ProCamera2D.ScreenSizeInWorldCoordinates.y)
{
_targetCamSize = ProCamera2D.ScreenSizeInWorldCoordinates.y * .5f;
_targetCamSizeSmoothed = _targetCamSize;
_zoomVelocity = 0f;
}
UpdateTargetCamSize();
}
_previousCamSize = ProCamera2D.ScreenSizeInWorldCoordinates.y;
return _targetCamSizeSmoothed = Mathf.SmoothDamp(_targetCamSizeSmoothed, _targetCamSize, ref _zoomVelocity, _targetCamSize < _targetCamSizeSmoothed ? ZoomInSmoothness : ZoomOutSmoothness, float.MaxValue, deltaTime);
}
public int SOOrder { get { return _soOrder; } set { _soOrder = value; } }
int _soOrder;
#endregion
override public void OnReset()
{
_zoomVelocity = 0;
_previousCamSize = ProCamera2D.StartScreenSizeInWorldCoordinates.y * .5f;
_targetCamSize = _previousCamSize;
_targetCamSizeSmoothed = _previousCamSize;
}
void UpdateTargetCamSize()
{
// Targets bounding box
float maxX = Mathf.NegativeInfinity;
float minX = Mathf.Infinity;
float maxY = Mathf.NegativeInfinity;
float minY = Mathf.Infinity;
for (int i = 0; i < ProCamera2D.CameraTargets.Count; i++)
{
var targetPos = new Vector2(Vector3H(ProCamera2D.CameraTargets[i].TargetPosition) + ProCamera2D.CameraTargets[i].TargetOffset.x, Vector3V(ProCamera2D.CameraTargets[i].TargetPosition) + ProCamera2D.CameraTargets[i].TargetOffset.y);
maxX = targetPos.x > maxX ? targetPos.x : maxX;
minX = targetPos.x < minX ? targetPos.x : minX;
maxY = targetPos.y > maxY ? targetPos.y : maxY;
minY = targetPos.y < minY ? targetPos.y : minY;
}
var distanceMaxX = Mathf.Abs(maxX - minX);
var distanceMaxY = Mathf.Abs(maxY - minY);
if (CompensateForCameraPosition)
{
distanceMaxX += Mathf.Abs(Vector3H(ProCamera2D.TargetsMidPoint) - Vector3H(ProCamera2D.LocalPosition)) * 2f;
distanceMaxY += Mathf.Abs(Vector3V(ProCamera2D.TargetsMidPoint) - Vector3V(ProCamera2D.LocalPosition)) * 2f;
}
distanceMaxX *= .5f;
distanceMaxY *= .5f;
// Zoom out
if (distanceMaxX > ProCamera2D.ScreenSizeInWorldCoordinates.x * ZoomOutBorder * .5f ||
distanceMaxY > ProCamera2D.ScreenSizeInWorldCoordinates.y * ZoomOutBorder * .5f)
{
if (distanceMaxX / ProCamera2D.ScreenSizeInWorldCoordinates.x >= distanceMaxY / ProCamera2D.ScreenSizeInWorldCoordinates.y)
_targetCamSize = (distanceMaxX / ProCamera2D.GameCamera.aspect) / ZoomOutBorder;
else
_targetCamSize = distanceMaxY / ZoomOutBorder;
}
// Zoom in
else if (distanceMaxX < ProCamera2D.ScreenSizeInWorldCoordinates.x * ZoomInBorder * .5f &&
distanceMaxY < ProCamera2D.ScreenSizeInWorldCoordinates.y * ZoomInBorder * .5f)
{
if (distanceMaxX / ProCamera2D.ScreenSizeInWorldCoordinates.x >= distanceMaxY / ProCamera2D.ScreenSizeInWorldCoordinates.y)
_targetCamSize = (distanceMaxX / ProCamera2D.GameCamera.aspect) / ZoomInBorder;
else
_targetCamSize = distanceMaxY / ZoomInBorder;
}
_minCameraSize = (ProCamera2D.StartScreenSizeInWorldCoordinates.y * .5f) / MaxZoomInAmount;
_maxCameraSize = (ProCamera2D.StartScreenSizeInWorldCoordinates.y * .5f) * MaxZoomOutAmount;
_targetCamSize = Mathf.Clamp(_targetCamSize, _minCameraSize, _maxCameraSize);
}
#if UNITY_EDITOR
override protected void DrawGizmos()
{
base.DrawGizmos();
var gameCamera = ProCamera2D.GetComponent<Camera>();
var cameraDimensions = gameCamera.orthographic ? Utils.GetScreenSizeInWorldCoords(gameCamera) : Utils.GetScreenSizeInWorldCoords(gameCamera, Mathf.Abs(Vector3D(transform.localPosition)));
float cameraDepthOffset = Vector3D(ProCamera2D.transform.localPosition) + Mathf.Abs(Vector3D(transform.localPosition)) * Vector3D(ProCamera2D.transform.forward);
var cameraCenter = Application.isPlaying ? ProCamera2D.TargetsMidPoint : VectorHVD(Vector3H(transform.position), Vector3V(transform.position), cameraDepthOffset);
var bordersColor = DisableWhenOneTarget && ProCamera2D.CameraTargets.Count <= 1 ? EditorPrefsX.GetColor(PrefsData.ZoomToFitColorKey, Color.white) * .75f : EditorPrefsX.GetColor(PrefsData.ZoomToFitColorKey, Color.white);
// Targets bounding box
if (Application.isPlaying && ProCamera2D.CameraTargets.Count > 1)
{
float maxX = Mathf.NegativeInfinity;
float minX = Mathf.Infinity;
float maxY = Mathf.NegativeInfinity;
float minY = Mathf.Infinity;
for (int i = 0; i < ProCamera2D.CameraTargets.Count; i++)
{
var targetPos = new Vector2(Vector3H(ProCamera2D.CameraTargets[i].TargetPosition) + ProCamera2D.CameraTargets[i].TargetOffset.x, Vector3V(ProCamera2D.CameraTargets[i].TargetPosition) + ProCamera2D.CameraTargets[i].TargetOffset.y);
maxX = targetPos.x > maxX ? targetPos.x : maxX;
minX = targetPos.x < minX ? targetPos.x : minX;
maxY = targetPos.y > maxY ? targetPos.y : maxY;
minY = targetPos.y < minY ? targetPos.y : minY;
}
Gizmos.color = EditorPrefsX.GetColor(PrefsData.ZoomToFitColorKey, Color.white) * .25f;
Gizmos.DrawWireCube(cameraCenter, VectorHV(maxX - minX, maxY - minY));
}
if (CompensateForCameraPosition)
{
cameraCenter = VectorHVD(Vector3H(ProCamera2D.transform.localPosition), Vector3V(ProCamera2D.transform.localPosition), cameraDepthOffset);
}
// Zoom out border
Gizmos.color = Math.Abs(_targetCamSizeSmoothed - _maxCameraSize) < .01f ? bordersColor * .5f : bordersColor;
Gizmos.DrawWireCube(cameraCenter, VectorHV(cameraDimensions.x, cameraDimensions.y) * ZoomOutBorder);
Utils.DrawArrowForGizmo(cameraCenter + VectorHV(cameraDimensions.x / 2 * ZoomOutBorder, cameraDimensions.y / 2 * ZoomOutBorder), VectorHV(.05f * cameraDimensions.y, .05f * cameraDimensions.y), .04f * cameraDimensions.y);
Utils.DrawArrowForGizmo(cameraCenter - VectorHV(cameraDimensions.x / 2 * ZoomOutBorder, cameraDimensions.y / 2 * ZoomOutBorder), VectorHV(-.05f * cameraDimensions.y, -.05f * cameraDimensions.y), .04f * cameraDimensions.y);
// Zoom in border
Gizmos.color = Math.Abs(_targetCamSizeSmoothed - _minCameraSize) < .01f ? bordersColor * .75f : bordersColor;
Gizmos.DrawWireCube(cameraCenter, VectorHV(cameraDimensions.x, cameraDimensions.y) * ZoomInBorder);
Utils.DrawArrowForGizmo(cameraCenter + VectorHV(cameraDimensions.x / 2 * ZoomInBorder, cameraDimensions.y / 2 * ZoomInBorder), VectorHV(-.05f * cameraDimensions.y, -.05f * cameraDimensions.y), .04f * cameraDimensions.y);
Utils.DrawArrowForGizmo(cameraCenter - VectorHV(cameraDimensions.x / 2 * ZoomInBorder, cameraDimensions.y / 2 * ZoomInBorder), VectorHV(.05f * cameraDimensions.y, .05f * cameraDimensions.y), .04f * cameraDimensions.y);
}
#endif
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 60d259ae680f345ccb8abad710dd1263
timeCreated: 1478707495
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 8e42ceb90de0e4186a212d690bcfceff
folderAsset: yes
timeCreated: 1439810986
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: d936fc412fb074c00afaa1f16f621d11
folderAsset: yes
timeCreated: 1445532901
licenseType: Store
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,100 @@
using System;
using UnityEngine;
using System.Collections;
namespace Com.LuisPedroFonseca.ProCamera2D
{
[ExecuteInEditMode]
public class ProCamera2DLetterbox : MonoBehaviour
{
[Range(0, .5f)] public float Amount = 0f;
public Color Color;
Material _material;
private int TopPropertyID;
private int BottomPropertyID;
private int ColorPropertyID;
private float _previousAmount = float.MaxValue;
Material material
{
get
{
if (_material != null) return _material;
_material = new Material(Shader.Find("Hidden/ProCamera2D/Letterbox")) {hideFlags = HideFlags.HideAndDontSave};
return _material;
}
}
private void OnEnable()
{
_previousAmount = float.MaxValue;
if(TopPropertyID == 0)
TopPropertyID = Shader.PropertyToID("_Top");
if(BottomPropertyID == 0)
BottomPropertyID = Shader.PropertyToID("_Bottom");
if(ColorPropertyID == 0)
ColorPropertyID = Shader.PropertyToID("_Color");
}
void OnRenderImage(RenderTexture sourceTexture, RenderTexture destTexture)
{
if (Mathf.Approximately(Amount, 0f) || material == null)
{
Graphics.Blit(sourceTexture, destTexture);
return;
}
if (Math.Abs(Amount - _previousAmount) > 0.0001f)
{
Amount = Mathf.Clamp01(Amount);
material.SetFloat(TopPropertyID, 1 - Amount);
material.SetFloat(BottomPropertyID, Amount);
material.SetColor(ColorPropertyID, Color);
}
Graphics.Blit(sourceTexture, destTexture, material);
_previousAmount = Amount;
}
void OnDisable()
{
if (_material)
{
DestroyImmediate(_material);
}
}
public void TweenTo(float targetAmount, float duration)
{
StopAllCoroutines();
StartCoroutine(TweenToRoutine(targetAmount, duration));
}
IEnumerator TweenToRoutine(float targetAmount, float duration)
{
var initialAmount = Amount;
var t = 0f;
while (t <= 1.0f)
{
t += (ProCamera2D.Instance.IgnoreTimeScale ? Time.unscaledDeltaTime : Time.deltaTime) / duration;
Amount = Utils.EaseFromTo(initialAmount, targetAmount, t, EaseType.EaseOut);
yield return null;
}
Amount = targetAmount;
yield return null;
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 1f6c9f1aed605415dbee05337f61d59a
timeCreated: 1445532889
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: c0bbfbb0cfe67457db027809e1cdeeb9
folderAsset: yes
timeCreated: 1445955187
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,41 @@
Shader "Hidden/ProCamera2D/Letterbox"
{
Properties
{
_MainTex("Base (RGB)", 2D) = "white" {}
_Top("Top Bar", Range(0.0,1.0)) = 1.0
_Bottom("Bottom Bar", Range(0.0,1.0)) = 1.0
_Color("Base(RGB)", Color) = (1,1,1,1)
}
SubShader
{
ZTest Always Cull Off ZWrite Off Fog{ Mode Off }
Pass
{
CGPROGRAM
#pragma vertex vert_img
#pragma fragment frag
#include "UnityCG.cginc"
uniform sampler2D _MainTex;
uniform float4 _Color;
uniform float _Top;
uniform float _Bottom;
fixed4 frag(v2f_img i) : COLOR
{
fixed4 screen = tex2D(_MainTex, i.uv);
if (i.uv.y < _Bottom || i.uv.y > _Top)
{
screen.xyz = _Color;
}
return screen;
}
ENDCG
}
}
FallBack "Diffuse"
}

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 793e285a2632244d6bfaf202e00b88cd
timeCreated: 1445526368
licenseType: Store
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: d36db5ec1e3ae40c080d1d1536d8f767
folderAsset: yes
timeCreated: 1440931959
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,13 @@
using UnityEngine;
namespace Com.LuisPedroFonseca.ProCamera2D
{
[HelpURLAttribute("http://www.procamera2d.com/user-guide/extension-parallax/")]
/// <summary>
/// Add this class to an object if you want its position on the scene view to match the same relative position to the main parallax layer during runtime.
/// </summary>
public class ProCamera2DParallaxObject : MonoBehaviour
{
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 8d1877ba63b794fb7b73c35629719a64
timeCreated: 1440759673
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 54e42ba4d5f494e38a4ff0690a9b5692
folderAsset: yes
timeCreated: 1440931970
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,158 @@
using UnityEngine;
namespace Com.LuisPedroFonseca.ProCamera2D
{
[HelpURLAttribute("http://www.procamera2d.com/user-guide/extension-pixel-perfect/")]
[ExecuteInEditMode]
public class ProCamera2DPixelPerfectSprite : BasePC2D, IPostMover
{
public bool IsAMovingObject;
public bool IsAChildSprite;
public Vector2 LocalPosition;
[Range(-8, 32)]
public int SpriteScale = 0;
Sprite _sprite;
ProCamera2DPixelPerfect _pixelPerfectPlugin;
[SerializeField]
Vector3 _initialScale = Vector3.one;
int _prevSpriteScale;
override protected void Awake()
{
base.Awake();
if (ProCamera2D == null)
{
enabled = false;
return;
}
GetPixelPerfectPlugin();
GetSprite();
ProCamera2D.AddPostMover(this);
}
void Start()
{
SetAsPixelPerfect();
}
#region IPostMover implementation
public void PostMove(float deltaTime)
{
if(enabled)
Step();
}
public int PMOrder { get { return _pmOrder; } set { _pmOrder = value; } }
int _pmOrder = 2000;
#endregion
#if UNITY_EDITOR
void LateUpdate()
{
if(enabled && !Application.isPlaying && !IsAMovingObject)
SetAsPixelPerfect();
if(!Application.isPlaying)
Step();
}
#endif
void Step()
{
if (_pixelPerfectPlugin == null || !_pixelPerfectPlugin.enabled)
return;
if (IsAMovingObject)
SetAsPixelPerfect();
_prevSpriteScale = SpriteScale;
}
void GetPixelPerfectPlugin()
{
_pixelPerfectPlugin = ProCamera2D.GetComponent<ProCamera2DPixelPerfect>();
#if UNITY_EDITOR
if(_pixelPerfectPlugin == null)
Debug.LogWarning("PixelPerfect extension not present. Please add it to the ProCamera2D core.");
#endif
}
void GetSprite()
{
var spriteRenderer = GetComponent<SpriteRenderer>();
if (spriteRenderer != null)
_sprite = spriteRenderer.sprite;
}
public void SetAsPixelPerfect()
{
#if UNITY_EDITOR
if (Vector3H == null)
base.Awake();
if (_sprite == null)
GetSprite();
if (_pixelPerfectPlugin == null)
GetPixelPerfectPlugin();
if (Vector3H == null || _sprite == null || _pixelPerfectPlugin == null)
return;
#endif
// Reset position
if (IsAChildSprite)
_transform.localPosition = VectorHVD(
Utils.AlignToGrid(LocalPosition.x, _pixelPerfectPlugin.PixelStep),
Utils.AlignToGrid(LocalPosition.y, _pixelPerfectPlugin.PixelStep),
Vector3D(_transform.localPosition));
// Position
_transform.position = VectorHVD(
Utils.AlignToGrid(Vector3H(_transform.position), _pixelPerfectPlugin.PixelStep),
Utils.AlignToGrid(Vector3V(_transform.position), _pixelPerfectPlugin.PixelStep),
Vector3D(_transform.position));
// Scale
if (SpriteScale == 0)
{
//The user was at 0 scale the last update, so save the current scale
if (_prevSpriteScale == 0)
_initialScale = _transform.localScale;
//The user just changed the scale to 0, so restore the original scale
else
_transform.localScale = _initialScale;
}
else
{
var adjustedSpriteScale = SpriteScale < 0 ? 1f / (float)SpriteScale * -1f : SpriteScale;
var scale = _sprite.pixelsPerUnit * adjustedSpriteScale * (1 / _pixelPerfectPlugin.PixelsPerUnit);
_transform.localScale = new Vector3(
Mathf.Sign(_transform.localScale.x) * scale,
Mathf.Sign(_transform.localScale.y) * scale,
_transform.localScale.z);
}
}
protected override void OnDestroy()
{
base.OnDestroy();
if(ProCamera2D != null)
ProCamera2D.RemovePostMover(this);
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 4695037a2aece46e6bbdf2cbb78dc2da
timeCreated: 1455023231
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 446e477a03be643d599936de19c546d4
folderAsset: yes
timeCreated: 1456042443
licenseType: Store
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,20 @@
using UnityEngine;
namespace Com.LuisPedroFonseca.ProCamera2D
{
/// <summary>
/// Basic blit class used by the ProCamera2DTransitionFX extension
/// </summary>
[ExecuteInEditMode]
public class BasicBlit : MonoBehaviour
{
public Material CurrentMaterial;
void OnRenderImage(RenderTexture src, RenderTexture dst)
{
if (CurrentMaterial != null)
Graphics.Blit(src, dst, CurrentMaterial);
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 6725ec8ba7ec346269e03a744226f7a8
timeCreated: 1465202954
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,245 @@
%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: ProCamera2DTransitionsFXMaterial
m_Shader: {fileID: 4800000, guid: 8792cf492ecb54aa989bb9be033e5c62, type: 3}
m_ShaderKeywords:
m_LightmapFlags: 5
m_CustomRenderQueue: 2000
stringTagMap: {}
m_SavedProperties:
serializedVersion: 2
m_TexEnvs:
data:
first:
name: _MainTex
second:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
data:
first:
name: _BumpMap
second:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
data:
first:
name: _DetailNormalMap
second:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
data:
first:
name: _ParallaxMap
second:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
data:
first:
name: _OcclusionMap
second:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
data:
first:
name: _EmissionMap
second:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
data:
first:
name: _DetailMask
second:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
data:
first:
name: _DetailAlbedoMap
second:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
data:
first:
name: _MetallicGlossMap
second:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
data:
first:
name: _TransitionTex
second:
m_Texture: {fileID: 2800000, guid: 52c0eae9fffb947308dc66fa436b1a1a, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Floats:
data:
first:
name: _value
second: 0.84
data:
first:
name: _SrcBlend
second: 1
data:
first:
name: _DstBlend
second: 0
data:
first:
name: _Cutoff
second: 0.5
data:
first:
name: _Parallax
second: 0.02
data:
first:
name: _ZWrite
second: 1
data:
first:
name: _Glossiness
second: 0.5
data:
first:
name: _BumpScale
second: 1
data:
first:
name: _OcclusionStrength
second: 1
data:
first:
name: _DetailNormalMapScale
second: 1
data:
first:
name: _UVSec
second: 0
data:
first:
name: _Mode
second: 0
data:
first:
name: _Metallic
second: 0
data:
first:
name: value
second: 0
data:
first:
name: fadeToBackgroundColour
second: 1
data:
first:
name: distance
second: 0.01
data:
first:
name: numberOfBlinds
second: 20.6
data:
first:
name: dissolveRadius
second: 0.44
data:
first:
name: amplitude
second: 0.0625
data:
first:
name: wavelength
second: 8
data:
first:
name: spread
second: 0.25
data:
first:
name: horizontalCells
second: 16
data:
first:
name: verticalCells
second: 16
data:
first:
name: rectangles
second: 32
data:
first:
name: squares
second: 100
data:
first:
name: numberOfStripes
second: 16
data:
first:
name: numberOfSections
second: 8
data:
first:
name: amplitude1
second: 0.025
data:
first:
name: wavelength1
second: 16
data:
first:
name: amplitude2
second: 0.05
data:
first:
name: wavelength2
second: 4
data:
first:
name: _Step
second: 0
data:
first:
name: _Direction
second: 3
data:
first:
name: _Smoothing
second: 0.202
m_Colors:
data:
first:
name: _EmissionColor
second: {r: 0, g: 0, b: 0, a: 1}
data:
first:
name: _Color
second: {r: 1, g: 1, b: 1, a: 1}
data:
first:
name: backgroundColour
second: {r: 0, g: 0, b: 0, a: 1}
data:
first:
name: _BackgroundColour
second: {r: 0, g: 0, b: 0, a: 1}
data:
first:
name: _BackgroundColor
second: {r: 0.43382353, g: 0.05741782, b: 0.05741782, a: 1}

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 3a08940ebc9914ff7b06aecb5ee9e944
timeCreated: 1455819129
licenseType: Store
NativeFormatImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 8f3ba8813eca14522bbee0afa9d72281
folderAsset: yes
timeCreated: 1456045102
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

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