Reputation: 139
I'm doing this thing where an object is moving on a plane, and the camera is in the center of it. I got it so the camera rotates along with the mouse, and when the main camera sees the game object, it stops. So I was using the onbecamevisible() and onbecameinvisible() functions, but that applies to any camera, including the scene view. How do I make it so the objects stops when seen only by the main game camera?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class cubeMove : MonoBehaviour,moveObject
{
Camera cam;
public Transform checkedObject;
void Start()
{
cam = GetComponent<Camera>();
}
void Update()
{
Vector3 viewPos = cam.WorldToViewportPoint(checkedObject.position);
if ()
move();
}
public void move()
{
transform.Rotate(new Vector3(15, 30, 45) * Time.deltaTime);
}
}
Here's my Camera Script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Camera : MonoBehaviour {
public enum RotationAxes { MouseXAndY = 0, MouseX = 1, MouseY = 2 }
public RotationAxes axes = RotationAxes.MouseXAndY;
public float sensitivityX = 15F;
public float sensitivityY = 15F;
public float minimumX = -360F;
public float maximumX = 360F;
public float minimumY = -60F;
public float maximumY = 60F;
float rotationX = 0F;
float rotationY = 0F;
private List<float> rotArrayX = new List<float>();
float rotAverageX = 0F;
private List<float> rotArrayY = new List<float>();
float rotAverageY = 0F;
public float frameCounter = 20;
Quaternion originalRotation;
void Update()
{
if (axes == RotationAxes.MouseXAndY)
{
rotAverageY = 0f;
rotAverageX = 0f;
rotationY += Input.GetAxis("Mouse Y") * sensitivityY;
rotationX += Input.GetAxis("Mouse X") * sensitivityX;
rotArrayY.Add(rotationY);
rotArrayX.Add(rotationX);
if (rotArrayY.Count >= frameCounter)
{
rotArrayY.RemoveAt(0);
}
if (rotArrayX.Count >= frameCounter)
{
rotArrayX.RemoveAt(0);
}
for (int j = 0; j < rotArrayY.Count; j++)
{
rotAverageY += rotArrayY[j];
}
for (int i = 0; i < rotArrayX.Count; i++)
{
rotAverageX += rotArrayX[i];
}
rotAverageY /= rotArrayY.Count;
rotAverageX /= rotArrayX.Count;
rotAverageY = ClampAngle(rotAverageY, minimumY, maximumY);
rotAverageX = ClampAngle(rotAverageX, minimumX, maximumX);
Quaternion yQuaternion = Quaternion.AngleAxis(rotAverageY, Vector3.left);
Quaternion xQuaternion = Quaternion.AngleAxis(rotAverageX, Vector3.up);
transform.localRotation = originalRotation * xQuaternion * yQuaternion;
}
else if (axes == RotationAxes.MouseX)
{
rotAverageX = 0f;
rotationX += Input.GetAxis("Mouse X") * sensitivityX;
rotArrayX.Add(rotationX);
if (rotArrayX.Count >= frameCounter)
{
rotArrayX.RemoveAt(0);
}
for (int i = 0; i < rotArrayX.Count; i++)
{
rotAverageX += rotArrayX[i];
}
rotAverageX /= rotArrayX.Count;
rotAverageX = ClampAngle(rotAverageX, minimumX, maximumX);
Quaternion xQuaternion = Quaternion.AngleAxis(rotAverageX, Vector3.up);
transform.localRotation = originalRotation * xQuaternion;
}
else
{
rotAverageY = 0f;
rotationY += Input.GetAxis("Mouse Y") * sensitivityY;
rotArrayY.Add(rotationY);
if (rotArrayY.Count >= frameCounter)
{
rotArrayY.RemoveAt(0);
}
for (int j = 0; j < rotArrayY.Count; j++)
{
rotAverageY += rotArrayY[j];
}
rotAverageY /= rotArrayY.Count;
rotAverageY = ClampAngle(rotAverageY, minimumY, maximumY);
Quaternion yQuaternion = Quaternion.AngleAxis(rotAverageY, Vector3.left);
transform.localRotation = originalRotation * yQuaternion;
}
}
void Start()
{
Rigidbody rb = GetComponent<Rigidbody>();
if (rb)
rb.freezeRotation = true;
originalRotation = transform.localRotation;
}
public static float ClampAngle(float angle, float min, float max)
{
angle = angle % 360;
if ((angle >= -360F) && (angle <= 360F))
{
if (angle < -360F)
{
angle += 360F;
}
if (angle > 360F)
{
angle -= 360F;
}
}
return Mathf.Clamp(angle, min, max);
}
}
SphereMove
public class sphereMove : MonoBehaviour,moveObject {
public float delta = 1.5f;
public float speed = 2.0f;
private Vector3 startPos;
public UnityEngine.Camera cam;
public Transform checkedObject;
bool isMoving;
void Start()
{
isMoving = true;
cam = Camera.main;
}
void Update()
{
Vector3 viewPos = cam.WorldToViewportPoint(checkedObject.position);
if (viewPos.x > 0 && viewPos.x <= 1 && viewPos.y >= 0 && viewPos.y <= 1 && viewPos.z > 0)
isMoving = false;
else
isMoving = true;
if (isMoving)
move();
}
public void move()
{
Vector3 v = startPos;
v.x += delta * Mathf.Sin(Time.time * speed);
transform.position = v;
}
}
Upvotes: 6
Views: 35815
Reputation: 2612
You can use the Camera.WorldToViewport function, using your Main Camera to call it and giving in parameter the position of the object your are checking. If the x and y coordinates values of the result vector are between 0 and 1 and the z value is superior to 0, it means the center of your object is seen by your camera.
UnityEngine.Camera cam;
bool isMoving;
void Start()
{
cam = UnityEngine.Camera.main;
isMoving = true;
}
void Update()
{
Vector3 viewPos = cam.WorldToViewportPoint(checkedObject.position);
if (viewPos.x >= 0 && viewPos.x <= 1 && viewPos.y >= 0 && viewPos.y <= 1 && viewPos.z > 0)
{
// Your object is in the range of the camera, you can apply your behaviour
isMoving = false;
}
else
isMoving = true;
if(isMoving)
Move();
}
Upvotes: 11
Reputation: 5930
Methods suggested does not work in your case because you've made a class called Camera
which has exactly the same name as Unity
's Camera
component.
I would suggest you use the approach from the community wiki. It's simple enough to understand and lets you check visibility for each camera.
You can create an extension class for the Camera
component :
public static class CameraEx
{
public static bool IsObjectVisible(this UnityEngine.Camera @this, Renderer renderer)
{
return GeometryUtility.TestPlanesAABB(GeometryUtility.CalculateFrustumPlanes(@this), renderer.bounds);
}
}
The you can call that from each object separately like such :
// UnityEngine.Camera cam1;
// UnityEngine.Camera cam2;
void Update()
{
bool isVisibleForCamera1 = cam1.IsObjectVisible(GetComponent<MeshRenderer>());
bool isVisibleForCamera2 = cam2.IsObjectVisible(GetCoponent<SpriteRenderer>());
}
Here you can find whole documentation about GeometryUtility
Upvotes: 7