Question by
Rqe · Dec 29, 2021 at 01:38 PM ·
camera follow
How do I make the camera follow a selected game object?
I need help setting up my camera to constantly follow a game object when it's selected. I already have a game object that detects whenever it is clicked, and a camera script that follows a specified game object. I just need to somehow make the camera follow the exact object when selected.
Selectable game object script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Noggin : MonoBehaviour
{
private Animator anim;
public GameObject gui;
// Start is called before the first frame update
void Start()
{
anim = GetComponent<Animator>();
}
void OnMouseDown()
{
gui.SetActive(true);
if (this.gameObject != null)
{
DragCamera.instance.target = this.gameObject;
}
}
}
Camera script
using UnityEngine;
using System;
using System.Collections.Generic;
using UnityEngine.EventSystems;
public class DragCamera : MonoBehaviour
{
public static DragCamera instance;
public event Action<Vector2> onStartTouch;
public event Action<Vector2> onEndTouch;
public event Action<Vector2> onTap;
public event Action<Vector2> onSwipe;
public event Action<float, float> onPinch;
[Header("Tap")]
[Tooltip("The maximum movement for a touch motion to be treated as a tap")]
public float maxDistanceForTap = 40;
[Tooltip("The maximum duration for a touch motion to be treated as a tap")]
public float maxDurationForTap = 0.4f;
[Header("Desktop debug")]
[Tooltip("Use the mouse on desktop?")]
public bool useMouse = true;
[Tooltip("The simulated pinch speed using the scroll wheel")]
public float mouseScrollSpeed = 2;
[Header("Camera control")]
[Tooltip("Does the script control camera movement?")]
public bool controlCamera = true;
[Tooltip("The controlled camera, ignored of controlCamera=false")]
public Camera cam;
[Header("UI")]
[Tooltip("Are touch motions listened to if they are over UI elements?")]
public bool ignoreUI = false;
[Header("Bounds")]
[Tooltip("Is the camera bound to an area?")]
public bool useBounds;
public float boundMinX = -150;
public float boundMaxX = 150;
public float boundMinY = -150;
public float boundMaxY = 150;
Vector2 touch0StartPosition;
Vector2 touch0LastPosition;
float touch0StartTime;
bool cameraControlEnabled = true;
bool canUseMouse;
public float yPos = 2;
public bool ZoomActive;
public float interpVelocity;
public float minDistance;
public float followDistance;
public Vector3 offset;
Vector3 targetPos;
public GameObject target;
public bool isTouching { get; private set; }
public Vector2 touchPosition { get { return touch0LastPosition; } }
void Start()
{
canUseMouse = Application.platform != RuntimePlatform.Android && Application.platform != RuntimePlatform.IPhonePlayer && Input.mousePresent;
targetPos = transform.position;
}
void Update()
{
if (useMouse && canUseMouse)
{
UpdateWithMouse();
}
else
{
UpdateWithTouch();
}
if (target)
{
Vector3 posNoZ = transform.position;
posNoZ.z = target.transform.position.z;
Vector3 targetDirection = (target.transform.position - posNoZ);
interpVelocity = targetDirection.magnitude * 10f;
targetPos = transform.position + (targetDirection.normalized * interpVelocity * Time.deltaTime);
transform.position = Vector3.Lerp(transform.position, targetPos + offset, 0.25f);
}
}
void LateUpdate()
{
CameraInBounds();
}
void UpdateWithMouse()
{
if (Input.GetMouseButtonDown(0))
{
if (ignoreUI || !IsPointerOverUIObject())
{
touch0StartPosition = Input.mousePosition;
touch0StartTime = Time.time;
touch0LastPosition = touch0StartPosition;
isTouching = true;
if (onStartTouch != null) onStartTouch(Input.mousePosition);
}
}
if (Input.GetMouseButton(0) && isTouching)
{
Vector2 move = (Vector2)Input.mousePosition - touch0LastPosition;
touch0LastPosition = Input.mousePosition;
if (move != Vector2.zero)
{
OnSwipe(move);
}
}
if (Input.GetMouseButtonUp(0) && isTouching)
{
if (Time.time - touch0StartTime <= maxDurationForTap
&& Vector2.Distance(Input.mousePosition, touch0StartPosition) <= maxDistanceForTap)
{
OnClick(Input.mousePosition);
}
if (onEndTouch != null) onEndTouch(Input.mousePosition);
isTouching = false;
cameraControlEnabled = true;
}
if (Input.mouseScrollDelta.y != 0)
{
OnPinch(Input.mousePosition, 1, Input.mouseScrollDelta.y < 0 ? (1 / mouseScrollSpeed) : mouseScrollSpeed, Vector2.right);
}
}
void UpdateWithTouch()
{
int touchCount = Input.touches.Length;
if (touchCount == 1)
{
Touch touch = Input.touches[0];
switch (touch.phase)
{
case TouchPhase.Began:
{
if (ignoreUI || !IsPointerOverUIObject())
{
touch0StartPosition = touch.position;
touch0StartTime = Time.time;
touch0LastPosition = touch0StartPosition;
isTouching = true;
if (onStartTouch != null) onStartTouch(touch0StartPosition);
}
break;
}
case TouchPhase.Moved:
{
touch0LastPosition = touch.position;
if (touch.deltaPosition != Vector2.zero && isTouching)
{
OnSwipe(touch.deltaPosition);
}
break;
}
case TouchPhase.Ended:
{
if (Time.time - touch0StartTime <= maxDurationForTap
&& Vector2.Distance(touch.position, touch0StartPosition) <= maxDistanceForTap
&& isTouching)
{
OnClick(touch.position);
}
if (onEndTouch != null) onEndTouch(touch.position);
isTouching = false;
cameraControlEnabled = true;
break;
}
case TouchPhase.Stationary:
case TouchPhase.Canceled:
break;
}
}
else if (touchCount == 2)
{
Touch touch0 = Input.touches[0];
Touch touch1 = Input.touches[1];
if (touch0.phase == TouchPhase.Ended || touch1.phase == TouchPhase.Ended) return;
isTouching = true;
float previousDistance = Vector2.Distance(touch0.position - touch0.deltaPosition, touch1.position - touch1.deltaPosition);
float currentDistance = Vector2.Distance(touch0.position, touch1.position);
if (previousDistance != currentDistance)
{
OnPinch((touch0.position + touch1.position) / 2, previousDistance, currentDistance, (touch1.position - touch0.position).normalized);
}
}
else
{
if (isTouching)
{
if (onEndTouch != null) onEndTouch(touch0LastPosition);
isTouching = false;
}
cameraControlEnabled = true;
}
}
void OnClick(Vector2 position)
{
if (onTap != null && (ignoreUI || !IsPointerOverUIObject()))
{
onTap(position);
}
}
void OnSwipe(Vector2 deltaPosition)
{
if (onSwipe != null)
{
onSwipe(deltaPosition);
}
if (controlCamera && cameraControlEnabled)
{
if (cam == null) cam = Camera.main;
cam.transform.position -= (cam.ScreenToWorldPoint(deltaPosition) - cam.ScreenToWorldPoint(Vector2.zero));
}
}
void OnPinch(Vector2 center, float oldDistance, float newDistance, Vector2 touchDelta)
{
if (onPinch != null)
{
onPinch(oldDistance, newDistance);
}
if (controlCamera && cameraControlEnabled)
{
if (cam == null) cam = Camera.main;
if (cam.orthographic)
{
var currentPinchPosition = cam.ScreenToWorldPoint(center);
cam.orthographicSize = Mathf.Max(0.1f, cam.orthographicSize * oldDistance / newDistance);
var newPinchPosition = cam.ScreenToWorldPoint(center);
cam.transform.position -= newPinchPosition - currentPinchPosition;
}
else
{
cam.fieldOfView = Mathf.Clamp(cam.fieldOfView * oldDistance / newDistance, 0.1f, 179.9f);
}
}
}
public bool IsPointerOverUIObject()
{
if (EventSystem.current == null) return false;
PointerEventData eventDataCurrentPosition = new PointerEventData(EventSystem.current);
eventDataCurrentPosition.position = new Vector2(Input.mousePosition.x, Input.mousePosition.y);
List<RaycastResult> results = new List<RaycastResult>();
EventSystem.current.RaycastAll(eventDataCurrentPosition, results);
return results.Count > 0;
}
public void CancelCamera()
{
cameraControlEnabled = false;
}
void CameraInBounds()
{
if (controlCamera && useBounds && cam != null && cam.orthographic)
{
cam.orthographicSize = Mathf.Min(cam.orthographicSize, ((boundMaxY - boundMinY) / 2) - 0.001f);
cam.orthographicSize = Mathf.Min(cam.orthographicSize, (Screen.height * (boundMaxX - boundMinX) / (2 * Screen.width)) - 0.001f);
Vector2 margin = cam.ScreenToWorldPoint((Vector2.up * Screen.height / 2) + (Vector2.right * Screen.width / 2)) - cam.ScreenToWorldPoint(Vector2.zero);
float marginX = margin.x;
float marginY = margin.y;
float camMaxX = boundMaxX - marginX;
float camMaxY = boundMaxY - marginY;
float camMinX = boundMinX + marginX;
float camMinY = boundMinY + marginY;
float camX = Mathf.Clamp(cam.transform.position.x, camMinX, camMaxX);
float camY = Mathf.Clamp(cam.transform.position.y, camMinY, camMaxY);
cam.transform.position = new Vector3(camX, camY, cam.transform.position.z);
}
}
}
I tried the code I have right now but the game object script has an error and says "Object reference not set to an instance of an object"
Comment
Your answer

Follow this Question
Related Questions
3rd person camera for Roll a Ball 1 Answer
Camera following on Green and Red Axis 0 Answers
Camera Collision Problem 0 Answers
How do I stop camera movement from going out of frame while using lerp 0 Answers
Camera does not follow player properly 0 Answers