Commit 9c5f974a authored by Tommé Nöll's avatar Tommé Nöll
Browse files

made corruption camera scaling for zone visibility work with perspective camera

parent f4eb9b16
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CameraZone : MonoBehaviour
{
public enum FitMode {
grow,
shrink,
average,
useWidth,
useHeight
}
[Tooltip("How to scale the zone if the cameras aspect ration doesn't match")]
public FitMode fitMode;
private Bounds bounds;
private new static CameraController camera;
[SerializeField] [Range(0, 1f)]
private float triggerArea = 0.9f;
private bool playerWasInZone = false;
// Start is called before the first frame update
void Start()
{
CalculateBounds();
FindCamera();
}
public static void FindCamera()
{
if (!camera)
{
camera = GameObject.FindWithTag("MainCamera").GetComponent<CameraController>();
}
#if UNITY_EDITOR
camera.Init();
#endif
}
public void CalculateBounds()
{
bounds = new Bounds(transform.position, transform.localScale);
}
// Update is called once per frame
void Update()
{
Vector3 scaledPos = camera.player.transform.position;
scaledPos = bounds.center + (scaledPos - bounds.center) / triggerArea;
ApplyTarget(bounds.Contains(scaledPos));
}
public void ApplyTarget(bool apply)
{
if (apply)
{
//if (!playerWasInZone)
CalculateBounds();
{
if (camera.GetOrthographic())
{
camera.targetPos = transform.position;
camera.targetSize = CalculateCameraSize(bounds, fitMode);
}
else
{
camera.targetPos = VecZ(transform.position, -(CalculateCameraSize(bounds, fitMode) / 2) / Mathf.Tan(camera.GetFov() / 2 * Mathf.PI / 180));
}
}
}
else
{
if (playerWasInZone)
{
camera.ResetTarget();
}
}
playerWasInZone = apply;
}
public static float CalculateCameraSize(Bounds bounds, FitMode fitMode)
{
float aspect = camera.GetAspectRatio(); // width / height
//float cameraWidthScaled = bounds.size.y * aspect;
float cameraHeightScaled = bounds.size.x / aspect;
switch (fitMode)
{
case FitMode.useWidth :
return cameraHeightScaled;
case FitMode.useHeight :
return bounds.size.y;
case FitMode.grow :
return Mathf.Max(bounds.size.y, cameraHeightScaled);
case FitMode.shrink :
return Mathf.Min(bounds.size.y, cameraHeightScaled);
case FitMode.average :
default :
return (bounds.size.y + cameraHeightScaled) / 2;
}
}
void OnDrawGizmosSelected()
{
CalculateBounds();
Vector3 corner1 = new Vector3(bounds.min.x, bounds.max.y, 0);
Vector3 corner2 = new Vector3(bounds.max.x, bounds.min.y, 0);
Gizmos.color = Color.blue;
Gizmos.DrawLine(VecZ(bounds.max, 0), corner1);
Gizmos.DrawLine(VecZ(bounds.max, 0), corner2);
Gizmos.DrawLine(VecZ(bounds.min, 0), corner1);
Gizmos.DrawLine(VecZ(bounds.min, 0), corner2);
}
private static Vector3 VecZ(Vector3 vec, float z)
{
return new Vector3(vec.x, vec.y, z);
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CameraZone : MonoBehaviour
{
public enum FitMode {
grow,
shrink,
average,
useWidth,
useHeight
}
[Tooltip("How to scale the zone if the cameras aspect ration doesn't match")]
public FitMode fitMode;
private Bounds bounds;
private new static CameraController camera;
[SerializeField] [Range(0, 1f)]
private float triggerArea = 0.9f;
private bool playerWasInZone = false;
// Start is called before the first frame update
void Start()
{
CalculateBounds();
FindCamera();
}
public static void FindCamera()
{
if (!camera)
{
camera = GameObject.FindWithTag("MainCamera").GetComponent<CameraController>();
}
#if UNITY_EDITOR
camera.Init();
#endif
}
public void CalculateBounds()
{
bounds = new Bounds(transform.position, transform.localScale);
}
// Update is called once per frame
void Update()
{
Vector3 scaledPos = camera.player.transform.position;
scaledPos = bounds.center + (scaledPos - bounds.center) / triggerArea;
ApplyTarget(bounds.Contains(scaledPos));
}
public void ApplyTarget(bool apply)
{
if (apply)
{
if (!playerWasInZone)
{
if (camera.GetOrthographic())
{
camera.targetPos = transform.position;
camera.targetSize = CalculateCameraSize(bounds, fitMode);
}
else
{
camera.targetPos = CalculatePerpectiveCameraPosition(transform.position, bounds, fitMode); //calculate camera z to effectively change its size
}
}
}
else
{
if (playerWasInZone)
{
camera.ResetTarget();
}
}
playerWasInZone = apply;
}
public static Vector3 CalculatePerpectiveCameraPosition(Vector3 position, Bounds bounds, FitMode fitMode)
{
return VecZ(position, -(CalculateCameraSize(bounds, fitMode) / 2) / Mathf.Tan(camera.GetFov() / 2 * Mathf.PI / 180));
}
public static float CalculateCameraSize(Bounds bounds, FitMode fitMode)
{
float aspect = camera.GetAspectRatio(); // width / height
//float cameraWidthScaled = bounds.size.y * aspect;
float cameraHeightScaled = bounds.size.x / aspect;
switch (fitMode)
{
case FitMode.useWidth :
return cameraHeightScaled;
case FitMode.useHeight :
return bounds.size.y;
case FitMode.grow :
return Mathf.Max(bounds.size.y, cameraHeightScaled);
case FitMode.shrink :
return Mathf.Min(bounds.size.y, cameraHeightScaled);
case FitMode.average :
default :
return (bounds.size.y + cameraHeightScaled) / 2;
}
}
void OnDrawGizmosSelected()
{
CalculateBounds();
Vector3 corner1 = new Vector3(bounds.min.x, bounds.max.y, 0);
Vector3 corner2 = new Vector3(bounds.max.x, bounds.min.y, 0);
Gizmos.color = Color.blue;
Gizmos.DrawLine(VecZ(bounds.max, 0), corner1);
Gizmos.DrawLine(VecZ(bounds.max, 0), corner2);
Gizmos.DrawLine(VecZ(bounds.min, 0), corner1);
Gizmos.DrawLine(VecZ(bounds.min, 0), corner2);
}
private static Vector3 VecZ(Vector3 vec, float z)
{
return new Vector3(vec.x, vec.y, z);
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[ExecuteInEditMode]
public class CorruptionCamera : MonoBehaviour
{
public CorruptionMap corruptionMap;
public new Camera camera;
public Camera mainCamera;
[SerializeField] private float editorCorruptionCameraScaleFactor = 20f;
// Start is called before the first frame update
void Start()
{
corruptionMap.Init();
camera = GetComponent<Camera>();
camera.targetTexture = corruptionMap.mapTexture;
camera.backgroundColor = new Color(corruptionMap.globalCorruption, 0, 0, 1);
}
// Update is called once per frame
void Update()
{
camera.orthographicSize = mainCamera.orthographicSize;
#if UNITY_EDITOR
if (!Application.IsPlaying(gameObject))
{
ScaleZonesVisible();
camera.orthographicSize *= editorCorruptionCameraScaleFactor;
corruptionMap.plantSurfaceMaterial.SetFloat("_CorruptionCameraScaleFactor", editorCorruptionCameraScaleFactor);
}
#endif
}
//make sure all corruption zones are being rendered in scene view,
//by checking if they are visible to the corruption camera
private void ScaleZonesVisible()
{
Bounds bounds = new Bounds(transform.position, new Vector3(0, 0, 0));
foreach (Transform zoneTransform in corruptionMap.transform)
{
Bounds zoneBounds = zoneTransform.gameObject.GetComponent<SpriteRenderer>().bounds;
bounds.Encapsulate(zoneBounds.min);
bounds.Encapsulate(zoneBounds.max);
}
//Debug.Log(bounds.min + ", " + bounds.max);
//match bounds center to camera position by increasing bounds size
Vector3 min = bounds.min;
Vector3 max = bounds.max;
if (bounds.center.x < transform.position.x)
{
max.x = 2 * transform.position.x - min.x;
}
else
{
min.x = 2 * transform.position.x - max.x;
}
if (bounds.center.y < transform.position.y)
{
max.y = 2 * transform.position.y - min.y;
}
else
{
min.y = 2 * transform.position.y - max.y;
}
bounds.SetMinMax(min, max);
CameraZone.FindCamera();
float targetSize = CameraZone.CalculateCameraSize(bounds, CameraZone.FitMode.grow);
editorCorruptionCameraScaleFactor = Mathf.Max(1, targetSize / mainCamera.orthographicSize / 2);
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[ExecuteInEditMode]
public class CorruptionCamera : MonoBehaviour
{
public CorruptionMap corruptionMap;
public new Camera camera;
public Camera mainCamera;
[SerializeField] private float editorCorruptionCameraScaleFactor = 20f;
// Start is called before the first frame update
void Start()
{
corruptionMap.Init();
camera = GetComponent<Camera>();
camera.targetTexture = corruptionMap.mapTexture;
camera.backgroundColor = new Color(corruptionMap.globalCorruption, 0, 0, 1);
}
// Update is called once per frame
void Update()
{
camera.orthographicSize = mainCamera.orthographicSize;
#if UNITY_EDITOR
if (!Application.IsPlaying(gameObject))
{
ScaleZonesVisible();
if (camera.orthographic)
{
camera.orthographicSize *= editorCorruptionCameraScaleFactor;
}
else
{
camera.transform.position = new Vector3(camera.transform.position.x, camera.transform.position.y, mainCamera.transform.position.z * editorCorruptionCameraScaleFactor);
}
corruptionMap.plantSurfaceMaterial.SetFloat("_CorruptionCameraScaleFactor", editorCorruptionCameraScaleFactor);
}
#endif
}
//make sure all corruption zones are being rendered in scene view,
//by checking if they are visible to the corruption camera
private void ScaleZonesVisible()
{
/*if (!camera.orthographic)
{
editorCorruptionCameraScaleFactor = 1;
return;
}*/
Bounds bounds = new Bounds(transform.position, new Vector3(0, 0, 0));
foreach (Transform zoneTransform in corruptionMap.transform)
{
Bounds zoneBounds = zoneTransform.gameObject.GetComponent<SpriteRenderer>().bounds;
bounds.Encapsulate(zoneBounds.min);
bounds.Encapsulate(zoneBounds.max);
}
//Debug.Log(bounds.min + ", " + bounds.max);
//match bounds center to camera position by increasing bounds size
Vector3 min = bounds.min;
Vector3 max = bounds.max;
if (bounds.center.x < transform.position.x)
{
max.x = 2 * transform.position.x - min.x;
}
else
{
min.x = 2 * transform.position.x - max.x;
}
if (bounds.center.y < transform.position.y)
{
max.y = 2 * transform.position.y - min.y;
}
else
{
min.y = 2 * transform.position.y - max.y;
}
bounds.SetMinMax(min, max);
CameraZone.FindCamera();
float targetSize = CameraZone.CalculateCameraSize(bounds, CameraZone.FitMode.grow);
editorCorruptionCameraScaleFactor = Mathf.Max(1, targetSize / mainCamera.orthographicSize / 2);
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment