-
Notifications
You must be signed in to change notification settings - Fork 1
/
ScreenWrapper.cs
141 lines (137 loc) · 6.29 KB
/
ScreenWrapper.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(Camera))]
public class ScreenWrapper : MonoBehaviour
{
public delegate void Teleporting(GameObject gO);
/// <summary>
/// Executes before the game object is teleported (wrapped)
/// </summary>
public static event Teleporting OnTeleport;
public LayerMask cullingMask;
public static LayerMask _cullingMask { get; private set; } = 0;
[Tooltip("Will The Camera Move around the scene? (More Expensive)")]public bool stationaryCamera;
static Vector3 cameraWorldBounds;
static Vector3 cameraLocalBounds;
static Vector3[] cameraOffsets;
public static List<Transform> wrappableObjects = new List<Transform>();
private static List<GameObject> activeCameras = new List<GameObject>();
// Start is called before the first frame update
private void Awake()
{
_cullingMask = cullingMask;
UpdateCameraBounds();
UpdateCameraOffsets();
CreateCameras(cameraOffsets, cullingMask);
}
void CreateCameras(Vector3[] cameraPositions, LayerMask layer)
{
GameObject parent = new GameObject("ScreenWrapper");
for(int i = 0; i < cameraPositions.Length; i ++) // Create 8 new cameras and place at specific locations relative to central camera
{
GameObject newCam = new GameObject("Cam_" + i, typeof(Camera));
newCam.transform.parent = parent.transform;
activeCameras.Add(newCam);
Camera newCamCam = newCam.GetComponent<Camera>();
newCamCam.cullingMask = layer;
newCamCam.clearFlags = CameraClearFlags.Depth;
newCamCam.orthographic = true;
newCam.transform.position = cameraPositions[i];
}
}
void MoveCameras()
{
for(int i = 0; i < activeCameras.Count; i ++)
{
activeCameras[i].transform.position = cameraOffsets[i];
activeCameras[i].GetComponent<Camera>().depth = Camera.main.depth;
}
}
void UpdateCameraBounds()
{
cameraWorldBounds = new Vector3(transform.position.x + Camera.main.orthographicSize * Screen.width / Screen.height, // Get the top left corner of the camera in worldSpace.
transform.position.y + Camera.main.orthographicSize);
cameraLocalBounds = new Vector3(Camera.main.orthographicSize * Screen.width / Screen.height, // Get the width of camera view in Local space.
Camera.main.orthographicSize);
}
void UpdateCameraOffsets()
{
cameraOffsets = new Vector3[] {
cameraWorldBounds - 3 * new Vector3(cameraLocalBounds.x, 0) + new Vector3(0, cameraLocalBounds.y) + new Vector3(0, 0, transform.position.z), // Cam_1
cameraWorldBounds - new Vector3(cameraLocalBounds.x, 0) + new Vector3(0, cameraLocalBounds.y) + new Vector3(0, 0, transform.position.z), // Cam_2
cameraWorldBounds + cameraLocalBounds, // Cam_3
cameraWorldBounds - 3 * new Vector3(cameraLocalBounds.x, 0) - new Vector3(0, cameraLocalBounds.y) + new Vector3(0, 0, transform.position.z), // Cam_4
// Skip Cam 5 because it's main camera
cameraWorldBounds + new Vector3(cameraLocalBounds.x, 0) - new Vector3(0, cameraLocalBounds.y) + new Vector3(0, 0, transform.position.z), // Cam_6
cameraWorldBounds - 3 * cameraLocalBounds + new Vector3(0, 0, transform.position.z), // Cam_7
cameraWorldBounds - cameraLocalBounds - 2 * new Vector3(0, cameraLocalBounds.y) + new Vector3(0, 0, transform.position.z), // Cam_8
cameraWorldBounds + new Vector3(cameraLocalBounds.x, 0) - 3 * new Vector3(0, cameraLocalBounds.y) + new Vector3(0, 0, transform.position.z) // Cam_9
};
}
public void CheckPassingCameraBound(Transform gObject)
{
if (gObject.GetComponent<ScreenWrappingObject>().isInitialized)
{
if (gObject.position.x >= cameraWorldBounds.x)
{
if (OnTeleport != null) OnTeleport(gObject.gameObject);
gObject.position -= 2 * new Vector3(cameraLocalBounds.x, 0);
}
if (gObject.position.y >= cameraWorldBounds.y)
{
if (OnTeleport != null) OnTeleport(gObject.gameObject);
gObject.position -= 2 * new Vector3(0, cameraLocalBounds.y);
}
if (gObject.position.x <= (cameraWorldBounds - 2 * cameraLocalBounds).x)
{
if (OnTeleport != null) OnTeleport(gObject.gameObject);
gObject.position += 2 * new Vector3(cameraLocalBounds.x, 0);
}
if (gObject.position.y <= (cameraWorldBounds - 2 * cameraLocalBounds).y)
{
if (OnTeleport != null) OnTeleport(gObject.gameObject);
gObject.position += 2 * new Vector3(0, cameraLocalBounds.y);
}
}
}
public static bool IsSeenInMainCam(GameObject gO, bool fullObject = false)
{
Vector3 objectWidth = Vector3.zero;
if (fullObject)
{
objectWidth = gO.GetComponent<Collider2D>().bounds.size;
}
if (gO.transform.position.x < cameraWorldBounds.x - objectWidth.x // Defining a bounding box for the camera view "site".
&& gO.transform.position.x > (cameraWorldBounds - 2 * cameraLocalBounds).x + objectWidth.x // - if fullObject is true, account for the width of the object and only return true
&& gO.transform.position.y < cameraWorldBounds.y - objectWidth.y // if the entire object('s collider) can be seen in the camera
&& gO.transform.position.y > (cameraWorldBounds - 2 * cameraLocalBounds).y + objectWidth.y)
{
return true;
}
return false;
}
// Update is called once per frame
void Update()
{
if(!stationaryCamera)
{
UpdateCameraOffsets();
}
UpdateCameraBounds();
}
private void FixedUpdate()
{
foreach(Transform wrappableObject in wrappableObjects)
{
CheckPassingCameraBound(wrappableObject);
}
}
private void LateUpdate()
{
if(!stationaryCamera)
{
MoveCameras();
}
}
}