Laya商业级教程3d实战_012碰撞检测

Laya商业级教程,laya教程
本节目标:碰撞障碍物

laya商业级3d游戏开发

相交检测有很多方案,laya有内置的物理引擎,或者其他第三方类库

Laya内置物理引擎,刚体数量多时,苹果机上流畅度会比较低

在这里插入图片描述

性能和包体是非常重要的指标
分别决定了流畅度和加载速度,游戏包体越小,用户首次加载留存率就越高

考虑到性能和包体以及案例的实际需求原因

框架集成了最简单的3d碰撞模块

aabb VS aabb对称包围盒相交检测
在这里插入图片描述

碰撞检测模块源码在3Dphysics目录下

在这里插入图片描述

有unity的配套工具,方便碰撞器的序列和反序列化
在这里插入图片描述

给角色添加碰撞器

在catBase添加aabb shape组件 调节好边界
在这里插入图片描述
在这里插入图片描述

输出信息到黏贴版本
//center (0.0, 0.6, 0.0) size (0.6, 1.2, 0.3)

在onAwake给角色添加碰撞器
onAwake() {
super.onAwake();

this.animator = this.gameObject.getChildByName('CatBase').getComponent(Laya.Animator);
this.animator.play('Cat_RunLong');

//碰撞器章节讲解内容
let aabbshape: AABBShape = new AABBShape();
aabbshape.mask = CollisionMask.Character;
//位运算,表示碰撞器和 障碍物和鱼产生碰撞
aabbshape.collisionMask = 1 << CollisionMask.Obstacle | 1 << CollisionMask.Fish;
//center (0.0, 0.6, 0.0)  size (0.6, 1.2, 0.3)
aabbshape.size = new Laya.Vector3(0.6, 1.2, 0.3)
aabbshape.center = new Laya.Vector3(0.0, 0.6, 0.0);

this.gameObject.addComponentIntance(aabbshape);
//考虑到性能原因,开启主动检测的对象才会进行遍历检测
//{a,b,c,......} a.ActiveDetec()
// detect(a ,b) 
// detect(a ,c) 
//........

//{a,b,c,......} a.ActiveDetec(); b.ActiveDetec()
// detect(a ,b) 
// detect(a ,c) 
//detect(b ,a) 
//detect(b ,c) 

aabbshape.ActiveDetec();
//碰撞进入
aabbshape.RegisetCollsionEnter(this, this.OnCollisionEnter)
//碰撞离开

// aabbshape.RegisetCollsionExit(this, this.OnCollisionExit)

}

OnCollisionEnter(source: AABBShape, target: AABBShape) {

console.log('OnCollisionEnter', target.mask);

if (target.mask == CollisionMask.Fish) {
  target.gameObject.active = false;
  GameSample.soundMgr.FishCollection.Play();
}
else if (target.mask == CollisionMask.Obstacle)//障碍物
{
  this.Fail();
  let obstalcle = Game.instance.obstacleSpawn.itemMap.getNumberKey(target.gameObject.id)
  obstalcle.ani.play('death');
  obstalcle.collider.enabled = false;
}

}

Fail() {

Game.instance.speed = 0
this.animator.play('Cat_Death')

}

Reborn(){}

鱼添加碰撞器和逻辑
FishSpwan.ts

添加
//碰撞器教程讲解
protected CreateSpwanItem(spwanItemData: SpwanItemData): SpawnItem {
let item = super.CreateSpwanItem(spwanItemData);
let newgo = item.gob;
let boxCollider = new AABBShape()
boxCollider.mask = CollisionMask.Fish;
boxCollider.collisionMask = 0;
boxCollider.size = new Laya.Vector3(1, 1, 0.34);
boxCollider.center = new Laya.Vector3(0, 0, 0);
newgo.addComponentIntance(boxCollider);

    return item;
}

在这里插入图片描述

障碍物添加碰撞器
在这里插入图片描述

ObstacleSpawn.ts

//重载CreateSpwanItem
protected CreateSpwanItem(spwanItemData: SpwanItemData): SpawnItem {

    let spwanitem = super.CreateSpwanItem(spwanItemData)
    let newgo = spwanitem.gob;

    //碰撞器的添加
    let boxCollider = new AABBShape()
    //center (0.0, 0.7, 0.0)  size (1.5, 1.4, 0.6)
    boxCollider.mask = CollisionMask.Obstacle;
    boxCollider.collisionMask = 0;

    boxCollider.center = new Laya.Vector3(0.0, 0.7, 0.0)
    boxCollider.size = new Laya.Vector3(1.5, 1.4, 0.6)

    let collidergob = newgo as Laya.Sprite3D;
    collidergob.addComponentIntance(boxCollider);

    let obstacle = new Obstacle();
    obstacle.ani = newgo.getChildAt(0).getComponent(Laya.Animator) as Laya.Animator;
    obstacle.collider = boxCollider;

    this.itemMap.add(newgo.id, obstacle)

    return spwanitem;
}

//障碍物模型
export class Obstacle {
ani: Laya.Animator;
//碰撞系统章节会用到
collider: AABBShape;
}

添加
protected onSpawn(newGo: Laya.Sprite3D, spwanItemData: SpwanItemData, z)

//重新激活碰撞器
obstacle.collider.enabled=true;

Game.ts
Onawake

… //碰撞检测模块
this.scene.addComponent(CollsionManagerThreeD);
// this.addfishCollider();

验证碰撞器是否成功添加
打开全局设定,开启显示碰撞器

在这里插入图片描述

F8 f5
在这里插入图片描述

角色碰撞到障碍物后睡觉

在这里插入图片描述

自定义碰撞模块哪些是需要知道的?
因为采用了位运算表示碰撞器之间的碰撞种类检测,
所以有新物体增加时CollisionMask会常常也需要同步增加

//因为考虑到性能原因,只有开启了自动检测的对象才会进行检测
//以下为表里有3个对象,1个对象开启检测,需要进行2此运算
//2个对象开启检测,需要进行4此运算
//{a,b,c,…} a.ActiveDetec()
// detect(a ,b)
// detect(a ,c)
//…

//{a,b,c,…} a.ActiveDetec(); b.ActiveDetec()
// detect(a ,b)
// detect(a ,c)
//detect(b ,a)
//detect(b ,c)

碰撞管理器CollsionManagerThreeD.ts
onLateUpdate() {
if (GameDesgin.enableCollsion) {
if (this.detectObjs.length >= 1) {
for (let i = 0; i < this.detectObjs.length; i++) {

                let detectAABB = this.detectObjs[i] as AABBShape;
                this.GetFilterZItems(this.detectObjs[i].transform.position.z, detectAABB);

                this.Detect(detectAABB, detectAABB.moveSpeed);
            }
        }
    }

}

//进行粗略检测
//结合案例,主角前面30米之内的对象才进行检测
//大多数物理引擎采用的是二叉树,,四叉树,八叉树,进行粗略检测
this.GetFilterZItems(this.detectObjs[i].transform.position.z, detectAABB);

在这里插入图片描述

游戏开发,unity3d,laya,游戏开发,unity3d,laya,游戏开发,unity3d,laya,游戏开发,unity3d,laya,游戏开发,unity3d,laya,游戏开发,unity3d,laya,游戏开发,unity3d,laya,游戏开发,unity3d,laya,游戏开发,unity3d,laya,游戏开发,unity3d,laya,游戏开发,unity3d,laya

猜你喜欢

转载自blog.csdn.net/koljy111/article/details/108020241