unity3d - 如何添加额外的相机,以便在我使用电影相机时使用脚本 onBecomeInvisible() 的对象不会被破坏?
问题描述
我认为我的标题很明显。由于统一的 onbecomeinv 功能,我有一些对象设置在它们不可见时被破坏。我正在使用电影中的虚拟相机/二维相机,所以现在不可见的物体正在被破坏,他们不应该这样做吗?我怎样才能做到这一点?
解决方案
第一个普遍的“问题”OnBecameVisible
是OnBecameInvisible
它是基于渲染的。这意味着即使一个对象已经离开了相机视图,它也有可能仍然与渲染相关(例如投掷阴影),因此可能并不总是像预期的那样表现。
其次,无法确切知道对象在哪个相机上变得(不)可见,而是意味着它对于场景中的(所有/)任何现有相机变得(不)可见。
您可以(大约)通过GeometryUtility.CalculateFrustumPlanes
与GeometryUtility.TestPlanesAABB
[SerializeField] private Renderer _renderer;
[SerializeField] private Camera _camera;
private void Awake ()
{
if(!_camera) _camera = Camera.main;
if(!_renderer) _renderer = GetComponent<Renderer>();
}
private void Update ()
{
var planes = GeometryUtility.CalculateFrustumPlanes(_camera);
if (!GeometryUtility.TestPlanesAABB(planes, _renderer.bounds))
{
Debug.Log($"{name} is outside of {_camera.name}'s camera frustum!", this);
Destroy(gameObject);
}
}
当然,这种方法可以通过不让每个对象独立计算,而是使用通用控制器来改进。
在您的对象/预制件上有一个类
// Keeps track of existing instances of this component
// Provides a cached reference to the Renderer component
public class CheckVisibilityTarget : MonoBehaviour
{
// Each instances will (un)register itself here
private static readonly HashSet<CheckVisibilityTarget> _instances = new HashSet<CheckVisibilityTarget>();
// public readonly access to all existing instances of this component
// returns a copy of _instances
public static HashSet<CheckVisibilityTarget> Instances => new HashSet<CheckVisibilityTarget>(_instances);
// Reference this already in the Inspector
[SerializeField] private Renderer _renderer;
// public readonly access
public Renderer Renderer => _renderer;
private void Awake ()
{
// As fallback get it once on runtime
if(!_renderer) _renderer = GetComponent<Renderer>();
// Add yourself to the instances
_instances.Add(this);
}
private void OnDestroy ()
{
// remove yourself from the instances
_instances.Remove(this);
}
}
然后如您所说的场景中的中央控制器
public class DestroyInvisibleTargets : MonoBehaviour
{
// Reference this via the Inspector
[SerializeField] private Camera _camera;
private void Awake ()
{
// As fallback get it once on runtime
if(!_camera) _camera = Camera.main;
}
private void Update ()
{
// Get the planes once per frame
var planes = GeometryUtility.CalculateFrustumPlanes(_camera);
// Check all existing instances whether they are still within the frustum
foreach(var target in CheckVisibilityTarget.Instances)
{
if (!GeometryUtility.TestPlanesAABB(planes, target.Renderer.bounds))
{
Debug.Log($"{target.name} is outside of {_camera.name}'s camera frustum!", this);
Destroy(target.gameObject);
}
}
}
}
推荐阅读
- jquery - jQuery从ajax加载的内容替换字符串
- php - php和ajax传递日期strtotime转换不同
- rest - 使用 ADF REST API 的 RESTful Web 服务无法获取超过 500 条记录
- sql - BigQuery:如何简化此 SQL
- php - 使用 PHP 从 mySQL 导出数据
- python-3.x - PyTorch 已安装但未导入
- reactjs - 由顶级 BrowserRouter 调用的组件内部的 BrowserRouter 与 NavLinks 不同步
- javascript - 构建捆绑包:构建捆绑包文件时出错->文件'root/res/drawable/sr_list_item_background.xml'使用保留文件或目录名称'res'
- r - Data Wrangling - R - 想要删除在 fyweek 和 launchweek 之间对应的行
- r - r dplyr 文本挖掘 eval(rhs,env,env)中的错误:找不到对象'score'