Insanely huge initial commit

This commit is contained in:
2026-02-21 17:04:05 -08:00
parent 9cdd36191a
commit 613d75914a
22525 changed files with 4035207 additions and 0 deletions

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,544 @@
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);
_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);
// 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: