Insanely huge initial commit

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

View File

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

View File

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

View File

@@ -0,0 +1,9 @@
#if PLAYMAKER
using Com.LuisPedroFonseca.ProCamera2D;
using HutongGames.PlayMaker;
[ActionCategory(ProCamera2D.Title)]
public abstract class FsmStateActionProCamera2DBase : FsmStateAction
{
}
#endif

View File

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

View File

@@ -0,0 +1,32 @@
#if PLAYMAKER
using Com.LuisPedroFonseca.ProCamera2D;
using HutongGames.PlayMaker;
using TooltipAttribute = HutongGames.PlayMaker.TooltipAttribute;
[Tooltip("Add a target for the camera to follow.")]
public class PC2DAddCameraTarget : FsmStateActionProCamera2DBase
{
[RequiredField]
[Tooltip("The camera target to add")]
public FsmGameObject target;
[HasFloatSlider(0, 1)]
[Tooltip("The influence this target horizontal position should have when calculating the average position of all the targets")]
public FsmFloat targetInfluenceH = 1;
[HasFloatSlider(0, 1)]
[Tooltip("The influence this target vertical position should have when calculating the average position of all the targets")]
public FsmFloat targetInfluenceV = 1;
[Tooltip("The time it takes for this target to reach it's influence")]
public FsmFloat duration = 0;
public override void OnEnter()
{
if (ProCamera2D.Instance != null && target.Value)
ProCamera2D.Instance.AddCameraTarget(target.Value.transform, targetInfluenceH.Value, targetInfluenceV.Value, duration.Value);
Finish();
}
}
#endif

View File

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

View File

@@ -0,0 +1,32 @@
#if PLAYMAKER
using Com.LuisPedroFonseca.ProCamera2D;
using HutongGames.PlayMaker;
using TooltipAttribute = HutongGames.PlayMaker.TooltipAttribute;
[Tooltip("Adjusts a target influence")]
public class PC2DAdjustCameraTargetInfluence : FsmStateActionProCamera2DBase
{
[RequiredField]
[Tooltip("The Transform of the target")]
public FsmGameObject target;
[HasFloatSlider(0, 1)]
[Tooltip("The influence this target horizontal position should have when calculating the average position of all the targets")]
public FsmFloat targetInfluenceH = 1;
[HasFloatSlider(0, 1)]
[Tooltip("The influence this target vertical position should have when calculating the average position of all the targets")]
public FsmFloat targetInfluenceV = 1;
[Tooltip("The time it takes for this target to reach it's influence")]
public FsmFloat duration = 0;
public override void OnEnter()
{
if (ProCamera2D.Instance != null && target.Value)
ProCamera2D.Instance.AdjustCameraTargetInfluence(target.Value.transform, targetInfluenceH.Value, targetInfluenceV.Value, duration.Value);
Finish();
}
}
#endif

View File

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

View File

@@ -0,0 +1,18 @@
#if PLAYMAKER
using Com.LuisPedroFonseca.ProCamera2D;
using HutongGames.PlayMaker;
using TooltipAttribute = HutongGames.PlayMaker.TooltipAttribute;
[Tooltip("Apply the given influence to the camera")]
public class PC2DApplyInfluence : FsmStateActionProCamera2DBase
{
[Tooltip("The vector representing the influence to be applied")]
public FsmVector2 Influence;
public override void OnUpdate()
{
if (ProCamera2D.Instance != null)
ProCamera2D.Instance.ApplyInfluence(Influence.Value);
}
}
#endif

View File

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

View File

@@ -0,0 +1,48 @@
#if PLAYMAKER
using Com.LuisPedroFonseca.ProCamera2D;
using HutongGames.PlayMaker;
using TooltipAttribute = HutongGames.PlayMaker.TooltipAttribute;
using UnityEngine;
[Tooltip("Apply the given influences to the camera during the corresponding durations")]
public class PC2DApplyInfluencesTimed : FsmStateActionProCamera2DBase
{
[RequiredField]
[Tooltip("An array of the vectors representing the influences to be applied")]
public FsmVector2[] Influences;
[RequiredField]
[Tooltip("An array of the vectors representing the influences to be applied")]
public FsmFloat[] Durations;
public override void Reset()
{
Influences = new FsmVector2[0];
Durations = new FsmFloat[0];
}
public override void OnEnter()
{
if (ProCamera2D.Instance != null)
{
var entries = Influences.GetLength(0);
var influences = new Vector2[entries];
for (int i = 0; i < entries; i++)
{
influences[i] = (Influences.GetValue(i) as FsmVector2).Value;
}
var durations = new float[entries];
for (int i = 0; i < entries; i++)
{
durations[i] = (Durations.GetValue(i) as FsmFloat).Value;
}
ProCamera2D.Instance.ApplyInfluencesTimed(influences, durations);
}
Finish();
}
}
#endif

View File

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

View File

@@ -0,0 +1,27 @@
#if PLAYMAKER
using Com.LuisPedroFonseca.ProCamera2D;
using HutongGames.PlayMaker;
using TooltipAttribute = HutongGames.PlayMaker.TooltipAttribute;
using UnityEngine;
[Tooltip("Starts or stops a cinematic")]
public class PC2DCinematicsToggle : FsmStateActionProCamera2DBase
{
[RequiredField]
[Tooltip("The gameObject that contains the ProCamera2DCinematics component")]
public FsmGameObject Cinematics;
public override void OnEnter()
{
var cinematics = Cinematics.Value.GetComponent<ProCamera2DCinematics>();
if (cinematics == null)
Debug.LogError("No Cinematics component found in the gameObject: " + Cinematics.Value.name);
if (ProCamera2D.Instance != null && cinematics != null)
cinematics.Toggle();
Finish();
}
}
#endif

View File

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

View File

@@ -0,0 +1,21 @@
#if PLAYMAKER
using Com.LuisPedroFonseca.ProCamera2D;
using HutongGames.PlayMaker;
using TooltipAttribute = HutongGames.PlayMaker.TooltipAttribute;
[Tooltip("Moves the camera instantly to the defined position")]
public class PC2DMoveCameraInstantlyToPosition : FsmStateActionProCamera2DBase
{
[RequiredField]
[Tooltip("The final position of the camera")]
public FsmVector3 CameraPos;
public override void OnEnter()
{
if (ProCamera2D.Instance != null)
ProCamera2D.Instance.MoveCameraInstantlyToPosition(CameraPos.Value);
Finish();
}
}
#endif

View File

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

View File

@@ -0,0 +1,24 @@
#if PLAYMAKER
using Com.LuisPedroFonseca.ProCamera2D;
using HutongGames.PlayMaker;
using TooltipAttribute = HutongGames.PlayMaker.TooltipAttribute;
[Tooltip("Remove a target from the camera")]
public class PC2DRemoveCameraTarget : FsmStateActionProCamera2DBase
{
[RequiredField]
[Tooltip("The Transform of the target")]
public FsmGameObject target;
[Tooltip("The time it takes for this target to reach a zero influence. Use for a more progressive transition.")]
public FsmFloat duration = 0;
public override void OnEnter()
{
if (ProCamera2D.Instance != null && target.Value)
ProCamera2D.Instance.RemoveCameraTarget(target.Value.transform, duration.Value);
Finish();
}
}
#endif

View File

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

View File

@@ -0,0 +1,58 @@
#if PLAYMAKER
using Com.LuisPedroFonseca.ProCamera2D;
using HutongGames.PlayMaker;
using TooltipAttribute = HutongGames.PlayMaker.TooltipAttribute;
using UnityEngine;
[Tooltip("Enter a room when using the Rooms extension")]
public class PC2DRoomsEnter : FsmStateActionProCamera2DBase
{
[Tooltip("Set the current room by index"), RequiredField]
public FsmInt RoomIndex;
[Tooltip("Set the current room by ID. Note that using ID will override index")]
public FsmString RoomId;
[Tooltip("If false, the camera instantly transitions to the room. If true, the camera uses the transition configured in the Rooms extension editor.")]
public bool UseTransition = true;
ProCamera2DRooms _rooms;
public override void Reset()
{
RoomIndex = 0;
RoomId = null;
}
public override void OnEnter()
{
var pc2d = ProCamera2D.Instance;
if (pc2d == null)
{
Debug.LogError("No ProCamera2D found! Please add the core component to your Main Camera.");
Finish();
return;
}
_rooms = pc2d.GetComponent<ProCamera2DRooms>();
if (_rooms == null)
{
Debug.LogError("No Rooms extension found in ProCamera2D!");
Finish();
return;
}
SetRoom();
Finish();
}
void SetRoom()
{
if (!RoomId.IsNone && !string.IsNullOrEmpty(RoomId.Value))
{
_rooms.EnterRoom(RoomId.Value, UseTransition);
}
else
{
_rooms.EnterRoom(RoomIndex.Value, UseTransition);
}
}
}
#endif

View File

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

View File

@@ -0,0 +1,27 @@
#if PLAYMAKER
using Com.LuisPedroFonseca.ProCamera2D;
using HutongGames.PlayMaker;
using TooltipAttribute = HutongGames.PlayMaker.TooltipAttribute;
using UnityEngine;
[Tooltip("Stops the current constant shake on the camera")]
public class PC2DShakeConstantStop : FsmStateActionProCamera2DBase
{
[RequiredField]
[Tooltip("The camera with the ProCamera2D component, most probably the MainCamera")]
public FsmGameObject MainCamera;
public override void OnEnter()
{
var shake = MainCamera.Value.GetComponent<ProCamera2DShake>();
if (shake == null)
Debug.LogError("The ProCamera2D component needs to have the Shake plugin enabled.");
if (ProCamera2D.Instance != null && shake != null)
shake.StopConstantShaking();
Finish();
}
}
#endif

View File

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

View File

@@ -0,0 +1,30 @@
#if PLAYMAKER
using Com.LuisPedroFonseca.ProCamera2D;
using HutongGames.PlayMaker;
using TooltipAttribute = HutongGames.PlayMaker.TooltipAttribute;
using UnityEngine;
[Tooltip("Enables a constant shake on the camera using a preset configured in the editor")]
public class PC2DShakeConstantWithPreset : FsmStateActionProCamera2DBase
{
[RequiredField]
[Tooltip("The camera with the ProCamera2D component, most probably the MainCamera")]
public FsmGameObject MainCamera;
[Tooltip("The name of the constant shake preset configured in the editor")]
public FsmString PresetName;
public override void OnEnter()
{
var shake = MainCamera.Value.GetComponent<ProCamera2DShake>();
if (shake == null)
Debug.LogError("The ProCamera2D component needs to have the Shake plugin enabled.");
if (ProCamera2D.Instance != null && shake != null)
shake.ConstantShake(PresetName.Value);
Finish();
}
}
#endif

View File

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

View File

@@ -0,0 +1,27 @@
#if PLAYMAKER
using Com.LuisPedroFonseca.ProCamera2D;
using HutongGames.PlayMaker;
using TooltipAttribute = HutongGames.PlayMaker.TooltipAttribute;
using UnityEngine;
[Tooltip("Stops all current shakes on the camera")]
public class PC2DShakeStop : FsmStateActionProCamera2DBase
{
[RequiredField]
[Tooltip("The camera with the ProCamera2D component, most probably the MainCamera")]
public FsmGameObject MainCamera;
public override void OnEnter()
{
var shake = MainCamera.Value.GetComponent<ProCamera2DShake>();
if (shake == null)
Debug.LogError("The ProCamera2D component needs to have the Shake plugin enabled.");
if (ProCamera2D.Instance != null && shake != null)
shake.StopShaking();
Finish();
}
}
#endif

View File

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

View File

@@ -0,0 +1,30 @@
#if PLAYMAKER
using Com.LuisPedroFonseca.ProCamera2D;
using HutongGames.PlayMaker;
using TooltipAttribute = HutongGames.PlayMaker.TooltipAttribute;
using UnityEngine;
[Tooltip("Shakes the camera position along its horizontal and vertical axes using a preset configured in the editor")]
public class PC2DShakeWithPreset : FsmStateActionProCamera2DBase
{
[RequiredField]
[Tooltip("The camera with the ProCamera2D component, most probably the MainCamera")]
public FsmGameObject MainCamera;
[Tooltip("The name of the shake preset configured in the editor")]
public FsmString PresetName;
public override void OnEnter()
{
var shake = MainCamera.Value.GetComponent<ProCamera2DShake>();
if (shake == null)
Debug.LogError("The ProCamera2D component needs to have the Shake plugin enabled.");
if (ProCamera2D.Instance != null && shake != null)
shake.Shake(PresetName.Value);
Finish();
}
}
#endif

View File

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

View File

@@ -0,0 +1,58 @@
#if PLAYMAKER
using Com.LuisPedroFonseca.ProCamera2D;
using HutongGames.PlayMaker;
using TooltipAttribute = HutongGames.PlayMaker.TooltipAttribute;
using UnityEngine;
[Tooltip("Shakes the camera position along its horizontal and vertical axes with the given values")]
public class PC2DShakeWithValues : FsmStateActionProCamera2DBase
{
[RequiredField]
[Tooltip("The camera with the ProCamera2D component, most probably the MainCamera")]
public FsmGameObject MainCamera;
[Tooltip("The shake strength on each axis")]
public FsmVector2 Strength;
[Tooltip("The duration of the shake")]
public FsmFloat Duration = 1;
[Tooltip("Indicates how much will the shake vibrate. Don't use values lower than 1 or higher than 100 for better results")]
public FsmInt Vibrato = 10;
[Tooltip("Indicates how much random the shake will be")]
[HasFloatSlider(0, 1)]
public FsmFloat Randomness = .1f;
[Tooltip("The initial angle of the shake. Use -1 if you want it to be random.")]
[HasFloatSlider(-1, 360)]
public FsmInt InitialAngle = 10;
[Tooltip("The maximum rotation the camera can reach during shake")]
public FsmVector3 Rotation;
[Tooltip("How smooth the shake should be, 0 being instant")]
[HasFloatSlider(0, .5f)]
public FsmFloat Smoothness;
public override void OnEnter()
{
var shake = MainCamera.Value.GetComponent<ProCamera2DShake>();
if (shake == null)
Debug.LogError("The ProCamera2D component needs to have the Shake plugin enabled.");
if (ProCamera2D.Instance != null && shake != null)
shake.Shake(
Duration.Value,
Strength.Value,
Vibrato.Value,
Randomness.Value,
InitialAngle.Value,
Rotation.Value,
Smoothness.Value);
Finish();
}
}
#endif

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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