use*_*595 3 c# camera unity-game-engine gameobject
我正在做的事情是一个物体在平面上移动,而相机位于它的中心。我得到了它,所以相机随着鼠标旋转,当主相机看到游戏对象时,它会停止。所以我使用了 onbecamevisible() 和 onbecameinvisible() 函数,但这适用于任何相机,包括场景视图。如何使对象在仅被主游戏摄像机看到时停止?
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);
}
Run Code Online (Sandbox Code Playgroud)
}
这是我的相机脚本
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);
}
Run Code Online (Sandbox Code Playgroud)
}
球体移动
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;
}
Run Code Online (Sandbox Code Playgroud)
}
您可以使用Camera.WorldToViewport函数,使用您的主摄像机调用它并在参数中给出您正在检查的对象的位置。如果结果向量的 x 和 y 坐标值介于 0 和 1 之间,并且 z 值大于 0,则表示您的相机可以看到对象的中心。
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();
}
Run Code Online (Sandbox Code Playgroud)
建议的方法在您的情况下不起作用,因为您创建了一个名为的类,该类Camera与Unity的Camera组件名称完全相同。
我建议您使用来自社区 wiki的方法。它非常简单易懂,可让您检查每个摄像头的可见性。
您可以为Camera组件创建一个扩展类:
public static class CameraEx
{
public static bool IsObjectVisible(this UnityEngine.Camera @this, Renderer renderer)
{
return GeometryUtility.TestPlanesAABB(GeometryUtility.CalculateFrustumPlanes(@this), renderer.bounds);
}
}
Run Code Online (Sandbox Code Playgroud)
您可以像这样从每个对象分别调用它:
// UnityEngine.Camera cam1;
// UnityEngine.Camera cam2;
void Update()
{
bool isVisibleForCamera1 = cam1.IsObjectVisible(GetComponent<MeshRenderer>());
bool isVisibleForCamera2 = cam2.IsObjectVisible(GetCoponent<SpriteRenderer>());
}
Run Code Online (Sandbox Code Playgroud)
在这里你可以找到关于 GeometryUtility
| 归档时间: |
|
| 查看次数: |
15616 次 |
| 最近记录: |