Try using this script on the Camera to see if it draws a rectangle around the Camera even if it isn’t selected.
using UnityEngine;
using System.Collections;
namespace _AddedEffects
{
[ExecuteInEditMode]
public class DrawCameraBounds : MonoBehaviour
{
private Camera ourCamera;
public Color ourColor = Color.green;
void OnDrawGizmos()
{
if(ourCamera != null && enabled)
{
Rect pixelRect = ourCamera.pixelRect;
Gizmos.color = ourColor;
// the Screen coordinates map to the normal cartesian plane, starting from the bottom-left corner of the screen
Vector2 bottomLeftPoint = ourCamera.ScreenToWorldPoint(new Vector2(0f, 0f));
Vector2 bottomRightPoint = ourCamera.ScreenToWorldPoint(new Vector2(pixelRect.width, 0));
Vector2 topLeftPoint = ourCamera.ScreenToWorldPoint(new Vector2(0f, pixelRect.height));
Vector2 topRightPoint = ourCamera.ScreenToWorldPoint(new Vector2(pixelRect.width, pixelRect.height));
Gizmos.DrawLine(topLeftPoint, topRightPoint);
Gizmos.DrawLine(topRightPoint, bottomRightPoint);
Gizmos.DrawLine(bottomRightPoint, bottomLeftPoint);
Gizmos.DrawLine(bottomLeftPoint, topLeftPoint);
}
}
// Use this for initialization
void Start()
{
ourCamera = GetComponent<Camera>();
}
}
}
Your first 2 lines of code wont be the same. The first line will always be higher than the 2nd line because you’re multiplying the height by the value 0.066f. Both the Viewport and Screen points are relative to normal Cartesian coordinates, which means (0, 0) the origin of the Cartesian axis is the bottom-left of the Camera’s view.
What exactly are topWall, leftWall and rightWall references of?
topWall, leftWall and rightWall are of type BoxCollider2D and they represent the limit of the camera sight so nothing would go out of the player’s view.
Yeah, I know that, but the problem is that if I change the first code to transform.position = mainCamera.ScreenToWorldPoint (new Vector2 (0f, 0f)); it doesn’t put the game object at the bottom-left of the Camera’s view.
BoxCollider2D.center is a local-space coordinate relative to the object it resides upon. You’re trying to assign a World Coordinate relative to the Camera’s screen to a Component’s member variable that specifies a position relative to the GameObject it resides upon.
I don’t understand why your transform is positioned incorrectly in the first scenario. Do you have multiple Cameras in the scene? mainCamera could be pointing to a different Camera than the one you’re trying to position the GameObject relative to.
It’s hard to tell without knowing whats in your scene or what effects are being done on your GameObjects. I managed to get this script working for my camera without any issues using ScreenToWorldPoint
using UnityEngine;
using System.Collections;
namespace CameraBoundaries
{
[ExecuteInEditMode]
public class CameraWalls : MonoBehaviour
{
private Camera ourCamera;
public enum CameraWallSide {LEFT, RIGHT, TOP, BOTTOM}
// We assume these BoxColliders are located externally from the Camera's GameObject
public BoxCollider2D leftWall;
public BoxCollider2D rightWall;
public BoxCollider2D topWall;
// Use this for initialization
void Start()
{
ourCamera = GetComponent<Camera>();
}
// Update is called once per frame
void Update()
{
if(ourCamera != null)
{
if(leftWall != null)
{
SetCameraWall(ourCamera, leftWall, CameraWallSide.LEFT);
}
if(rightWall != null)
{
SetCameraWall(ourCamera, rightWall, CameraWallSide.RIGHT);
}
if(topWall != null)
{
SetCameraWall(ourCamera, topWall, CameraWallSide.TOP);
}
}
}
/// <summary>
/// Sets the wall's size and position to match the target Camera's specified side, stretching to fit the view area's width or height.
/// It is assumed that wall is on a different GameObject than that of the Camera
/// </summary>
public static void SetCameraWall(Camera cam, BoxCollider2D wall, CameraWallSide side)
{
Vector2 wallSidePosition = Vector2.zero;
Rect pixelRect = cam.pixelRect;
if (side == CameraWallSide.LEFT || side == CameraWallSide.RIGHT)
{
float wallThickness = wall.transform.localScale.x * wall.size.x;
if(side == CameraWallSide.LEFT)
{
Vector2 offset = (cam.transform.rotation * -Vector2.right) * (wallThickness / 2f);
wallSidePosition = cam.ScreenToWorldPoint(new Vector2(0f, pixelRect.height / 2f)) + (Vector3)offset;
}
else
{
Vector2 offset = (cam.transform.rotation * Vector2.right) * (wallThickness / 2f);
wallSidePosition = cam.ScreenToWorldPoint(new Vector2(pixelRect.width, pixelRect.height / 2f)) + (Vector3)offset;
}
float wallStretch = (cam.orthographicSize * 2) / wall.transform.localScale.y;
wall.size = new Vector2(wall.size.x, wallStretch);
}
else
{
float wallThickness = wall.transform.localScale.y * wall.size.y;
if(side == CameraWallSide.TOP)
{
Vector2 offset = (cam.transform.rotation * Vector2.up) * (wallThickness / 2f);
wallSidePosition = cam.ScreenToWorldPoint(new Vector2(pixelRect.width / 2f, pixelRect.height)) + (Vector3)offset;
}
else
{
// intentionally left out
}
float wallStretch = (cam.orthographicSize * 2 * cam.aspect) / wall.transform.localScale.x;
wall.size = new Vector2(wallStretch, wall.size.y);
}
wall.transform.position = wallSidePosition;
wall.transform.rotation = cam.transform.rotation;
}
}
}
Note: This script also assumes the walls are on different GameObjects. I don’t know if it will work with multiple Colliders on one GameObject, but I personally prefer to separate colliders to different GameObjects so its easier to manage them.
The walls are on different GameObjects and there’s only one camera on the scene, I really don’t know what’s causing this because I tested the same scripts on another project and the game worked as it should, but after I closed Unity and reopening it, the problem started again…
Changing the cam.ScreenToWorldSize() statement to Camera.main.ScreenToWorldSize() solves the problem, but why does the first one works sometimes? It’s a little confusing.
Did you assign the Camera variable with a Camera attached to a prefab and not the one in the scene? Because maybe its referring to a Camera attached to a prefab. I’ve run into a similar problem with transforms as I assigned a reference of a script in the scene with a prefab, and then instantiated a clone of the prefab before running the scene. Suffice to say, the results were not what I initially expected until I did further reading on prefabs.
In case that wasn’t well understood, consider the following Scene Heirarchy
-DummyCamera
-TestObject
A Camera is attached to DummyCamera.
TestObject has the following script attached:
using UnityEngine;
using System.Collections;
public class _DummyScript2 : MonoBehaviour
{
public Camera camRef;
// Use this for initialization
void Start()
{
}
// Update is called once per frame
void Update()
{
if(camRef != null)
Debug.Log(camRef.orthographicSize);
}
}
I made a prefab of DummyCamera by dragging and dropping it into a directory, then deleted the one in the scene. I assigned camRef with the DummyCamera prefab, and then I dragged DummyCamera into the scene. Changing the DummyCamera’s orthotgraphic size will not change whats printed to the console because camRef is pointing to a prefab instance created with the Scene the moment the Application starts playing. My assumption is that its hidden.
Also if you change the script to this
using UnityEngine;
using System.Collections;
public class _DummyScript2 : MonoBehaviour
{
public Camera camRef;
// Use this for initialization
void Start()
{
}
// Update is called once per frame
void Update()
{
if(camRef != null)
Debug.Log("camRef ortho size: " + camRef.orthographicSize);
Debug.Log("Camera count: " + Camera.allCamerasCount);
}
}
You’ll see that the Camera count is still one, even though the prefab instance with a Camera attached quite obviously exists.
That’s the only thing I can guess if you only have 1 camera shown in the Scene Hierarchy. I don’t know how you’re assigning mainCamera so I can only assume that this might be the problem.