1. 程式人生 > >cocos 射線檢測 3D物體 (Sprite3D點擊)

cocos 射線檢測 3D物體 (Sprite3D點擊)

get director 轉化 cocos hello dir 調用 true 得到

看了很多朋友問怎麽用一個3D物體做一個按鈕,而且網上好像還真比較難找到答案, 今天翻了一下cocos源碼發現Ray 已經封裝了intersects函數,那麽剩下的工作其實很簡單了, 從屏幕的一個point 轉化為 一條射線, 然後從一個3D物體拿到碰撞盒後調用intersects 就可以了。

void HelloWorld::onEnter(){
    Scene::onEnter();
    
    //添加一只3D的烏龜在場景, 作為一個按鈕
    auto orc = cocos2d::Sprite3D::create("tortoise.c3b");
    orc->setScale(0.05);
    orc->setPositionNormalized(Vec2(.5f,.3f));
    //orc->setPositionZ(40);
    orc->setRotation3D(Vec3(0,180,0));
    orc->setPosition3D(Vec3(-100, 0, -140));
    orc->setGlobalZOrder(-1);
    this->addChild(orc);
    
    
    auto listener1 = EventListenerTouchOneByOne::create();//創建一個觸摸監聽
    listener1->setSwallowTouches(true);//設置是否想下傳遞觸摸
    cocos2d::EventListenerTouchOneByOne::ccTouchBeganCallback ccTouchCallback = [this, orc] (Touch* touch, Event* event)->bool{
        auto point = touch->getLocation();
        
        
        //窗口大小
        auto winSize = Director::getInstance()->getWinSize();
        auto camera = this->getDefaultCamera();
        if(nullptr == camera){
            return false;
        }
        
        auto nearP = Vec3(point.x, point.y, 0.0f);//近平面
        auto farP = Vec3(point.x, point.y, 1.0f);//遠平面
        
        camera->unprojectGL(winSize, &nearP, &nearP);//反投影
        camera->unprojectGL(winSize, &farP, &farP);
        
        auto dir = farP - nearP;//得到射線方向
        dir.normalize();//歸一化向量
        auto ray = Ray(nearP, dir);//從近平面射出的一條射線
        
        auto aabb = orc->getAABB();//獲取3D物體的AABB碰撞盒
        if(ray.intersects(aabb)){//射線是否命中該包圍盒
            CCLOG("on hit!!!!");
        }
        
        
        return false;
    };
    
    listener1->onTouchBegan = ccTouchCallback;
    
    this->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener1, this);

    
    
}

  (我的博客:http://www.cnblogs.com/CodeerHome/)

cocos 射線檢測 3D物體 (Sprite3D點擊)