0
点赞
收藏
分享

微信扫一扫

Cocos Creator 3.x之角色移动

一,场景设计

Cocos Creator 3.x之角色移动_3.x

1, Plane加一个碰撞器

Cocos Creator 3.x之角色移动_cocos_02

2, player加一个刚体,加一个碰撞器

Cocos Creator 3.x之角色移动_角色_03

二, Character.ts

import {
    _decorator,
    Camera,
    CapsuleCollider,
    Component,
    EventTouch,
    Input,
    input,
    Node,
    Quat,
    RigidBody,
    v3,
    Vec2,
    Vec3,
    geometry,
    PhysicsSystem,
    PhysicsRayResult,
} from "cc";
const { ccclass, property } = _decorator;

@ccclass("Character")
export class Character extends Component {
    @property({ type: RigidBody, tooltip: "角色刚体" })
    private playerRigidBody: RigidBody = null;
    @property({ type: Camera, tooltip: "主摄像机" })
    private camera3D: Camera = null;
    /**当前的屏幕坐标*/
    private curScreenLocation: Vec2;
    private curWorldPosition: Vec3;
    private tempV3: Vec3;
    private tempQuat: Quat;
    private curQuat: Quat;
    private tempScreenRay: geometry.Ray;

    //#region player旋转相关
    private readonly PLAYER_ROTATION_DURATION_SECOND: number = 0.5;
    private isPlayerRotating: boolean;
    private curPlayerRotationTime: number;
    //#endregion

    //#region player移动相关
    private isPlayerMoving: boolean;
    private perDistance: number;
    //#endregion

    protected onLoad(): void {
        this.tempV3 = v3(0, 0);
        this.tempQuat = new Quat();
        this.curQuat = new Quat();
        this.isPlayerRotating = false;
        this.isPlayerMoving = false;
        this.tempScreenRay = new geometry.Ray();
    }

    protected onEnable(): void {
        this.listener(true);
    }

    protected onDisable(): void {
        this.listener(false);
    }

    private listener(isAdd: boolean): void {
        if (isAdd) {
            input.on(Input.EventType.TOUCH_END, this.onTouchHandler, this);
        } else {
            input.off(Input.EventType.TOUCH_END, this.onTouchHandler, this);
        }
    }

    private onTouchHandler(e: EventTouch): void {
        switch (e.type) {
            case Input.EventType.TOUCH_END: //玩家点击结束
                this.curScreenLocation = e.getLocation(); //获得了屏幕的坐标
                this.camera3D.screenPointToRay(
                    this.curScreenLocation.x,
                    this.curScreenLocation.y,
                    this.tempScreenRay
                ); //构建一条射线
                if (
                    PhysicsSystem.instance.raycastClosest(
                        this.tempScreenRay,
                        PhysicsSystem.PhysicsGroup.DEFAULT
                    ) == true
                ) {
                    this.curPlayerRotationTime = 0;
                    this.isPlayerMoving = false;
                    this.perDistance = null;
                    let ressult: PhysicsRayResult = PhysicsSystem.instance.raycastClosestResult; //最近的一个碰撞体
                    this.curWorldPosition = ressult.hitPoint;
                    this.curWorldPosition.y = this.node.worldPosition.y;
                    //获得从player指向点击点的向量
                    Vec3.subtract(this.tempV3, this.curWorldPosition, this.node.worldPosition);
                    //获得一个face指向点击点的四元数
                    Quat.fromViewUp(this.curQuat, this.tempV3.clone().normalize(), Vec3.UP);
                    this.isPlayerRotating = true;
                }
                break;
        }
    }

    protected update(deltaTime: number): void {
        if (this.isPlayerRotating) {
            this.curPlayerRotationTime += deltaTime / this.PLAYER_ROTATION_DURATION_SECOND;
            if (this.curPlayerRotationTime >= 1) {
                this.curPlayerRotationTime = 1;
                this.isPlayerRotating = false;
                this.isPlayerMoving = true;
                this.curPlayerRotationTime = 0;
                this.perDistance = null;
            }
            this.tempQuat
                .set(this.node.worldRotation)
                .slerp(this.curQuat, this.curPlayerRotationTime);
            this.node.setWorldRotation(this.tempQuat);
            return;
        }
        if (this.isPlayerMoving) {
            //从player指向目标点的向量
            Vec3.subtract(this.tempV3, this.curWorldPosition, this.node.worldPosition);
            //计算向量的模
            const distance: number = this.tempV3.length();
            if (this.perDistance != null && distance == this.perDistance && distance <= 0.2) {
                this.isPlayerMoving = false;
            } else {
                this.perDistance = distance;
            }
            this.playerRigidBody.setLinearVelocity(this.tempV3);
        }
    }

    protected onDestroy(): void {
        this.curScreenLocation = null;
        this.curWorldPosition = null;
        this.tempV3 = null;
        this.tempQuat = null;
        this.tempScreenRay = null;
    }
}

三, 结果

Cocos Creator 3.x之角色移动_角色_04

举报

相关推荐

0 条评论