- Home /
Making main camera focus on trigger
Hello, I have a main camera that follows my player all the time, what I want to do is when the player gets to a specific position it triggers the camera to focus on a different area and then smoothly go back to the player (ex.: after 3sec). I tried to do the "Cinemachine 2D tips and tricks" "Group Camera" option but unfortunately i did not managed to do it by myself. The way I kind want it to look like is like this: https://blogs.unity3d.com/wp-content/uploads/2018/07/cinemachine2d8.gif
Hope I explained well with my English :D
Answer by AndyMcGardeen · Jun 02, 2020 at 05:09 PM
I would try something like this:
public float smoothTime = 0.3f;
private Vector3 velocity = Vector3.zero;
// If something
StartCoroutine(Focus(target, player))
//...
IEnumerator Focus (Vector3 targetPos, Vector3 playerPos)
{
while (Vector3.Distance(cam.position, targetPos) > 0.001f)
{
cam.position = Vector3.SmoothDamp(cam.position, targetPos, ref velocity, smoothTime);
yield return new WaitForEndOfFrame();
}
yield return new WaitForSecods(3.0f);
while (Vector3.Distance(cam.position, playerPos) > 0.001f)
{
cam.position = Vector3.SmoothDamp(cam.position, playerPos, ref velocity, smoothTime);
yield return new WaitForEndOfFrame();
}
}
Should I attach this script to the main camera or player?
Attach it where you think is best. I made a more explicit version, that looks more alike the gif. You should change how the coroutine is triggerd tho, maybe using onTriggerEnter: https://docs.unity3d.com/ScriptReference/$$anonymous$$onoBehaviour.OnTriggerEnter2D.html
using System.Collections;
using UnityEngine;
public class GroupView : $$anonymous$$onoBehaviour
{
public Transform cam;
public Transform player;
public Transform target;
public Vector3 camRelPos = Vector3.forward * 4.0f; //Camera position relative to the player
public float timeToWait = 3.0f; //Time to wait before camera returns to player
public float smoothTime = 0.3f; //How quickly will the camera reach group view
private Vector3 velocity = Vector3.zero;
private float fieldOfView;
private void Awake()
{
fieldOfView = cam.GetComponent<Camera>().fieldOfView;
}
void Update()
{
if (Input.GetKeyDown(KeyCode.E)) //Whatever triggers the group view...
{
//***$$anonymous$$ake the camera stop following the player***
StartCoroutine(Focus());
}
}
bool isFocusing = false;
IEnumerator Focus ()
{
if (!isFocusing)
{
isFocusing = true;
Vector3 groupPos = GetGroupPosition(target.position, player.position);
float t = 0;
while (Vector3.Distance(cam.position, groupPos) > 0.02f)
{
groupPos = GetGroupPosition(target.position, player.position);
cam.position = Vector3.SmoothDamp(cam.position, groupPos, ref velocity, smoothTime);
yield return new WaitForFixedUpdate();
}
while (t < timeToWait)
{
groupPos = GetGroupPosition(target.position, player.position);
cam.position = Vector3.SmoothDamp(cam.position, groupPos, ref velocity, smoothTime);
t += Time.deltaTime;
yield return new WaitForFixedUpdate();
}
while (Vector3.Distance(cam.position, player.position + camRelPos) > 0.02f)
{
cam.position = Vector3.SmoothDamp(cam.position, player.position + camRelPos, ref velocity, smoothTime);
yield return new WaitForFixedUpdate();
}
isFocusing = false;
}
}
Vector3 GetGroupPosition(Vector3 targetPos, Vector3 playerPos)
{
return new Vector3
(playerPos.x + (targetPos.x - playerPos.x) / 2,
playerPos.y + (targetPos.y - playerPos.y) / 2,
1.0f + (90 / fieldOfView) * $$anonymous$$athf.Abs(targetPos.x - playerPos.x) / 2); //***Should this be negative?****
}
}
In the script you call "$$anonymous$$ake the camera stop following the player" but how do I do that, I use Cinemachine to follow my player. (2D game btw)
Follow this Question
Related Questions
How to create a multilayered 2D effect? 1 Answer
Unity 3D Render Camera Bug!!! 1 Answer
Scale game vertically only 0 Answers
Cinemachine camera shake on button press 0 Answers
Camera Smooth - Player moves little bit back when jump 1 Answer