-
-
Save IneonInoodle/64459ae547fabb7deb1d5133e28b2405 to your computer and use it in GitHub Desktop.
switches cinemachine camera bounds and blends to new pre defined cameras
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Cinemachine; | |
using MoreMountains.Tools; | |
using System.Collections; | |
using System.Collections.Generic; | |
using UnityEngine; | |
public enum CameraZoomType { Normal, ZoomIn, ZoomOut} | |
/// <summary> | |
/// Lets you change bounds based on triggers, also can zoom in and out, works with the obect CameraBoundsChanger.cs (use prefab) | |
/// </summary> | |
public class CameraBoundsManager : Singleton<CameraBoundsManager> | |
{ | |
public CinemachineVirtualCamera CurrentVirtualCamera; | |
protected CinemachineVirtualCamera LastVirtualCamera; | |
public CameraZoomType CurrentCameraZoomType; | |
// say if you have two camera bounds, one camera bounds inside another, then both would be stored in here. | |
public List<CinemachineVirtualCamera> CurrentlyActiveVirtualCameras; | |
public List<CinemachineVirtualCamera> AllCameras; | |
public GameObject DefaultVirtualCameraPrefab; | |
public GameObject ZoomInVirtualCameraPrefab; | |
public GameObject ZoomOutVirtualCameraPrefab; | |
public GameObject VirtualCameraParent; | |
public CinemachineTargetGroup TargetGroup; | |
public CinemachineVirtualCamera SetToActive(CameraZoomType zoomType, Collider2D col) | |
{ | |
CurrentCameraZoomType = zoomType; | |
GameObject currentNewCamera = null; | |
switch (zoomType) | |
{ | |
case CameraZoomType.Normal: | |
currentNewCamera = Instantiate(DefaultVirtualCameraPrefab, VirtualCameraParent.transform); | |
break; | |
case CameraZoomType.ZoomIn: | |
currentNewCamera = Instantiate(ZoomInVirtualCameraPrefab, VirtualCameraParent.transform); | |
break; | |
case CameraZoomType.ZoomOut: | |
currentNewCamera = Instantiate(ZoomOutVirtualCameraPrefab, VirtualCameraParent.transform); | |
break; | |
} | |
// save last for setting priority | |
LastVirtualCamera = CurrentVirtualCamera; | |
// set current camera | |
CurrentVirtualCamera = currentNewCamera.GetComponent<CinemachineVirtualCamera>(); | |
if (LastVirtualCamera != null) | |
{ | |
// set priority to be one higher than the last so camera pans from last to camera we just created | |
CurrentVirtualCamera.Priority = LastVirtualCamera.Priority + 1; | |
} | |
else | |
{ | |
// first camera | |
CurrentVirtualCamera.Priority = 10; | |
} | |
// set bounds of newly created camera to be the bonds we pass in | |
CinemachineConfiner _confiner = currentNewCamera.GetComponent<CinemachineConfiner>(); | |
// if no col set to default col, then we check if this manger has collider, and we use that(its the collider attached to this prefab object), could be null! camera works fine with no bounds | |
if (col == null) | |
_confiner.m_BoundingShape2D = GetComponent<PolygonCollider2D>(); | |
else | |
_confiner.m_BoundingShape2D = col; | |
_confiner.InvalidatePathCache(); | |
// make camera follow player | |
CurrentVirtualCamera.Follow = TargetGroup.gameObject.transform; | |
// store camera in list | |
CurrentlyActiveVirtualCameras.Add(CurrentVirtualCamera); | |
return CurrentVirtualCamera; | |
} | |
/// <summary> | |
/// Called normally on player OnTriggerExit, to delete/remove camera | |
/// </summary> | |
/// <param name="c"></param> | |
public void RemoveFromActive(CinemachineVirtualCamera c) | |
{ | |
if (c == null) | |
return; | |
// these means we had case of nested camera bounds | |
// dont need to create new default camera, because one exists still | |
if (CurrentlyActiveVirtualCameras.Count > 1) | |
{ | |
int _index = CurrentlyActiveVirtualCameras.IndexOf(CurrentVirtualCamera); | |
// we couldnt find camera in our list | |
if (_index == -1) | |
{ | |
Debug.LogWarning("ERROR Virtual camera from somewhere we didnt create?"); | |
} | |
// our active camera is now the one we had before | |
CurrentVirtualCamera = CurrentlyActiveVirtualCameras[_index - 1]; | |
} else | |
{ | |
// we need to create a default camera with no bounds, we are not inside any bounds triggers | |
//set active camera to be a new default virtual cam with no bounds | |
SetToActive(CameraZoomType.Normal, null); | |
} | |
// remove item from list | |
CurrentlyActiveVirtualCameras.Remove(c); | |
// set its priority to 0 to shift to next camera | |
c.Priority = 0; | |
// destroy object, after 3 seconds to make sure cinemachine is not blending between this camera (blend time on CM Brain is 2) | |
Destroy(c.gameObject, 3); | |
} | |
// Start is called before the first frame update | |
void Awake() | |
{ | |
// base awake initializes this singleton | |
base.Awake(); | |
Initialize(); | |
// create first vcam so we have a default one | |
SetToActive(CameraZoomType.Normal, null); | |
} | |
void Initialize() | |
{ | |
// we want to parent the virtual camera in the right spot | |
if (VirtualCameraParent == null) | |
{ | |
VirtualCameraParent = Camera.main.transform.parent.gameObject; | |
} | |
// cinemachine supports a thing called target group which works like super smash bros camera with multiple targets. We use this by default because game technically built for multiplayer. and would still work with multiplayer | |
if (TargetGroup == null) | |
{ | |
// use target group to follow player (target group targets are set by level manager to be all the players in multiplayer, only has one player in it normally) | |
TargetGroup = FindObjectOfType<CinemachineTargetGroup>(); | |
} | |
} | |
// Update is called once per frame | |
void Update() | |
{ | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment