[开发者心得] 【射线检测】😍各种检测,助你快速实现射击类游戏功能

[复制链接]
2484 |0
空伊伊 发表于 2023-2-19 18:21:10 | 显示全部楼层 |阅读模式

本帖最后由 空伊伊 于 2023-11-8 18:10 编辑

话不多说,先看效果!

朝屏幕中心点发射一条射线,并在射击点创建一个特效,同时生成一个气球往垂直于射击点的方向飞行

<video controls src="https://forum.ark.online/forum.php?mod=attachment&aid=MzYwfDliMzJhZmExfDE2OTY5MDUwNjl8MTEzfDExMzg%3D&noupdate=yes"></video>

实现代码

@Component
export default class Line extends Script {

    /** 当脚本被实例后,会在第一帧更新前调用此函数 */
    protected onStart(): void {
        this.useUpdate = true
        if (SystemUtil.isClient()) {
            // 按下G键,开始射击
            InputUtil.onKeyDown(Keys.G, () => {
                this.shoot()
            })
        }
    }

    /**向屏幕中心点发射一条射线 */
    public async shoot() {
        // 获取角色
        let character = (await Player.asyncGetLocalPlayer()).character
        // 射线起点为角色头顶往上200的位置
        let startLoc = character.worldTransform.position.clone()
        startLoc.z += 200
        // 获取从起点到屏幕中心点的方向
        let aimDir = getShootDir(character, startLoc, 2000);
        // 根据起点和方向算出终点位置
        let endLoc = startLoc.clone().add(aimDir.multiply(2000));
        // 发射一条射线
        let hitInfo = QueryUtil.lineTrace(startLoc, endLoc, false, true);
        if (hitInfo.length > 0) {
            for (let hitResult of hitInfo) {
                // 在碰撞发生的接触点播放一次特效
                EffectService.playAtPosition("13595", hitResult.impactPoint)
                // 调用自定义的函数,传入接触点和接触点的法线,实现气球飞行的效果
                this.objFly(hitResult.impactPoint, hitResult.impactNormal)
            }
        }
    }

    /**让物体从startLoc朝着dir进行飞行 */
    public async objFly(startLoc: Vector, dir: Vector) {
        // 异步创建一个气球
        let obj = await GameObject.asyncSpawn("85003")
        // 根据传过来的位置和方向,算出终点
        let endPos = startLoc.clone().add(dir.multiply(1000))
        // 根据起点和终点,算出气球朝向
        obj.worldTransform.rotation = endPos.clone().subtract(startLoc).toRotation().add(new Rotation(0, -90, 0))
        // 使用Tween让气球飞行
        let tween = new Tween(startLoc).to(endPos, 2000).onUpdate((v) => {
            obj.worldTransform.position = v
        }).onComplete(() => {
            // Tween播放结束,删除气球
            obj.destroy();
        })
        tween.start();
    }

    protected onUpdate(dt: number): void {
        TweenUtil.TWEEN.update()
    }

}


function getShootDir(chara: Character, startPos: Vector, shootRange: number) {
    const camera = Camera.currentCamera;
    let start = Vector.zero;
    let end = Vector.zero;
    let dir = Vector.zero;
    if (startPos) {
        start = startPos;
    }
    if (camera) {
        end = camera.worldTransform.position.add(camera.worldTransform.getForwardVector().multiply(shootRange));
        const hits = QueryUtil.lineTrace(camera.worldTransform.position, end, false, true, [], false, true, chara);
        dir = end.subtract(start);
        if (hits.length > 0) {
            dir = hits[0].impactPoint.subtract(start);
        }
    }
    return dir.normalize();
}

一、射线检测(QueryUtil.lineTrace)

1.基本用法

该API的返回值为Array<HitResult>

let hitInfo = QueryUtil.lineTrace(射线起点, 射线终点, 是否穿透, 是否可视化绘制)

2.HitResult

包含了碰撞到的物体信息(注:没有碰撞到物体,将不会返回HitResult)

img 参数意义:<br /> blockingHit 用来判断射线是否碰到物体 <br />time(0~1) 用来判断碰到多个物体时的先后顺序 <br />distance 测距 <br />Location 位置点 <br />impactPoint 接触点 <br />normal 位置点的法线 (配合位置点做一些特效) <br />impactNormal 接触点的法线 <br />traceStart 射线起点 <br />traceEnd 射线终点 <br />boneName 骨骼名称 <br />gameObject 碰撞到的物体

二、范围检测

1.矩形范围检测(QueryUtil.boxOverlap)

返回值为Array<GameObject>

QueryUtil.boxOverlap(矩形的中心位置, 盒体的大小, 是否可视化绘制)

2.球形范围检测(QueryUtil.sphereOverlap)

返回值为Array<GameObject>

QueryUtil.sphereOverlap(球体中心位置, 检测半径, 是否可视化绘制)

3.胶囊体范围检测(QueryUtil.capsuleOverlap)

返回值为Array<GameObject>

QueryUtil.capsuleOverlap(胶囊体中心位置, 胶囊体半径, 胶囊体半高, 是否可视化绘制)

三、特殊射线检测

1.盒体射线检测(QueryUtil.boxTrace)

返回值为Array<HitResult>

QueryUtil.boxTrace(起始位置,结束位置,合体半长宽高,盒体朝向,是否穿透检测,是否可视化绘制)

2.球体射线检测(QueryUtil.sphereTrace)

返回值为Array<HitResult>

QueryUtil.sphereTrace(起始位置,结束位置,球体半径,是否穿透检测,是否可视化绘制)

3.胶囊体射线检测(QueryUtil.capsuleTrace)

返回值为Array<HitResult>

QueryUtil.capsuleTrace(起始位置,结束位置,胶囊体半径,胶囊体半高,是否穿透检测,是否可视化绘制)

imgimgimgimg

有用就点个赞吧家人们~

射线检测.mp4

2.64 MB, 下载次数: 47

抛物线检测.mp4

47.74 MB, 下载次数: 45

回复

使用道具 举报

热门版块
快速回复 返回顶部 返回列表