如何判断一个物体是否在相机的可视范围内?哪位大佬知道方法 折腾2天时间啦 ..

  • Creator 版本:

  • 目标平台:

  • 详细报错信息,包含调用堆栈:

  • 重现方式:

  • 之前哪个版本是正常的 :

  • 手机型号 :

  • 手机浏览器 :

  • 编辑器操作系统 :

  • 编辑器之前是否有其它报错 :

  • 出现概率:

  • 额外线索:

建议开发者,文档都过一遍,用不了1天~
http://docs.cocos.com/creator/manual/zh/render/camera.html?h=getworldtocamerapoint#坐标转换

1赞

说错啦, 是屏幕坐标转化成世界坐标,就是ScreenToWorldPoint. 不是屏幕坐标转化成相机坐标。
因为需要一个接口判断一个物体是否在相机可视范围内。网上搜索到u3d的一个解决方案:
目前U3D 的方法是
“ Vector3 screenPoint = playerHead.leftCamera.WorldToViewportPoint(targetPoint.position);
bool onScreen = screenPoint.z > 0 && screenPoint.x > 0 && screenPoint.x < 1 && screenPoint.y > 0 && screenPoint.y < 1;”
目前creator 有类似的解决方案吗?

1:// 将一个世界坐标系下的点转换到摄像机坐标系下
camera.getWorldToCameraPoint(point, out);
//这个是世界坐标转化成相机坐标?

2:Camera.prototype.screenToWorld = function screenToWorld (out, screenPos, width, height)
这个是屏幕坐标转化成世界坐标?

有没有类似的方法 可以判断一个物体是否在相机可视范围内?

获取物体的世界坐标,转换成相机的本地坐标,这样应该就可以判断对象在不在相机内部了。

好的,我等会试试。谢谢

应该还是不行,
比如 首先
1: 获取一个物体的世界坐标:
var nodeparent = this.node1.parent;
var pos = this.node1.getPosition();
var worldpos = nodeparent.convertToWorldSpace(pos);

2: 把node1 的 世界坐标转化成 相机坐标
var out = cc.v3();
this.camera.getWorldToCameraPoint(worldpos, out);

现在out 就是相机的本地坐标啦吧?, 然后怎么判断out 是否在相机内? 这个怎么判断? 比较 相机的坐标点? 应该不对啊。? 大佬,有什么好方法吗?

如果你的camera位于canvas下面,且canvas没有做缩放,那么camera的大小就是canvas的大小,camera的锚点在矩形区域中心,判断out是不是在这个区域内。

我把结果演示给你看:

methodA()
{
var nodeparent = this.node1.parent;
var pos = this.node1.getPosition();

    var visible_origin = cc.view.getVisibleOrigin();
    var visibleSize = cc.view.getDesignResolutionSize();
    var camera = this.camera._camera;


    //1: 把node的局部坐标转化成世界坐标
    var worldpos = nodeparent.convertToWorldSpace(pos);
    var ar = this.node1.getAnchorPoint();
    var nodesize = this.node1.getContentSize();

    var posbl = cc.v2(worldpos.x - nodesize.width * ar.x, worldpos.y - nodesize.height * ar.y);
    var posrt = cc.v2(worldpos.y + nodesize.width * ar.x, worldpos.y + nodesize.height * ar.y);
    
    //2:把node的世界坐标转化到相机坐标系下的坐标
    var out = cc.v2();
    this.camera.getWorldToCameraPoint(posrt, out);

    //相机坐标
    var camepos = this.node.getPosition();
    //log("out:" + out.toString() + " camepos" + camepos.toString());

    //假如相机位于屏幕的中心点, 如果相机的坐标位置超过 node的右边界
    if(camepos.x >= (out.x + cc.visibleRect.width/2))
    {
        cc.log("pass!!");
    }
},

测试结果:那个粉红色的图片 过去一半,就说pass啦? 这个结果肯定不对。目前相机节点 是每帧 向右走5个像素。

这是完整代码:

methodA()
{
    var nodeparent = this.node1.parent;
    var pos = this.node1.getPosition();

    var visible_origin = cc.view.getVisibleOrigin();
    var visibleSize = cc.view.getDesignResolutionSize();
    var camera = this.camera._camera;


    //1: 把node的局部坐标转化成世界坐标
    var worldpos = nodeparent.convertToWorldSpace(pos);
    var ar = this.node1.getAnchorPoint();
    var nodesize = this.node1.getContentSize();

    var posbl = cc.v2(worldpos.x - nodesize.width * ar.x, worldpos.y - nodesize.height * ar.y);
    var posrt = cc.v2(worldpos.y + nodesize.width * ar.x, worldpos.y + nodesize.height * ar.y);
    
    //2:把node的世界坐标转化到相机坐标系下的坐标
    var out = cc.v2();
    this.camera.getWorldToCameraPoint(posrt, out);

    //相机坐标
    var camepos = this.node.getPosition();
    //log("out:" + out.toString() + " camepos" + camepos.toString());

    //假如相机位于屏幕的中心点, 如果相机的坐标位置超过 node的右边界
    if(camepos.x >= (out.x + cc.visibleRect.width/2))
    {
        cc.log("pass!!");
    }
},



lateUpdate : function(dt)
{
    //cc.log("node name:" + this.node.name);
    this.node.x += 5.0;
    this.methodA();
}

跟camepos.x没关系,你都把节点转换到camera的坐标系下面了。

那怎么判断?是否可以这样。把屏幕2个点
let origin = cc.view.getVisibleOrigin();
let topright = origin + cc.v2(cc.visibleRect.width, cc.visibleRect.height);
把这2个也通过接口 getWorldToCameraPoint 转化成 相机内坐标。
然后比较 node 的相机内坐标 是否在 (origin topright)组成的一个rect里面? 这样是否可行?

就是node 转化到相机坐标系后,我不知道怎么判断这个node 是否在相机的可视范围内。目前相机一直是向后移动的。

var out_view_orign = cc.v2();
this.camera.getWorldToCameraPoint(origin, out_view_orign);

    var out_view_tr = cc.v2();
    var view_tr = cc.v2(origin.x + visibleSize.width, origin + visibleSize.y);
    this.camera.getWorldToCameraPoint(out_view_tr, view_tr);
    
    var rect = cc.rect(
        out_view_orign.x, 
        out_view_orign.y, 
        out_view_tr.x - out_view_orign.x, 
        out_view_tr.y - out_view_orign.y);

    cc.log("out_node:" + out_node.toString() + "out_view_orign:" + out_view_orign.toString());
    if(out_node.x < out_view_orign.x)
    {
        cc.log("pass left!!");
    }

我这样做也不行。

貌似解决了,只要第一次获取view orign的相机坐标就可以,然后一直比较 node 相机坐标。不过这种方法好像不好。最好有通用的方法。

我搞定啦。。

请问如何解决的

请问是怎么解决的,能分享下吗?