核心要點: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*/); } }); } }