首页 > 其他分享 >Cocos Creator 3.x之旋转基础

Cocos Creator 3.x之旋转基础

时间:2023-12-31 16:32:06浏览次数:27  
标签:Cocos const Creator Quat private tempQuat player Vec3 旋转

一, 场景设计

Cocos Creator 3.x之旋转基础_Quat

二,整体场景效果

Cocos Creator 3.x之旋转基础_Rotation_02

三,QuatView.ts代码

import {_decorator, Component, EventTouch, Input, input, Node, Quat, v3, Vec3, Vec2} from "cc";

const {ccclass, property} = _decorator;

@ccclass("QuatView")
export class QuatView extends Component {
    @property({type: Node, tooltip: "目标cube"})
    private cube: Node = null;
    @property({type: Node, tooltip: "玩家"})
    private player: Node = null;

    private isSlerp: boolean;
    private rotationQuat: Quat;
    private tempQuat: Quat;
    private timerMs: number;
    private durationMs: number;
    private tempV3: Vec3;

    protected onl oad(): void {
        this.isSlerp = false;
        this.rotationQuat = new Quat();
        this.tempQuat = new Quat();
        this.tempV3 = new Vec3();
    }

    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);
            input.on(Input.EventType.TOUCH_MOVE, this.onTouchHandler, this);
        } else {
            input.off(Input.EventType.TOUCH_END, this.onTouchHandler, this);
            input.off(Input.EventType.TOUCH_MOVE, this.onTouchHandler, this);
        }
    }

    private onTouchHandler(e: EventTouch): void {
        switch (e.type) {
            case Input.EventType.TOUCH_END:
                // this.turningToTarget(true);
                break;
            case Input.EventType.TOUCH_MOVE:
                // this.touchRotation(e);
                this.touchAroundRotation(e);
                break;
        }
    }

    /**
     * 转向目标
     */
    private turningToTarget(isSlerp: boolean): void {
        let targetPosition: Vec3 = this.cube.worldPosition
            .subtract(this.player.worldPosition)
            .normalize();//看向的方向 player -> cube
        Quat.fromViewUp(this.rotationQuat, targetPosition, Vec3.UP);//获取转向rotationQuat
        if (Quat.equals(this.rotationQuat, this.player.worldRotation)) {
            this.isSlerp = false;
            console.log(`%c 已经旋转到目标值,不需要再次旋转了`, "color:#F00");
        } else {
            if (!isSlerp) {
                this.player.setWorldRotation(this.rotationQuat);
            } else {
                this.durationMs = 2000;
                this.timerMs = 0;
            }
            this.isSlerp = isSlerp;
        }
    }

    /**
     * 触摸自旋转
     */
    private touchRotation(e: EventTouch): void {
        const delta: Vec2 = e.getDelta();
        const axis: Vec3 = v3(-delta.y, delta.x, 0); //旋转轴,根据相似三角形求出
        const rad: number = delta.length() * 1e-2; //旋转角度
        this.tempQuat = this.player.getRotation(); //当前的四元数
        Quat.rotateAround(this.rotationQuat, this.tempQuat, axis.normalize(), rad); //当面的四元数绕旋转轴旋转
        this.player.setRotation(this.rotationQuat);
    }


    private touchAroundRotation(e: EventTouch): void {
        const delta: Vec2 = e.getDelta();
        // 绕轴转
        // 这里选取轴朝上
        const axis2: Vec3 = Vec3.UP;//旋转轴: Y
        const rad2: number = 1e-2 * delta.x; //旋转角度
        // 计算坐标
        const point: Vec3 = this.cube.worldPosition; //旋转点
        const pointNow: Vec3 = this.player.worldPosition; // 当前点的位置
        // 算出坐标点的旋转四元数
        Quat.fromAxisAngle(this.tempQuat, axis2, rad2);//在zx轴上的旋转量
        // 计算旋转点和现有点的向量
        Vec3.subtract(this.tempV3, pointNow, point);//pointNow - point , cube -> player
        // 计算旋转后的向量
        Vec3.transformQuat(this.tempV3, this.tempV3, this.tempQuat);
        // 计算旋转后的点
        Vec3.add(this.tempV3, point, this.tempV3);//point + this.tempV3
        this.player.setWorldPosition(this.tempV3);

        // 计算朝向
        // 这么旋转会按原始的朝向一起旋转
        const quatNow: Quat = this.player.worldRotation;
        Quat.rotateAround(this.tempQuat, quatNow, axis2, rad2);
        Quat.normalize(this.tempQuat, this.tempQuat);
        this.player.setWorldRotation(this.tempQuat);
    }

    //做一个动画的缓动
    protected update(dt: number): void {
        if (!this.isSlerp) return;
        this.timerMs += dt * 1000;
        const ratio: number = this.timerMs / this.durationMs;
        if (ratio < 1) {
            //先快后慢, 使用球面插值,不然在旋转的时候会出现变形
            this.tempQuat.set(this.player.worldRotation).slerp(this.rotationQuat, ratio);
        } else {
            this.tempQuat = this.rotationQuat;
            this.isSlerp = false;
        }
        this.player.setWorldRotation(this.tempQuat);
    }
}

脚本字段赋值:

Cocos Creator 3.x之旋转基础_旋转角度_03


标签:Cocos,const,Creator,Quat,private,tempQuat,player,Vec3,旋转
From: https://blog.51cto.com/aonaufly/9049245

相关文章

  • 旋转矩阵一些用法备忘
    Box_A的旋转角度为a 旋转矩阵为:a) 用于做localToWorld的变换,这个矩阵的col1,col2分别表示模型空间的x轴、y轴坐标b) 求点在世界坐标轴上的投影c)abs(RotA)*rightTopPoint_Local,求Box_A相对世界坐标轴的AABB包围盒halfSize 旋转矩阵的转置矩阵或逆矩阵为:a) 用......
  • cocos 自定义property
    exportenumAviaBC2CountryEnum{GBR=1,USA=2,}//定义一个图片类型的类@ccclass("SpriteTypes")//这个名字一定要写,而且还注意不能取下面的类名不然cocosCreator会一直报警告classSpriteType{//语言@property({type:cc.Enum(AviaBC2Cou......
  • mac m1 编译cocos2d-x 在模拟器上运行 一些问题汇总
     如果涉及到侵权请联系本人删除 1  》〉/Users/yzfhkms-m/Library/Developer/Xcode/DerivedData/formi-dlcfwgxcmidqefdkxnvnfwfprpfs/Build/Products/Debug-iphonesimulator/formi-mobile.appisnotavalidpathtoanexecutablefile.Pleaserebuildtheprojectto......
  • WPF 图片围绕中心点旋转
    <Image.RenderTransform></Image.RenderTransform><Image.Triggers></Image.Triggers><Image.Source><DrawingImage><DrawingImage.Drawing><DrawingGroup>......
  • Cocos Creator 2.x之通用计时器
    一,代码核心1,CommonTimer.ts/***通用计时器*/import{CommonTimerModeType,ICommonTimerInfo}from"./CommomTimerDefine";exportdefaultclassCommonTimerMgrextendscc.Component{publicstaticinstance:CommonTimerMgr;privatetimerList:ICo......
  • Cocos Creator 2.x之ScrollView分层渲染
    一,场景设计1,ScrollViewPrefab:挂载ScrollViewPrefab脚本。2,ScrollViewPrefabItem:挂载ScrollViewPrefabItem脚本。是内容item。二,传统做法,加入30个item三,分层处理,加入30个item1,代码:CommomScrollViewCDconst{ccclass,property}=cc._decorator;//绘画层classDraw{......
  • Spring的Bean后置处理器之AnnotationAwareAspectJAutoProxyCreator
    本文能帮你回答以下几个问题;AnnotationAwareAspectJAutoProxyCreator后置器的作用是什么?SpringAOP自动增强bean是如何实现的。如何在spring上下文添加AnnotationAwareAspectJAutoProxyCreator?如何利用ProxyFactory硬编码实现一个bean的增强?AnnotationAwareAspectJAutoProx......
  • 【教程】步兵 cocos2dx 加密和混淆
    文章目录摘要引言正文代码加密具体步骤代码加密具体步骤测试和配置阶段IPA重签名操作步骤总结参考资料 摘要本篇博客介绍了针对iOS应用中的Lua代码进行加密和混淆的相关技术。通过对Lua代码进行加密处理,可以确保应用代码的安全性,同时提高性能表现。文......
  • 【终极教程】Cocos2dx服务端重构(优化cocos2dx服务端)
    【终极教程】Cocos2dx服务端重构(优化cocos2dx服务端)文章目录概述问题概述1.代码混淆代码加密具体步骤测试和配置阶段IPA重签名操作步骤2.缺乏文档3.缺乏推荐的最佳实践4.性能问题总结 概述Cocos2dx是一个非常流行的跨平台游戏引擎,开发者可以使用这个引擎来开......
  • 【教程】使用ipagurd打包与混淆Cocos2d-x的Lua脚本
    【教程】使用ipagurd打包与混淆Cocos2d-x的Lua脚本文章目录摘要引言正文1.准备工作2.使用ipaguard处理Lua文件3.运行ipagurd进行混淆代码加密具体步骤测试和配置阶段IPA重签名操作步骤4.IPA重签名与发布总结 摘要本文将介绍如何使用ipagurd工具对Cocos2d-......