2017-09-22 3 views
0

Je fais cette chose où un objet se déplace sur un plan, et la caméra est au centre de celui-ci. Je l'ai eu pour que la caméra tourne avec la souris, et quand la caméra principale voit l'objet du jeu, elle s'arrête. Donc j'utilisais les fonctions onbecamevisible() et onbecameinvisible(), mais cela s'applique à n'importe quelle caméra, y compris la vue de la scène. Comment puis-je faire en sorte que les objets s'arrêtent lorsqu'ils sont vus uniquement par la caméra de jeu principale?Unity-Comment vérifier si un objet est vu par la caméra principale

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); 
} 

}

Voici mon appareil photo 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; 
} 

}

+0

Considérez-vous que votre objet est "vu" par la caméra lorsqu'il se trouve dans la portée de la caméra ou qu'il est réellement vu à l'écran (c'est-à-dire qu'il n'est caché par aucun autre objet)? – Isuka

+0

pour l'instant, juste ce qui est à l'écran – user8048595

+0

Vous voulez faire quelque chose quand un objet est dans la vue d'une caméra, mais quelle caméra? Celui que vous avez fait une classe ou le composant Camera intégré de Unity? –

Répondre

2

Vous pouvez utiliser la fonction Camera.WorldToViewport, en utilisant votre caméra principale pour l'appeler et en donnant en paramètre la position de l'objet que vous contrôlez. Si les valeurs des coordonnées x et y du vecteur résultat sont comprises entre 0 et 1 et que la valeur z est supérieure à 0, cela signifie que le centre de votre objet est vu par votre caméra.

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(); 
} 
+0

Mais un autre objet peut bloquer la vie avec ceci et la caméra le "verra" encore – Programmer

+0

Vous avez oublié de vérifier la position 'Z':' viewPos.z> 0'. –

+0

Une erreur s'est produite, indiquant que la caméra ne contient pas de définition pour WorldToViewportPoint. – user8048595

1

Méthodes proposées ne fonctionne pas dans votre cas parce que vous avez fait une classe appelée Camera qui a exactement le même nom que le composant de CameraUnity.

Je vous suggère d'utiliser l'approche du community wiki. C'est assez simple à comprendre et vous permet de vérifier la visibilité de chaque caméra.


Vous pouvez créer une classe d'extension pour le composant Camera:

public static class CameraEx 
{ 
    public static bool IsObjectVisible(this UnityEngine.Camera @this, Renderer renderer) 
    { 
     return GeometryUtility.TestPlanesAABB(GeometryUtility.CalculateFrustumPlanes(@this), renderer.bounds); 
    } 
} 

Le vous pouvez appeler à partir de chaque objet séparément comme tel:

// UnityEngine.Camera cam1; 
// UnityEngine.Camera cam2; 

void Update() 
{ 
    bool isVisibleForCamera1 = cam1.IsObjectVisible(GetComponent<MeshRenderer>()); 
    bool isVisibleForCamera2 = cam2.IsObjectVisible(GetCoponent<SpriteRenderer>()); 
} 

Ici vous pouvez trouver toute la documentation sur GeometryUtility