Unity 旋转跟随

news2024/12/28 23:57:15

Unity 使用任意一个局部轴指向目标

效果:

主要用于在编辑器中可视化对象的朝向,同时提供了选择不同轴向的功能。在运行时,物体将根据所选择的轴向朝向目标,并在 Scene 视图中绘制一个带箭头的圆环。
请添加图片描述

定义轴向枚举:

public enum OnlyAxis
{
    x_Axis,
    y_Axis,
    z_Axis
}
  • 这是一个用于表示轴向的枚举,包括 x 轴、y 轴和 z 轴。

定义变量:

public Transform target; // 要指向的目标物体
[Header("追踪轴向")]
public OnlyAxis Axis = OnlyAxis.x_Axis; // 选择旋转的轴向
private OnlyAxis CurrentAxis = OnlyAxis.x_Axis; // 当前轴向
  • target: 用于指定需要朝向的目标物体。
  • Axis: 用于在 Inspector 窗口中选择旋转的轴向。
  • CurrentAxis: 用于在运行时跟踪当前的轴向。

主要计算:

private void Update()
{
    SetAxis(Axis);

    // 获取目标方向
    Vector3 targetDirection = target.position - transform.position;
    Vector3 RotateAxis = transform.up;

    // 根据选择的轴向,获取目标方向在对应轴上的投影
    Vector3 axisDirection = Vector3.zero;
    switch (CurrentAxis)
    {
        case OnlyAxis.x_Axis:
            axisDirection = Vector3.ProjectOnPlane(targetDirection, transform.right);
            break;
        case OnlyAxis.y_Axis:
            axisDirection = Vector3.ProjectOnPlane(targetDirection, transform.up);
            break;
        case OnlyAxis.z_Axis:
            axisDirection = transform.forward;
            Vector3 dirTemp = transform.forward.normalized;
            RotateAxis = Vector3.ProjectOnPlane(targetDirection, dirTemp);
            break;
    }

    // 计算旋转角度
    Quaternion newRotation = Quaternion.LookRotation(axisDirection, RotateAxis);
    transform.rotation = newRotation;
}

  • SetAxis 方法用于在运行时更新 CurrentAxis,确保在不同的轴向之间正确切换。
  • 在 Update 方法中,获取目标方向,并根据当前选择的轴向计算相应的旋转。最后,将物体的旋转设为新的旋转。

OnDrawGizmosSelected 方法(仅在编辑器中生效):

#if UNITY_EDITOR
    private void OnDrawGizmosSelected()
    {
        DrawCircle();
    }
    public bool is3DDraw = false;
    public float radius = 0.1f;
    public float arrowLength = 0.01f;
    int segments = 20;

    private void DrawCircle()
    {
        float Radius = is3DDraw ? radius : radius * Vector3.Distance(transform.position, SceneView.lastActiveSceneView.camera.transform.position);
        float ArrowLength = is3DDraw ? arrowLength : arrowLength * Vector3.Distance(transform.position, SceneView.lastActiveSceneView.camera.transform.position);

        Gizmos.color = Color.green;
        Vector3 center = transform.position;
        Quaternion rotation = transform.rotation;
        float angleIncrement = 360f / segments;
        for (int i = 0; i < segments; i++)
        {
            float angle = i * angleIncrement;
            Vector3 point = Vector3.zero;
            float nextAngle = (i + 1) * angleIncrement;
            Vector3 nextPoint = Vector3.zero;

            // 根据所选轴向,调整旋转
            switch (Axis)
            {
                case OnlyAxis.x_Axis:
                    point = center + rotation * Quaternion.Euler(angle, 0, 0) * (Vector3.up * Radius);
                    nextPoint = center + rotation * Quaternion.Euler(nextAngle, 0, 0) * (Vector3.up * Radius);
                    if (i == 0)
                    {
                        Gizmos.DrawLine(nextPoint, center + rotation * Quaternion.Euler(angle + angleIncrement / 2, 0, 0) * (Vector3.up * (Radius + ArrowLength)));
                        Gizmos.DrawLine(nextPoint, center + rotation * Quaternion.Euler(angle + angleIncrement / 2, 0, 0) * (Vector3.up * (Radius - ArrowLength)));
                    }
                    break;
                case OnlyAxis.y_Axis:
                    point = center + rotation * Quaternion.Euler(0, angle, 0) * (Vector3.right * Radius);
                    nextPoint = center + rotation * Quaternion.Euler(0, nextAngle, 0) * (Vector3.right * Radius);
                    if (i == 0)
                    {
                        Gizmos.DrawLine(nextPoint, center + rotation * Quaternion.Euler(0, angle + angleIncrement / 2, 0) * (Vector3.right * (Radius + ArrowLength)));
                        Gizmos.DrawLine(nextPoint, center + rotation * Quaternion.Euler(0, angle + angleIncrement / 2, 0) * (Vector3.right * (Radius + -ArrowLength)));
                    }
                    break;
                case OnlyAxis.z_Axis:
                    point = center + rotation * Quaternion.Euler(0, 0, angle) * (Vector3.right * Radius);
                    nextPoint = center + rotation * Quaternion.Euler(0, 0, nextAngle) * (Vector3.right * Radius);
                    if (i == 0)
                    {
                        Gizmos.DrawLine(nextPoint, center + rotation * Quaternion.Euler(0, 0, angle + angleIncrement / 2) * (Vector3.right * (Radius + ArrowLength)));
                        Gizmos.DrawLine(nextPoint, center + rotation * Quaternion.Euler(0, 0, angle + angleIncrement / 2) * (Vector3.right * (Radius + -ArrowLength)));
                    }
                    break;
            }
            if (i != 1) Gizmos.DrawLine(point, nextPoint);
        }
    }
#endif
  • OnDrawGizmosSelected 方法用于在 Scene 视图中绘制圆环。
  • DrawCircle 方法根据选择的轴向,绘制一个圆环并在第一个点上画一个箭头。

点击下载Demo

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1342138.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

学python用哪本书比较好,学python应该买什么书

大家好&#xff0c;小编来为大家解答以下问题&#xff0c;学python用哪本书比较好&#xff0c;学python应该买什么书&#xff0c;今天让我们一起来看看吧&#xff01; 文章目录 一、Python 基础 01-《Python编程&#xff1a;从入门到实践&#xff08;第2版&#xff09;》02-《P…

右键添加 idea 打开功能

1.开始运行regedit 2.找到: HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Directory\shell _3.开始设置 一、右键shell目录新建项Idea二、右键Idea新建command三、选择Idea 右侧空白出新建字符串 名字为Icon 值填入idea的运行程序地址 四、选择command 默认项填入idea的运行程序地址…

javascript之跳转页面的几种方法?

文章目录 前言代码演示及解释使用location.href属性使用location.assign()方法使用location.replace()方法使用window.open()方法使用document.URL方法 总结 前言 本章学习的是JavaScript中的跳转页面的几种方法 代码演示及解释 使用location.href属性 可以直接将一个新的URL…

LabVIEW的便携式车辆振动测试分析

随着计算机和软件技术的发展&#xff0c;虚拟仪器正逐渐成为机械工业测试领域的主流。在现代机械工程中&#xff0c;特别是车辆振动测试&#xff0c;传统的测试方法不仅设备繁杂、成本高昂&#xff0c;而且操作复杂。为解决这些问题&#xff0c;开发了一款基于美国国家仪器公司…

PostgreSQL 数据库归档最近被问及的问题问题 与 4 毋 处世学

开头还是介绍一下群&#xff0c;如果感兴趣PolarDB ,MongoDB ,MySQL ,PostgreSQL ,Redis, Oceanbase, Sql Server等有问题&#xff0c;有需求都可以加群群内&#xff0c;可以解决你的问题。加群请联系 liuaustin3 &#xff0c;&#xff08;共1790人左右 1 2 3 4 5&#xff0…

跑项目报错Cannot find module ‘@babel/preset-env/lib/utils‘

换了电脑之后新电脑 npm install 安装包之后&#xff0c;npm run serve 运行项目出错 &#x1f447;&#x1f447;&#x1f447; npm run serve 运行项目报错 Cannot find module babel/preset-env/lib/utils 根据报错提示查看报错的包路径 可以确定安装的依赖包没有问题&#…

elasticsearch系列四:集群常规运维

概述 在使用es中如果遇到了集群不可写入或者部分索引状态unassigned&#xff0c;明明写入了很多数据但是查不到等等系列问题该怎么办呢&#xff1f;咱们今天一起看下常用运维命令。 案例 起初我们es性能还跟得上&#xff0c;随着业务发展壮大&#xff0c;发现查询性能越来越不…

【第十二课】KMP算法(acwing-831 / c++代码 / 思路 / 视频+博客讲解推荐)

目录 暴力做法 代码如下 KMP算法 不同的next求法-----视频讲解/博客推荐 视频推荐 博客推荐 课本上的方法- prefix的方法- 求next数组思路---next数组存放前缀表的方式 s和p匹配思路 代码如下 暴力做法 遍历s主串中每一个元素&#xff0c;如果该元素等于模板串p中…

SeaTunnel流处理同步MySQL数据至ClickHouse

ClickHouse是一种OLAP类型的列式数据库管理系统&#xff0c;ClickHouse完美的实现了OLAP和列式数据库的优势&#xff0c;因此在大数据量的分析处理应用中ClickHouse表现很优秀。 SeaTunnel是一个分布式、高性能、易扩展、用于海量数据同步和转化的数据集成平台。用户只需要配置…

你的 VSCode 上 还没有 GitHub Copilot ?看这里

GitHub Copilot 是由 OpenAI 和 GitHub 开发的 AI 工具。其目的是通过自动完成代码来帮助开发人员使用集成开发环境 &#xff08;IDE&#xff09;&#xff0c;如 Visual Studio Code。它目前仅作为技术预览版提供&#xff0c;因此只有已加入候补名单的用户才能访问它。对于使用…

OpenAI: InstructGPT的简介

OpenAI: InstructGPT paper: 2022.3 Training Language Model to follow instructions with human feedback Model: (1.3B, 6B, 175B) GPT3 一言以蔽之&#xff1a;你们还在刷Benchamrk?我们已经换玩法了&#xff01;更好的AI才是目标 这里把InstructGPT拆成两个部分&#…

Arduino stm32 USB CDC虚拟串口使用示例

Arduino stm32 USB CDC虚拟串口使用示例 &#x1f4cd;相关篇《STM32F401RCT6基于Arduino框架点灯程序》&#x1f516;本开发环境基于VSCode PIO&#x1f33f;验证芯片&#xff1a;STM32F401RC⌛USB CDC引脚&#xff1a; PA11、 PA12&#x1f527;platformio.ini配置信息&…

线程基础知识(三)

前言 之前两篇文章介绍了线程的基本概念和锁的基本知识&#xff0c;本文主要是学习同步机制&#xff0c;包括使用synchronized关键字、ReentrantLock等&#xff0c;了解锁的种类&#xff0c;死锁、竞争条件等并发编程中常见的问题。 一、关键字synchronized synchronied关键…

android studio 将含有jni c++ 的library项目封装成jar并调用

请参考博客&#xff1a;android studio 4.1.1 将library项目封装成aar 并调用_android studio 4.1 aar release-CSDN博客 一 . 简单叙述 android studio 中可以创建Module 的两种属性&#xff0c;可以在build.gradle 中查看&#xff1a; 1. application属性&#xff1a;可以独…

2023我的编程之路

你的编程学习经历和成长过程&#xff1a; 在我探索编程世界的旅程中&#xff0c;我深刻地认识到&#xff0c;编程不仅仅是一种技术&#xff0c; 是一种思维方式&#xff0c; 一种解决问题的方法。希望通过分享我的编程学习体验&#xff0c;能够启发更多的人看到编程的魅力和价值…

分享70套超治愈的宫崎骏漫画PPT模板

又到了每年最年终总结的时候了&#xff0c;最近都在忙着做总结的PPT&#xff0c;找了好些个模板&#xff0c;希望这些模板也能够对你做PPT有用。 这70套唯美的宫崎骏治愈系PPT模板&#xff0c;适合文艺又与众不同的你。可以用在文艺汇报、工作总结、作品展示、产品介绍等。 Tip…

ssm基于javaweb的数学竞赛网站的设计与实现论文

摘 要 传统办法管理信息首先需要花费的时间比较多&#xff0c;其次数据出错率比较高&#xff0c;而且对错误的数据进行更改也比较困难&#xff0c;最后&#xff0c;检索数据费事费力。因此&#xff0c;在计算机上安装数学竞赛网站软件来发挥其高效地信息处理的作用&#xff0c…

【微服务核心】MyBatis Plus

MyBatis Plus 文章目录 MyBatis Plus1. 简介2. 入门使用3. 核心功能3.1 CRUD 接口3.1.1 Mapper CRUD 接口3.1.2 Service CRUD 接口 3.2 条件构造器3.3 分页插件3.4 Mybatis-Plus 注解 4. 拓展4.1 逻辑删除4.2 MybatisX快速开发插件 5. 插件5.1 [分页插件](#page)5.2 乐观锁插件…

《Python》:深拷贝、浅拷贝、赋值之间的关系(附可变与不可变)【用图文讲清楚!】

背景 想必大家面试或者平时学习经常遇到问python的深拷贝、浅拷贝和赋值之间的区别了吧&#xff1f;看网上的文章很多写的比较抽象&#xff0c;小白接收的难度有点大&#xff0c;于是乎也想自己整个文章出来供参考 可变与不可变 讲深拷贝和浅拷贝之前想讲讲什么是可变数据类型…

Openslide安装

文章目录 安装open-slide python下载openslide二进制文件解压到Anaconda的library目录下配置环境变量在py文件中添加以下语句即可 官网链接 安装open-slide python 表面上这样就可以导入了但事实上会遇到 Couldn’t locate OpendSlide DLL的问题&#xff0c;openslide必须独立安…