版本号:3.4.1
原理
创建2dui卡片
2dui卡片上绑定脚本(card)
card脚本上绑定要放置的物体
通过触摸2d的ui卡片,监听TOUCH_MOVE事件,获得当前触摸的卡片,可触摸位置
通过事件分发,发送当前触摸位置和本卡片的放置物体
触摸结束时,分发结束事件
创建逻辑处理脚本
脚本上绑定摄像机和当前地板
接收card发送的事件
如果没有放置物体对象,则克隆收到的放置物体,赋值给放置物体对象,添加到地板上
通过收到的触摸位置生成射线,获取当前和地板相交的坐标,赋值给克隆出来的物体,让物体随着每次坐标的变化而变化
收到结束事件时,清空脚本上绑定的放置物体对象
import { _decorator, Component, Node, Button, EventTouch, v3, input, Input } from 'cc';
const { ccclass, property } = _decorator;
import MyEvent from './MyEvent'
/**
* Predefined variables
* Name = card
* DateTime = Tue Mar 01 2022 01:04:59 GMT+0800 (中国标准时间)
* Author = qiuhe
* FileBasename = card.ts
* FileBasenameNoExtension = card
* URL = db://assets/script/addDW.ts
* ManualUrl = https://docs.cocos.com/creator/3.4/manual/zh/
*
*/
@ccclass('card')
export class card extends Component {
// [1]
// dummy = '';
// [2]
// @property
// serializableDummy = 0;
@property({type:Node,displayName:"放置的动物"})
public targetNode!: Node
start () {
// [3]
this.node.on(Node.EventType.TOUCH_MOVE, this.onTouchMove, this);
this.node.on(Node.EventType.TOUCH_CANCEL,this.onTouchEnd,this)
this.node.on(Node.EventType.TOUCH_END,this.onTouchEnd,this)
}
onDestroy(){
this.node.off(Node.EventType.TOUCH_MOVE, this.onTouchMove, this);
this.node.off(Node.EventType.TOUCH_CANCEL,this.onTouchEnd,this)
this.node.off(Node.EventType.TOUCH_END,this.onTouchEnd,this)
}
// update (deltaTime: number) {
// // [4]
// }
onTouchMove(event: EventTouch) {
const touch = event.touch!;
// console.log(`要放置的节点是:${this.targetNode.name}`)
this.node.setScale(v3(0.8,0.8,1))
this.node.dispatchEvent( new MyEvent('moveCard', true, {
touch,targetNode:this.targetNode
}) );
}
onTouchEnd(event: EventTouch) {
const touch = event.touch!;
// console.log(`要放置的节点是:${this.targetNode.name}`)
this.node.setScale(v3(1,1,1))
console.log("发送事件")
this.node.dispatchEvent( new MyEvent('endCard', true, {
touch
}) );
}
}
/**
* [1] Class member could be defined like this.
* [2] Use `property` decorator if your want the member to be serializable.
* [3] Your initialization goes here.
* [4] Your update function goes here.
*
* Learn more about scripting: https://docs.cocos.com/creator/3.4/manual/zh/scripting/
* Learn more about CCClass: https://docs.cocos.com/creator/3.4/manual/zh/scripting/decorator.html
* Learn more about life-cycle callbacks: https://docs.cocos.com/creator/3.4/manual/zh/scripting/life-cycle-callbacks.html
*/
import { _decorator, Component, Node, Camera, geometry, input, Input, EventTouch, PhysicsSystem, v3, math, Vec3, director, instantiate } from 'cc';
import MyEvent from './MyEvent'
const { ccclass, property } = _decorator;
@ccclass("Example")
export class Example extends Component {
// Specify the camera rendering the target node.
@property(Camera)
readonly cameraCom!: Camera;
@property(Node)
public targetNode!: Node
private _ray: geometry.Ray = new geometry.Ray();
private card_targetNode:Node
onEnable() {
console.log("初始化事件")
this.node.on('moveCard', (event: MyEvent) => {
event.propagationStopped = true;
if(!this.card_targetNode){
this.card_targetNode=instantiate(event.detail.targetNode);
this.card_targetNode.parent = event.detail.targetNode.parent;
}
if(!this.card_targetNode){
return
}
this.onTouchMove(event.detail)
});
this.node.on('endCard', (event: MyEvent) => {
event.propagationStopped = true;
this.card_targetNode=null
});
}
onTouchMove(event: EventTouch) {
const touch = event.touch!;
this.cameraCom.screenPointToRay(touch.getLocationX(), touch.getLocationY(), this._ray);
if (PhysicsSystem.instance.raycast(this._ray)) {
const raycastResults = PhysicsSystem.instance.raycastResults;
for (let i = 0; i < raycastResults.length; i++) {
const item = raycastResults[i];
if (item.collider.node == this.targetNode) {
this.card_targetNode.setPosition(new Vec3(item.hitPoint.x,this.card_targetNode.getPosition().y,item.hitPoint.z))
break;
}
}
} else {
console.log('raycast does not hit the target node !');
}
}
}
// Event 由 cc 模块导入
import { Event } from 'cc';
class MyEvent extends Event {
constructor(name: string, bubbles?: boolean, detail?: any) {
super(name, bubbles);
this.detail = detail;
}
public detail: any = null; // 自定义的属性
}
export default MyEvent