看了很多朋友问怎么用一个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/)