CRO Camera
Adding camera to the scene

As soon as you import the CRO Camera into your project, a new menu will be available. From that menu you have access to Camera Creation Wizard. You can find it in GameObject -> CodeRoadOne -> Camera. This will open this window:

The wizard will try to find the first camera in the scene and add it to the ‘Camera’ field. In case this is not the right camera, drag and drop from your hierarchy the correct camera that you want the script to control.
If there is no camera in the scene, a new camera will be created with the default settings. You can rename camera and pivot in the respective fields. The pivot is another game object that has the script CRO_Camera attached, and is also the parent of the camera.
If “Add Axis To Input Manager” is selected the axis used by the CRO Camera will be automatically added to the Input Manager. If you don’t select the “Overwrite Axes If Exists” the wizard will not change the existing setup. This could cause some problems with the setup and manual fix will be needed. In general, the input axes names are really specific to the camera so not overwrite will happen if you just imported the camera. In case you click second time, overwrite will be unavoidable.
A note here: If you rename an axis after you added them to the input manager and decide to re-add axis to the input manager the old axes are still going to be there.
After that, you just need to click the Create button and everything will be set up for you.
Setting up the camera
Setup

When you select CRO_Camera, you will see our custom editor.
Setup is the first menu displayed. You can see the camera that is being used in the Camera field.
Follow target will let you select which game object to follow, or if not selected, you can choose what position the camera should look at.
Smoothing allows you to setup how fast the camera will rotate to the targeted rotation, how fast it will get to the targeted position, how fast it will zoom in and out and how fast it will rotate to see the target position in case it needs to move up if a collision occurs.
Camera limit. In this section you can specify in what area the camera is allowed to move, the collision bound. You can manually set it up or let it autodetect the world bounds. For autodetect limits, you should select the layer mask that will be used when checking for objects. For example, you could have a collision layer that is used by the game play, that will dictate the actual world bounds for the camera move, and another layer that is defining an outer area for cosmetics or far away objects only, area that the player cannot in fact reach.
Distance

In this section you control how the camera is positioned in relation to the targeted position or object.
For each of the Orbit radius, Orbit height and Orthographic size you have two values. The two values indicate where the camera is located when zoomed in (min) and where the camera is located when zoomed out (max).
The Orthographic size is used only when you have an orthographic camera, which requires a specific way to give the illusion of zooming in and out.
The Defaults fields specify what is the zoom level and from what direction the camera is looking to the target when you press play.
The Apply button will take the information from the target, distances and defaults and adjust the camera to look at that position immediately.
Control

In this section you define how the camera will be controlled by panning, rotating and zooming. The default mapping is using Unity Standard Input.
We also provide default mapping for touch control. The touch control should work on all devices that supports touch control.
Panning

In this section you control how or if you allow to pan the camera.
The panning only works if the camera is NOT following a target.
Pan with keyboard. If you enable panning by keyboard you will need to set up the axis names for horizontal and vertical. The axis can be added inside the Input Tab.
When panning with the keyboard you need to specify how fast the camera will move when you press the keys. This can be set by modifying the value in the Movement speed.
The default movement keys are arrows and A, S, D, W.
Pan with mouse. To pan with the mouse, you need to specify when this will happen. By default, you will start to pan with the mouse when you hold down the middle mouse button or left ctrl.
Pan with joystick. We also provide a way to allow you to pan the camera with the joystick. As you did for the set up of the keyboard, you will need to set up the names for the axis for horizontal and vertical movement, and set up the speed of movement as well.
This is how the axis are setup (in the Input Tab) in the demo scene, to use the left stick in the case of dual controller. Please note that the joystick input controller was tested only on Windows.
Screen edge input. Panning by screen edge input refers to panning by moving the mouse to the edge of the screen. If enabled, you can specify the thickness of the border at top and bottom (vertical) and left and right (horizontal). Also, you need to specify how fast the camera will move if the mouse gets in the specified area, close to the edge of the screen.
Pan using touch. If you enable it, you will be able to pan on IOS and Android and any other platform that supports touch controls. To pan with touch, you will need to use one finger and drag around.
Drag detection. This is a very important parameter. This is used when panning with the mouse on a desktop, and on mobiles using touch controls.
Threshold is defining the distance in pixels you must move the mouse on desktop or finger on touch screen, before we consider that you are actually trying to drag. This is useful in case you want to add support to detect click, or some other useful controls.
If you don’t want the user to be able to move the camera by panning, you can disable the panning by deselecting the Keyboard, Mouse, Joystick, Screen edge and Touch controls.
Rotating

Here you have similar options as you had for panning. You can enable rotating around the target on the Y axis using the keyboard, mouse, joystick or touch controls. Same as on panning, if you don’t want to allow the user to rotate around the target, you can just disable the keyboard, mouse, joystick and touch controls.
Rotate with Keyboard. Here you need to setup the axis name for the keyboard rotation, and how fast you will rotate by using the keys. The default key for rotating the camera are E, R.
Rotate with Mouse. As in the case of panning, you need to define the keys used to rotate. By default, this is set up as right click and left alt button.
Rotate with Joystick. By default, the rotation with the joystick is set up for using dual joystick, and rotation is done using the right stick. Please note that the joystick controller was tested only on Windows.
Rotate using touch. As in the case on panning, using touch controls you need to define the angle threshold that will indicate that you are trying to rotate.
You have two option for rotation Swipe or Rotation gesture. Both of them are using two fingers.
For the swipe gesture place two fingers close to each other and move them left or right to rotate the camera.
For the rotation gesture the easiest method of rotation is to place two fingers close to each other and move one of them around the other.
Zooming

As already stated above, you can set up the controls for zooming by keyboard, mouse wheel, joystick and touch controls. The previous values are adjusted for the demo scene, so if you have different scaling or wider range for zooming you will need to adjust the speed for zooming.
Zooming with keyboard. Again, you will need to specify the axis name for zooming and the speed. To zoom with keyboard the defaults are keypad + and -, or page up and page down.
Zoom with mouse wheel. For this you just need to specify the speed of zooming.
Zoom with joystick. Same as for the keyboard, you need to specify the axis name and the speed. In the demo scene the buttons for zooming are: L1, R1 (on a PS4 controller) or LB, RB (on an Xbox controller).
Zoom using touch. Zooming on mobile is done using two fingers. If you want to zoom in you need to move the fingers away from each other. If you want to zoom out you need to get your fingers close to each other.
You will need to setup the threshold for detecting that you are trying to zoom, and the speed of zooming
Clicking

With clicking you can setup an event when a click is detected. You can customize what key, mouse button or joystick button to be used when detecting a click. This for example is useful to find out what object is under mouse if you click somewhere.
In the above image you have the default settings for the camera.
Click using keyboard. The default key is space. This is using the current mouse position to check what is under the cursor.
Click using mouse. The default mouse button is left mouse button.
Click using joystick. The default button is Joystick Button 0.
Click detection time. This defines the maximum time from when you press the button until you release it in seconds. If the time is bigger, this is not going to be a valid click.
Collision

In this menu you can specify if you want the camera to react to the environment. Basically, to move up if there is no clear view of the target.
If enabled, you will need to setup a few parameters. First, there is the collision mask. What collision layers should we take into account when we try to detect the height of the environment. You can choose any combination of layers you want.
Height cast. This is defining from what height we should start to detect the collidable objects. Be aware that if the height is too low and we start the cast from inside an object we will not be able to identify that object. To be safe, you should set this value to be above all the objects in your world (Y axis).
Optimise angle. This is used for the case when the camera is moving up because of a collision with the environment, and defines how close the camera will get to the target. For every single unit that the camera is moving up, the angle set up is defining by how many units the camera will get closer to the target.
Collision type Capsule. If you are using a Perspective camera this is the type of collision that you need to use.
This is trying to create a capsule between the camera position and the target position, with the radius that you set up. The length is specifying how much the capsule will extend behind the camera. In this way we can try to detect if there is one object ready to enter the screen so we can start to move up the camera.
Collision type Box. If you are using Orthographic camera this is the type of collision that you need to use.
The box collision was designed to be used with orthographic camera. For this method, you need to set up only the height of the Box that is used to detect the highest point of intersection of the environment with it. The box height should be small as there is no real influence on the result.
How to use camera from code
You have access to all the parameters that you set up in the editor, by directly modifying them. The most useful parameters are “follow target” or “free camera”.
If you changed the settings at runtime you might need to call m_CRO_Camera.SettingsChanged(); to readjust the camera position, orientation and zoom levels based on the new settings.
When switching from one target to another, the camera will smoothly go to the new target. If you want to just snap in one frame to the desired position, just call m_CRO_Camera.SnapToDefault();
Functions and helpers
Setup
Camera GetCamera()
Transform GetTarget()
Vector3 GetTargetedPosition()
Vector2 GetMapLimitLow()
Vector2 GetMapLimitHigh()
float GetSmoothMoveSpeed()
float GetSmoothRotationSpeed()
float GetSmoothZoomSpeed()
float GetSmoothAdjDistance()
bool IsFollowingTarget()
void SetCamera(Camera camera)
void SetTarget(Transform target)
void SetFreeCam(bool keepCurrentPosition)
void SetTargetedPosition(Vector3 position)
void SetMapLimitLow(Vector2 limitLow)
void SetMapLimitHigh(Vector2 limitHigh)
void SetSmoothMoveSpeed(float value)
void SetSmoothRotationSpeed(float value)
void SetSmoothZoomSpeed(float value)
void SetSmoothAdjDistance(float value)
Distance
Vector2 GetOrbitRadius()
Vector2 GetOrbitHeight()
Vector2 GetOrthographicSize()
float GetDefaultOrientation()
float GetDefaultZoomLevel()
void SetOrbitRadius(Vector2 radius)
void SetOrbitHeight(Vector2 height)
void SetOrthographicSize(Vector2 size)
void SetDefaultOrientation(float orientation)
void SetDefaultZoomLevel(float zoom)
Collision
bool GetUseCameraCollision()
LayerMask GetCollisionMask()
float GetCapsuleRadius()
float GetCapsuleLength()
float GetHeightCast()
float GetPerUnitInHeightCloser()
float GetBoxHeight()
CollisionType GetCollisionTypeCheck()
void SetUseCameraCollision(bool useCameraCollision)
void SetCollisionMask(LayerMask collisionMask)
void SetCapsuleRadius(float capsuleRadius)
void SetCapsuleLength(float capsuleLength)
void SetHeightCast(float heightCast)
void SetPerUnitInHeightCloser(float perUnitInHeightCloser)
void SetBoxHeight(float boxHeight)
void SetCollisionTypeCheck(CollisionType collisionTypeCheck)
Helpers methods
//Get current camera orientation
Quaternion GetCameraOrientation()
//Get current camera forward
Vector3 GetCameraForward()
//Get current pivot position
Vector3 GetPivotPosition()
//Get the targeted zoom level. This is where the camera level should get. Is not necessary where the camera zoom level is in this moment
float GetTargetedZoomLevel()
//Get the targeted rotation angle. Same as for the zoom, is where the camera should rotate now where is the camera now
float GetTargetedRotationAngle()
//Set where the camera should get in terms of zoom. It will smoothly interpolate towards that zoom level
void SetTargetedZoomLevel(float zoom)
//Set where the camera should rotate. It will smoothly interpolate towards that rotation angle
void SetTargetedRotationAngle(float angle)
//Set where the pivot of the camera should be.
void SetPivotPosition(Vector3 position)
//Computes an offset taking into account the angle of rotation around Y on a circle with a specific radius at specific height.
Vector3 GetOffset(float angle, float radius, float height)
//Using the current camera and a specific position, we re construct a plane at the specified height (iY). Using the mouse position we will return where we intersect the constructed plane. This helps not to have collision on all objects and still be able to identify where we clicked.
Vector3 MouseToWorld(Vector3 iCameraPosition, float iY, Vector3 iMousePosition)
//Get the object under the mouse. It will return true in case there is valid information inside hitInfo.
bool GetObjectUnderMouse(out RaycastHit hitInfo)
//In case you changed setting at runtime, you might need to call this function to readjust the camera position and zoom levels based on the new settings
void SettingsChanged()
//If you want to disable camera controls just call DisableInputs(true). If you need to re-enable camera controls call DisableInputs(false)
void EnableInputs(bool enableInputs)
//If you want the camera to jump to new settings and not smoothly interpolate between current position/orientation/zoom call this function
void SnapToDefault()
//This is a helper function used to compute the map limits. It is used by the editor to auto detect world bounds
void ComputeMapLimits(LayerMask layerMask)
Example on how to switch between follow target and free camera
public class CRO_GameController : MonoBehaviour
{
public CRO_Camera m_CRO_Camera;
public void FollowTarget(Transform target)
{
m_CRO_Camera.m_Target = target;
m_CRO_Camera.m_FollowTarget = true;
}
public void FreeCamera(Vector3 position)
{
m_CRO_Camera.m_TargetPosition = position;
m_CRO_Camera.m_Target = null;
m_CRO_Camera.m_FollowTarget = false;
}
public void SwitchToFreeCamera()
{
FreeCamera(m_CRO_Camera.m_Target ? m_CRO_Camera.m_Target.position : m_CRO_Camera.m_TargetPosition);
}
}