Creator射线检测 | 模拟选中
射线检测官方文档
射线检测的用途有很多,捡物品,射击都需要用到射线检测
官方给出三种常见的构建射线的方法
我们使用第三种方法
思路:通过相机和点击屏幕得到的触点构造一条射线,检测所有的碰撞盒,并记录与射线距离最短的检测结果,给检测结果设置描边材质
节点层级
新建一个空节点取名Game,创建一个平面当地面,再创建一堆模型
一定要给每个模型加上碰撞体,射线只会检测有碰撞体的节点
再撸一个canvas和label出来,直接创建一个label,会自动创建canvas
再新建两个材质,一个不用动当默认材质,另一个换成卡通Effect,设置好描边颜色和粗细
需要用到的属性
@property({displayName: "3D相机", type: CameraComponent})
camera: CameraComponent = null!;
@property({displayName: "文字", tooltip: "文字", type: LabelComponent})
label: LabelComponent = null!;
@property({displayName: "描边材质", tooltip: "描边材质", type: Material})
outline: Material = null!;
@property({displayName: "默认材质", tooltip: "默认材质", type: Material})
default: Material = null!;
// 上一个选中的结果
last: MeshRenderer = null!;
在onLoad添加触摸事件,获取触点并构造射线
onLoad () {
this.label.string = "请点击屏幕";
systemEvent.on(SystemEventType.TOUCH_START, (e: Touch) => {
// 获取触摸点并且创建射线
let pos = e.getLocation();
let ray = this.camera.screenPointToRay(pos.x, pos.y);
// 传入射线
this.get_result(ray);
}, this);
}
封装了一个方法,传入一条射线,检测所有的碰撞盒,并记录与射线距离最短的检测结果。有结果就将检测结果设置描边材质,将上次的检测结果设置默认材质。没结果直接设置上次检测结果为默认材质。并根据不同的情况设置文字的显示内容
get_result (ray: geometry.Ray) {
// 如果选中了节点
if (PhysicsSystem.instance.raycastClosest(ray) == true) {
// 获取射线最短的检测结果
var node = PhysicsSystem.instance.raycastClosestResult;
// 获取名字
let name = node.collider.name;
// 根据不同的名字进行不同的判断
if (name == "Cylinder<CylinderCollider>") {
this.label.string = "点击到了物体:圆柱";
} else if (name == "Cube<BoxCollider>") {
this.label.string = "点击到了物体:立方体";
} else if (name == "Capsule<CapsuleCollider>") {
this.label.string = "点击到了物体:胶囊";
} else if (name == "Cone<ConeCollider>") {
this.label.string = "点击到了物体:圆锥";
} else if (name == "Sphere<SphereCollider>") {
this.label.string = "点击到了物体:球";
} else if (name == "Torus<MeshCollider>") {
this.label.string = "点击到了物体:圆环";
} else {
this.label.string = "点击到了物体:" + node.collider.name;
}
// 设置检测结果的材质为红色描边
node.collider.node.getComponent(MeshRenderer)!.material = this.outline;
// 如果不是第一次选中并本次选中和上次不同
if (this.last != null && node.collider.node.getComponent(MeshRenderer) != this.last) {
// 设置为默认材质
this.last.material = this.default;
}
// 设置上次选中的结果
this.last = node.collider.node.getComponent(MeshRenderer)!;
} else {
// 没选中任何物体设置上次选中结果材质为默认
this.label.string = "没点到任何物体";
if (this.last != null) {
this.last.material = this.default;
}
}
}
绑定好节点就可以了
源码:https://gitee.com/propertygame/cocos-creator3.x-demos/tree/master/RaySelected
技术交流Q群:1130122408
更多内容请关注微信公众号