欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Layabox 3D游戏开发学习笔记---射线检测,鼠标控制物体运动

程序员文章站 2022-06-29 12:42:45
核心要点:3D物体碰撞是靠射线检测,射线与碰撞器相撞获取对应的碰撞点信息。 ......

核心要点:3d物体碰撞是靠射线检测,射线与碰撞器相撞获取对应的碰撞点信息。

class raypicking03 {
    private ray: laya.ray;
    private point: laya.vector2 = new laya.vector2();
    private _outhitinfo: laya.raycasthit;
    private _position: laya.vector3;
    private _upvector3: laya.vector3;
    private _vector3: laya.vector3;
    private _offsetvector3: laya.vector3;
    private box: laya.meshsprite3d;
    private _rotatev3:laya.vector3;
    private camera: laya.camera;
    private label: laya.label;
    constructor() {
        laya3d.init(0, 0, true);//初始化3d
        laya.stage.scalemode = "full";//屏幕缩放方式
        laya.stage.screenmode = "none";
        laya.stat.show();

        var scene: laya.scene = laya.stage.addchild(new laya.scene()) as laya.scene;//添加场景

        this.point = new laya.vector2();//位置信息
        this.ray = new laya.ray(new laya.vector3(0, 0, 0), new laya.vector3(0, 0, 0));//初始化射线
        this._outhitinfo = new laya.raycasthit();//初始化射线信息
        this._position = new laya.vector3(0, 0.25, 0);//位置
        this._upvector3 = new laya.vector3(0, 1, 0);
        this._rotatev3 = new laya.vector3(1, 0, 1);
        this._vector3 = new laya.vector3();
        this._offsetvector3 = new laya.vector3(0, 0.15, 0)

        //初始化照相机
        this.camera = scene.addchild(new laya.camera(0, 0.1, 100)) as laya.camera;
        this.camera.transform.translate(new laya.vector3(0, 2, 5));
        this.camera.transform.rotate(new laya.vector3(-15, 0, 0), true, false);
        this.camera.clearcolor = null;

        //方向光
        var directionlight: laya.directionlight = scene.addchild(new laya.directionlight()) as laya.directionlight;
        directionlight.color = new laya.vector3(0.6, 0.6, 0.6);
        directionlight.direction = new laya.vector3(1, -1, -1);

        var plane: laya.meshsprite3d = scene.addchild(new laya.meshsprite3d(new laya.planemesh(6, 6, 10, 10))) as laya.meshsprite3d;//创建平面物体
        var planemat: laya.standardmaterial = new laya.standardmaterial();//标准材质
        planemat.diffusetexture = laya.texture2d.load("../bin/res/layabox.png");//添加材质
        planemat.albedo = new laya.vector4(0.9, 0.9, 0.9, 1);
        plane.meshrender.material = planemat;

        var meshcollider = plane.addcomponent(laya.meshcollider) as laya.meshcollider;//网格碰撞器
        meshcollider.mesh = plane.meshfilter.sharedmesh;//网格过滤器,获取共享网格

        this.box = scene.addchild(new laya.meshsprite3d(new laya.spheremesh(0.2, 8, 8))) as laya.meshsprite3d;//创建立方体
        var mat: laya.standardmaterial = new laya.standardmaterial();
        mat.diffusetexture = laya.texture2d.load("../bin/res/layabox.png");
        this.box.meshrender.material = mat;

        laya.timer.frameloop(1, this, this.checkhit);

        this.loadui();
    }
    private checkhit(): void {
        this.box.transform.position = this._position;
        //this.box.transform.rotate(this._rotatev3, true, false)
        //从屏幕空间生成射线
        this.point.elements[0] = laya.mousemanager.instance.mousex;//鼠标x坐标
        this.point.elements[1] = laya.mousemanager.instance.mousey;//鼠标y坐标
        this.camera.viewportpointtoray(this.point, this.ray);//从摄像机到鼠标点击位置生成射线
        laya.physics.raycast(this.ray, this._outhitinfo, 30, 0);//生成射线
    }

    private loadui(): void {

        this.label = new laya.label();
        this.label.text = "点击移动";
        this.label.pos(laya.browser.clientwidth / 2.5, 100);
        this.label.fontsize = 50;
        this.label.color = "#40ff40";
        laya.stage.addchild(this.label);

        //鼠标事件
        laya.stage.on(laya.event.mouse_up, this, function (): void {
            if (this._outhitinfo.distance !== -1) {
                laya.vector3.add(this._outhitinfo.position, this._offsetvector3, this._vector3);
                laya.tween.to(this._position, { x: this._vector3.x, y: this._vector3.y, z: this._vector3.z }, 500/**,ease.circin*/);
            }
        });
    }
}