[Unity3D]-螺旋线

2023-10-19 14:59
文章标签 unity3d 螺旋线

本文主要是介绍[Unity3D]-螺旋线,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

之前,在做人物技能设计的时候,遇见一个做螺旋运动的技能,特效师,K帧K个半死,最终还是没有完美的弄出一个螺旋运动.这个时候,纯手工制作就没有用工程学的方法制作那般完美了.
在一个平面上做螺旋运动,螺纹由外向内,只需要两个步骤就可以完成.

1. 先在平面中做圆周运动
2. 然后逐渐缩短半径

如果在螺纹平面的垂直方向上再加一个运动量,则可形成3D螺旋运动.想想都觉得简单..哈哈!
这里写图片描述
上图为2D螺旋线运动轨迹和3D螺旋线运动轨迹示意图.
接下来本文将讲解如何制作一个2D螺线运动轨迹.


圆周运动

在3D空间中使一个物体在绕指定轴做圆周运动,例如Y轴,那么物体就在XZ平面上运动.
这里写图片描述
中心点A可已看成是从世界坐标远点到A点的向量,在此表示为OA,图中交点B也可用同样的方式去理解,在此表示为OB,那么红线所代表向量则可表示为AB.
已知A点和向量AB时,向量OB=OA+AB;
以此类推,物体做圆周运动时,轨迹上的点X(向量OX),可以由向量OA加上中心到圆周交点的X的向量AX求得,即OX=OA+AX;向量AX就是需要我们去实时计算的量.

如何计算向量 AX?
由图中的向量AB绕Y轴(或者说是中心点A)旋转一圈就可以求得所有的向量AX.向量AB=半径长度*单位向量.这里的单位向量可用XZ平面的任何一个单位向量表示.

如何旋转向量 AB?
我们可以使用四元数对向量AB做旋转变换,得出所有的向量AX.
物体圆周运动的求解思路大致如此,下面我给出一段示例代码.

public class MROTATE : MonoBehaviour
{public float _distance = 5f;public float _angle = 10f;bool _isStart = false;Transform _center;Transform _surround;void Awake(){_center = transform;_surround = GameObject.CreatePrimitive(PrimitiveType.Sphere).transform;_center.name = "_center";_surround.name = "_surround";_surround.position = Vector3.Normalize(Vector3.forward) * _distance + _center.position;StartCoroutine(InitEnd());}IEnumerator InitEnd(){yield return new WaitForSeconds(1);_isStart = true;}void Update(){if (!_isStart) return;//绕Y轴旋转_angle度Quaternion rotate = Quaternion.AngleAxis(_angle, Vector3.up);//由中心指向圆周的方向向量Vector3 dir = Vector3.Normalize(_surround.position - _center.position);//向量OX = 向量OA + 向量AX_surround.position = _center.position + rotate * dir * _distance;}}

关于四元数的类容.
可以参考链接http://blog.csdn.net/candycat1992/article/details/41254799
或者参考书籍<3D数学基础:图形与游戏开发>


逐渐缩短半径

逐渐缩短半径就比较容易了,没有圆周运动那么复杂的计算.如果理解Lerp线性插值运算,那么逐渐缩短半径对你来说就是小菜一碟.

Lerp运算,有三个参数,第一个参数是起始值start,第二个参数是终点值end;第三个参数t范围在[0,1].
当第三个参数为0时,返回值start;
当第三个参数为1时,返回值end;
当第三个参数为0.5时,返回start与end中间的值,即(start+end)/2;

在Update方法中,做插值计算便可做到半径逐渐减小的效果.
其他好像没什么好说的了,下面是最终代码!

public class MROTATE : MonoBehaviour
{public float _distance = 10f;public float _speed = 10;public float _angle = 2f;bool _isStart = false;Transform _center;Transform _surround;float _value = 1;void Awake(){_center = transform;_surround = GameObject.CreatePrimitive(PrimitiveType.Sphere).transform;_center.name = "_center";_surround.name = "_surround";_surround.position = Vector3.Normalize(Vector3.forward) * _distance + _center.position;//这一步协程是为了避免螺纹线初始位置绘制错误StartCoroutine(InitEnd());}IEnumerator InitEnd(){yield return new WaitForSeconds(1);_isStart = true;}void Update(){if (!_isStart) return;//半径逐渐减小_value -= _speed * Time.deltaTime * 0.01f;float distance = Mathf.Lerp(0, _distance, _value);//圆周运动Quaternion rotate = Quaternion.AngleAxis(_angle, Vector3.up);Vector3 dir = Vector3.Normalize(_surround.position - _center.position);_surround.position = rotate * dir * distance + _center.position;_pos.Add(_surround.position);}List<Vector3> _pos = new List<Vector3>();void OnDrawGizmos(){Gizmos.color = Color.red;//在Scene视图中绘制螺纹线for (int i = 0; i < _pos.Count - 1; i++){Vector3 from = _pos[i];Vector3 to = _pos[i + 1];Gizmos.DrawLine(from, to);}}
}

最终在Scene视图下的效果图如下.
这里写图片描述

这篇关于[Unity3D]-螺旋线的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/240556

相关文章

Unity3D自带Mouse Look鼠标视角代码解析。

Unity3D自带Mouse Look鼠标视角代码解析。 代码块 代码块语法遵循标准markdown代码,例如: using UnityEngine;using System.Collections;/// MouseLook rotates the transform based on the mouse delta./// Minimum and Maximum values can

Unity3D 运动之Move函数和translate

CharacterController.Move 移动 function Move (motion : Vector3) : CollisionFlags Description描述 A more complex move function taking absolute movement deltas. 一个更加复杂的运动函数,每次都绝对运动。 Attempts to

Unity3D在2D游戏中获取触屏物体的方法

我们的需求是: 假如屏幕中一个棋盘,每个棋子是button构成的,我们希望手指或者鼠标在哪里,就显示那个位置的button信息。 网上有很多获取触屏物体信息的信息的方法如下面代码所示: Camera cam = Camera.main; // pre-defined...if (touch.phase == TouchPhase.Bagan)){ // 如果触控点状态为按下Ray

Unity3D Shader详解:只画顶点或只画线框

在Unity3D开发中,Shader是控制渲染过程的关键组件,它允许开发者自定义物体的渲染方式。有时,为了特定的视觉效果,我们可能需要只渲染模型的顶点或者只显示其线框。下面,我们将详细探讨这两种效果的技术实现,并给出相应的代码示例。 对惹,这里有一个游戏开发交流小组,大家可以点击进来一起交流一下开发经验呀! 只画顶点 在Unity中直接“只画顶点”的概念可能不是非常直观,因为顶点本身只是模型

Unity3D ARPG(动作角色扮演游戏)设计与实现详解

动作角色扮演游戏(Action Role-Playing Game, ARPG)结合了传统角色扮演游戏(RPG)的深度与动作游戏(Action Game)的即时反应和流畅战斗体验。Unity3D 作为一款强大的跨平台游戏开发引擎,为开发者提供了丰富的工具和资源来创建高质量的 ARPG 游戏。本文将详细介绍如何使用 Unity3D 设计和实现一个基本的 ARPG 游戏,包括技术选型、游戏架构、关键系

(转)Unity3D 三种移动方式

第一种移动方式: 首先在方法外声明刚体:private Rigidbody body; 为了明显,可定义一个速度:public float speed; void Start(){ speed = 10f; body = GetCompoente(); } void Update(){ //第一种移动方式:直接修改Transform属性 //如果是球体,自身不会旋转 if(In

Unity3D中控制3D场景中游戏对象显示层级的详解

前言 在Unity3D开发中,控制游戏对象的显示层级(也称为渲染顺序或渲染层级)是一个常见的需求,特别是在处理复杂的3D场景时,如角色、道具、UI元素等的可见性和渲染顺序的管理变得尤为重要。Unity通过几种不同的机制来实现对游戏对象显示层级的控制,包括使用Sorting Layers、Sorting Order以及Camera的Culling Mask等。下面将详细解释这些机制,并提供相应的代

Unity3D关于AI的编写代码

1. Unity3D简单AI编写   由于这次介绍的AI很简单,代码直接贴上,AI分成四个状态:思考,转身,移动,攻击,这里只是初步实现,所以想实现简单点的操作,就像自动范围内随机移动,锁敌攻击,超出距离复位,近距离察觉等。   1 Enemy_AI.js   2   3 private var Regression : Vector3;   4 public var Player_

【Unity3D】【UI】Cannot restructure Prefab instance.

触发原因未知,猜测是策划把别的预设A挪了一个改了个名字成了预设B。想要改动预设B中的组件产生了一下报错。 Cannot restructure Prefab instance. Children of a Prefab instance cannot be deleted or moved,and components cannot be reordered. You can open th

Unity3D 获取资源运行时内存和硬盘大小

Unity3D 🌻获取资源运行时内存和硬盘大小 🌻内存 使用Profiler可以查看某个资源的内存占用情况,但是必须启动游戏,并且待查看的资源已经载入游戏中。我希望的是不启动游戏,也能看到它的内存好做统计。 🌻硬盘 由于unity中的资源压缩格式记录在meta中所以,在文件夹中看到的资源大小是不正确的。打开unity需要选择一个资源,比如Texture、然后在右侧Ins