unity判断范围内有物体_Laya 判断3D物体是否在摄像机范围内

背景:依稀记得,Laya引擎版本2.3之后,3D物体对象属性的meshRender 就不暴露【_visible】属性,好像也找不到其他属性代替这个【不满足开发需求~】,至于为啥?

c0e6ae124b9f27731c0839f61d52957f.png

备菜环节【此改动是基于JS创建的3D示例项目,暂无TS跟AS版】:

1:导出一个结尾文件为【.ls】格式的、简陋的、落落大方的unity场景文件

为了体现区别,我先将两个3D物体移出摄像头范围内:啊【red】跟啊【blue】

73c2de7ac51798f2bd5da6f66c8de9c0.png

导出场景文件就不介绍了~( 略 * 3 )

2: 【LayaAir IDE 2.8.0beta】 创建【3D示例项目】--> 构建UI --> 绑定场景runTime脚本

本来想图文并茂的,但是这些都不是重点,所以

4c45a30a1b00201bf4071e6759b9e78b.png
来自路人甲的心理活动

laya场景编译运行效果图如下

cd4ad8eeff685d3ae436e4d6c2bb90b5.png

重点

找到 bin/libs/laya.d3.js 文件,搜字眼:static _traversalCulling ,(大概在11747行)

static _traversalCulling(cameraCullInfo, scene, context, renderList, customShader, replacementTag, isShadowCasterCull) {
	var renders = renderList.elements;
	var boundFrustum = cameraCullInfo.boundFrustum;
	var camPos = cameraCullInfo.position;
	var cullMask = cameraCullInfo.cullingMask;
	var loopCount = Laya.Stat.loopCount;
	for (var i = 0, n = renderList.length; i < n; i++) {
		var render = renders[i];
		var canPass;
		if (isShadowCasterCull)
			canPass = render._castShadow && render._enable;
		else
			canPass = ((Math.pow(2, render._owner._layer) & cullMask) != 0) && render._enable;
		if (canPass) {
			Laya.Stat.frustumCulling++;
			if (!cameraCullInfo.useOcclusionCulling || render._needRender(boundFrustum, context)) {
				render._renderMark = loopCount;
				render._distanceForSort = Vector3.distance(render.bounds.getCenter(), camPos);
				var elements = render._renderElements;
				for (var j = 0, m = elements.length; j < m; j++)
					elements[j]._update(scene, context, customShader, replacementTag);
			}
		}
	}
}

在这个代码块里面添加【_visible】属性;

02261e30acbb7e25e868bca86856dd51.png
static _traversalCulling(cameraCullInfo, scene, context, renderList, customShader, replacementTag, isShadowCasterCull) {
	var renders = renderList.elements;
	var boundFrustum = cameraCullInfo.boundFrustum;
	var camPos = cameraCullInfo.position;
	var cullMask = cameraCullInfo.cullingMask;
	var loopCount = Laya.Stat.loopCount;
	for (var i = 0, n = renderList.length; i < n; i++) {
		var render = renders[i];
		var canPass;
		if (isShadowCasterCull)
			canPass = render._castShadow && render._enable;
		else
			canPass = ((Math.pow(2, render._owner._layer) & cullMask) != 0) && render._enable;
		if (canPass) {
			Laya.Stat.frustumCulling++;
			if (!cameraCullInfo.useOcclusionCulling || render._needRender(boundFrustum, context)) {
				render._renderMark = loopCount;
				render._visible = true;
				render._distanceForSort = Vector3.distance(render.bounds.getCenter(), camPos);
				var elements = render._renderElements;
				for (var j = 0, m = elements.length; j < m; j++)
					elements[j]._update(scene, context, customShader, replacementTag);
			}else{
				render._visible = false;
			}
		}else{
			render._visible = false;
		}
	}
}

然后保存,编译运行,实时输出3D物体是否在摄像机视野范围内的真假状态

附上场景UI截图 与 测试代码:

e80ba59e3a43ad9239b3ee1ea9e01ab7.png
export default class Main01 extends Laya.Scene {
    constructor() {
        super()
        Main01.instance = this;
    }
    onAwake() {
        //  获取UI根文件
        this.root = Laya.stage.getChildByName("root");
    }
    /**
     * 测试物体是否在摄像机范围内
     */
    onOpened() {
        let _this = this;
        Laya.loader.create(["scenes/LayaScene_Main/Conventional/Main.ls"], Laya.Handler.create(this, function () {
            _this.Main = Laya.loader.getRes("scenes/LayaScene_Main/Conventional/Main.ls");
            _this.Main.name = "Main";
            _this.camera = this.Main.getChildByName("Main Camera");
            _this.camera.addComponent(CameraMoveScript);
            Laya.stage.addChild(_this.Main);
            Laya.timer.loop(1, this, function () {
                console.log("【")
                console.log("white is visible:", _this.Main.getChildByName("white").meshRenderer._visible)
                console.log("pick is visible:", _this.Main.getChildByName("pick").meshRenderer._visible)
                console.log("blue is visible:", _this.Main.getChildByName("blue").meshRenderer._visible)
                console.log("red is visible:", _this.Main.getChildByName("red").meshRenderer._visible)
                console.log("】")
                _this.tips.text =
                    "【white:" + _this.Main.getChildByName("white").meshRenderer._visible+ "】" +
                    "【pick:" + _this.Main.getChildByName("pick").meshRenderer._visible+ "】" +
                    "【blue:" + _this.Main.getChildByName("blue").meshRenderer._visible+ "】" +
                    "【red:" + _this.Main.getChildByName("red").meshRenderer._visible + "】"
            })
            // 确保UI层级比三维场景层级高
            _this.root.zOrder = _this.Main.zOrder + 1
        }))
    }

}

最后,附上测试结果图:

e65ef7b8ef03a249f593450c23225e70.png

ec1587b718419ad9aa786de093192748.png

f2a453f31f22d1cba1356873116f24f4.png

a99b7266c81aa7820d3f73680210509e.png

================>>>>>>>>>>>>>>>>>>>> 终。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值