// --------------------------------------------------------------------------------------------------------------------
//
// Part of: Photon Unity Networking Demos
//
//
// Used in PUN Basics Tutorial to deal with the Camera work to follow the player
//
// developer@exitgames.com
// --------------------------------------------------------------------------------------------------------------------
using UnityEngine;
namespace Photon.Pun.Demo.PunBasics
{
///
/// Camera work. Follow a target
///
public class CameraWork : MonoBehaviour
{
#region Private Fields
[Tooltip("The distance in the local x-z plane to the target")]
[SerializeField]
private float distance = 7.0f;
[Tooltip("The height we want the camera to be above the target")]
[SerializeField]
private float height = 3.0f;
[Tooltip("Allow the camera to be offseted vertically from the target, for example giving more view of the sceneray and less ground.")]
[SerializeField]
private Vector3 centerOffset = Vector3.zero;
[Tooltip("Set this as false if a component of a prefab being instanciated by Photon Network, and manually call OnStartFollowing() when and if needed.")]
[SerializeField]
private bool followOnStart = false;
[Tooltip("The Smoothing for the camera to follow the target")]
[SerializeField]
private float smoothSpeed = 0.125f;
// cached transform of the target
Transform cameraTransform;
// maintain a flag internally to reconnect if target is lost or camera is switched
bool isFollowing;
// Cache for camera offset
Vector3 cameraOffset = Vector3.zero;
#endregion
#region MonoBehaviour Callbacks
///
/// MonoBehaviour method called on GameObject by Unity during initialization phase
///
void Start()
{
// Start following the target if wanted.
if (followOnStart)
{
OnStartFollowing();
}
}
void LateUpdate()
{
// The transform target may not destroy on level load,
// so we need to cover corner cases where the Main Camera is different everytime we load a new scene, and reconnect when that happens
if (cameraTransform == null && isFollowing)
{
OnStartFollowing();
}
// only follow is explicitly declared
if (isFollowing) {
Follow ();
}
}
#endregion
#region Public Methods
///
/// Raises the start following event.
/// Use this when you don't know at the time of editing what to follow, typically instances managed by the photon network.
///
public void OnStartFollowing()
{
cameraTransform = Camera.main.transform;
isFollowing = true;
// we don't smooth anything, we go straight to the right camera shot
Cut();
}
#endregion
#region Private Methods
///
/// Follow the target smoothly
///
void Follow()
{
cameraOffset.z = -distance;
cameraOffset.y = height;
cameraTransform.position = Vector3.Lerp(cameraTransform.position, this.transform.position +this.transform.TransformVector(cameraOffset), smoothSpeed*Time.deltaTime);
cameraTransform.LookAt(this.transform.position + centerOffset);
}
void Cut()
{
cameraOffset.z = -distance;
cameraOffset.y = height;
cameraTransform.position = this.transform.position + this.transform.TransformVector(cameraOffset);
cameraTransform.LookAt(this.transform.position + centerOffset);
}
#endregion
}
}