Unity --- Vector3类的API讲解

文章详细解释了Unity3D中Vector3类对象的坐标概念,包括世界坐标和局部坐标的区别,以及如何通过Position和localPosition影响游戏物体的位置。还讨论了静态变量、normalized和Normalize的区别,以及Project和Reflect方法的用途。此外,重点介绍了插值移动方法MoveTowards和Lerp,特别是Lerp的高级用法,结合AnimationCurve实现自定义速度变化的平滑移动效果。
摘要由CSDN通过智能技术生成

1.Vector3中的静态变量是相对于世界坐标系的还是相对于自身坐标系呢?(我们创建的Vector3类对象同理)

答:这取决我们将创建的Vector3类对象 / 通过Vector3调用的静态变量传给了哪一个引用

 如果是传给了positon的话,则该Vector3类对象就是相对于世界坐标系的,反之,如果传的是localPosition的话,则是Vector3类对象是相对于本地坐标系(父类坐标系)的

(如果游戏物体没有父类的话,其localPositon与Position重合)

1.这个Transform中显示的是localPosition,localRotation和localScale 

当游戏物体没有父物体的时候,游戏物体相对于世界的Positon,rotation和scale和相对于本地坐标系local的部分相重合

2.以一个有父物体的游戏物体为例:

如果我们直接设置

那么会出现:

a.Transform的Position(localPosition)显示0,1,0  --- 物体位置发生改变

b.该物体的世界坐标系Positon跟随着localPositon的改变而发生对应的改变

如果我们更改的是物体的position的话

a.物体的位置也会发生改变 --- 物体的位置会变到跟定的世界坐标系的位置,同时要注意的是

通过positon改变了物体的位置后,物体的localPositon也会根据新的位置发生对应的变化,变化完成后,生成的新的localPositon会在Transfrom中显示

 

1.可以直接通过类名 + 点操作符访问的方法/变量,就是静态方法/变量  

1.normalized 和 Normalize的区别:

a. normalized 是Vector3类中的属性,而Normalized则是Vector3类中的一个方法

b. 一个Vector3类对象A调用normalized属性之后,会返回一个新的Vector3类对象,该对象是A的单位向量

c.一个Vector3类对象A调用Normalize方法后,会改变自身的模长 --- 具体改变是将自身的模长改为1,将自身变为自身的单位向量

 1.参数为ref标志着这个参数是引用参数

2.该方法的作用是将与引用A指向的向量垂直的两个单位向量分别传给引用basisB 和 引用 basisC(注意,这个垂直指的是类似于坐标轴那样的垂直) --- PS:三个向量彼此互相垂直

1.上面这个介绍的是Vector3中的一个静态方法 --- Project()方法,这个方法的作用是投影一个向量到另一个向量 

这里的投影是什么意思呢?

a.首先我们要知道该方法是vector向量投影到onNormal向量上

b.该方法的返回值是一个向量,且该向量是vector向量投影后得到的那根投影向量

3.所谓的投影其实就是vector向量沿着onNormal向量的方向做分量

 1.在Reflect方法中,第一个参数 --- Vector3对象 inDirection是用来给定一个确定入射方向的向量的;第二个参数就是给定一个确定法线方向的向量

2.最后该方法会返回一个向量,该向量是沿着给定的入射向量和法线向量反射后得到的反射向量

1.法线是垂直于面的,给定一条法线就能够确定一个面 


接下来开始讲讲Vector3类中为我们提供的插值移动方法

这个方法与直接更改游戏物体transfrom中的位置属性的区别是:

1.插值移动方法在给定移动终点后能够实现从起点到终点的逐步移动过程

2.直接更改位置属性则是直接将游戏物体在起点处的渲染停止,直接在终点处开始渲染 --- 这样呈现出的效果就是突然消失然后突然出现

1.Vector3类中为我们提供的插值方法就是 --- MoveTowards方法 ,该方法需要三个参数 --- 第一个是游戏物体的移动起点,第二个是移动终点(这两个都是Vector3变量),最后一个则是移动速度

使用这个方法产生的移动效果就是 --- 游戏物体按照给定的速度逐渐从起点匀速移动到终点

注意:该方法只能够实现匀速移动!

1.对应的还有一个Lerp方法,它能够实现游戏物体从起点先快后慢向终点移动,且只能无限接近终点而无法到达终点。 

2.Lerp方法除了能够实现物体从起点出发由快到慢不断接近终点之外,它还能够实现各种各样的速度变化:

a.首先我们先介绍一下默认的由快到慢的速度变化时,三个参数的情况:

起点参数是不固定的,他会随着物体位置的改变而跟着改变;终点参数是固定的,段落比例是固定的(为什么是段落比例可以去看看前面讲解的Lerp插值方法的实现原理

b.此时我们再引进一个变量:

(curve是曲线的意思),设置好公共动画曲线之后,我们就能够在inspector面板看到这样一个参数窗口点开之后会出现一个线条窗口供我们调节 ---

 

在这里我们可以自由的设置一个曲线的形状(曲线的x轴是时间),设置好之后就会返回给我们一个变量 --- 这个变量的类型是浮点型,它的最小值是0,最大值是1

这个变量的值是随着时间不断变化的,而具体的变化规律就是我们设置好的曲线

 

1.引入了两个变量之后我们开始正式讲解这个Lerp方法的进阶使用 --- 

首先进阶使用方法依然需要三个参数,其中起点参数和终点参数必须是固定的,唯一能够变化的参数是比例参数

2.这个变化的比例参数 = curve.Evaluate(时间参数) --- curve就是我们引用的AnimationCurve变量 

我们最终的目的是获得动画曲线的y轴上的值来作为比例参数,且这个y轴上的值还必须随着时间变化 --- 那么实现这个需求就需要我们调用动画曲线中的放啊 -- Evaluate() --- 在给定该方法一个单精度浮点型参数之后(要求参数范围是0到1,一旦小于0/大于1,方法只会返回0/1),它就会在动画曲线的x轴上找到这个参数的位置,并将这个位置对应的y轴值返回

(也就是说,如果我们想持续改变比例参数的话,就需要提供一个不断变化的时间参数给Evaluate方法)

(PS:在C#中,默认0.5,0.6...这种浮点数的类型为双精度浮点数double,如果想将其转换为单精度浮点数类型float的话,只需要在数的后面加上一个f --- 如0.5f,0.6f

3.在动画曲线中如果想增加一个点来调整的话,只需要在想要增加的点双击即可

4.动画曲线的y轴值可以大于1,也可以小于0

5.Lerp方法需要的比例参数可以大于1,也可以小于0 --- 当比例参数大于1的时候。Lerp方法调用后的效果是:物体移动1:1的距离,直接闪现到终点

如果小于0的话,则是物体移动0:1的距离,不发生移动

6.如果想让Lerp方法在比例大于1,小于0的时候也能够有效果的话,就需要我们用一个Lerp的解放版方法 --- LerpUnclamped方法 ---unclamp松开 --- 使用该方法后,如给比例大于1如1.5,则游戏物体会沿着起点到终点的方向加速移动到两者距离的1.5倍处,反之小于0,如-0.5则是沿着起点到终点的反方向由快到慢的移动到二者之间距离的0.5倍处

7.设curve.Evaluate()方法的时间参数为x(浮点型),该参数从0开始累加,当参数加到1的时候,动画曲线走完全程,游戏物体完成移动 --- 也就是说游戏物体从起点到终点总共耗时1s

如果我们想改变消耗的时间 --- 比如使得消耗时间小于1s/大于1s,那我们该怎么做呢?

此时我们需要创建一个变量,该变量用来记录我们实际想让游戏物体完成全程的时间 T

然后对Evaluate的时间参数做修改 ---- 从单纯的x变为 x/T --- 此时只有在x = T时,游戏物体才会完成全程(动画曲线也会跟着时间参数等比例缩放)(PS:一般时间参数x都是通过 x = x + Time.deltaTime来实现不断向前变化的)

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 这个问题是关于Unity引擎中Vector2和Vector4型的转换问题。以下是一个示例解决方案: 问题的错误提示表明这是一个引用问题,涉及到两种不同的Vector型。根据Unity官方文档,Vector2是一个二维向量,而Vector4是一个四维向量。 因此,将Vector4型转换为Vector2型可能会引发数据丢失。但是,您可以通过以下方式将Vector4值分配给Vector2: Vector4 v4 = new Vector4(1f, 2f, 3f, 4f); Vector2 v2 = new Vector2(v4.x, v4.y); 在上面的代码片段中,我们创建一个Vector4 v4变量,然后使用其.x和.y成员值分配给Vector2 v2变量。如果您想将所有四个分量值从Vector4转换为Vector2,可以这样做: Vector4 v4 = new Vector4(1f, 2f, 3f, 4f); Vector2 v2 = new Vector2(v4.x, v4.y); Vector2 v2_2 = new Vector2(v4.z, v4.w); 在上面的代码片段中,我们使用.v2.x和.v2.y来拆分前两个分量,使用v2_2.x和v2_2.y来拆分后两个分量。 总结来说,要解决这个问题,需要将Vector4值拆分为Vector2值,以避免数据丢失。 ### 回答2: 出现这个错误是因为无法将型为`Vector4`的参数传递给期望接收`Vector2`型参数的方法或函数。解决这个问题的步骤如下: 1. 首先,需要确定具体在哪个方法或函数中出现了这个问题,以便针对性地进行修改。 2. 确认为什么需要将`Vector4`型转换为`Vector2`型。如果要传递给方法或函数的参数确实需要是`Vector2`型,那么继续进行下一步。如果不是必需的,考虑使用`Vector4`型参数来代替。 3. 创建一个新的`Vector2`实例,并将`Vector4`中相应的值赋给新的`Vector2`实例。假设我们有一个名为`vector4`的`Vector4`实例,我们可以通过以下方式创建一个新的`Vector2`实例: ```csharp Vector2 vector2 = new Vector2(vector4.x, vector4.y); ``` 这将使用`Vector4`实例的x和y值来创建一个新的`Vector2`实例。 4. 将新创建的`Vector2`实例传递给方法或函数,以替代之前错误的`Vector4`参数。确保方法或函数中的参数型也被修改为`Vector2`。 下面是一个简单的示例,演示如何解决这个问题: ```csharp using UnityEngine; public class Example : MonoBehaviour { // 使用Vector2型的参数的方法 public void PrintVector2(ref Vector2 vector2) { Debug.Log(vector2); } void Start() { Vector4 vector4 = new Vector4(1, 2, 3, 4); // 创建Vector4实例 // 创建新的Vector2实例,并将Vector4的x和y值赋给Vector2 Vector2 vector2 = new Vector2(vector4.x, vector4.y); // 调用PrintVector2方法并将新的Vector2实例作为参数传递 PrintVector2(ref vector2); } } ``` 在上述示例中,我们通过创建一个新的`Vector2`实例并将`Vector4`的x和y值赋给它来解决了无法将`Vector4`转换为`Vector2`的问题。然后,我们将新的`Vector2`实例作为参数传递给`PrintVector2`方法,并成功解决了该问题。 ### 回答3: 这个问题的解决方法是使用Vector4的x和y值来创建一个新的Vector2实例。因为无法直接将ref型的Vector4转换为ref型的Vector2,所以我们需要进行一些额外的操作。 以下是一个详细的例子: ```csharp // 定义一个ref型的Vector4参数 public void ConvertVector(ref Vector4 originalVector) { // 创建一个新的Vector2实例 Vector2 newVector = new Vector2(originalVector.x, originalVector.y); // 在这里可以使用新的Vector2实例进行其他操作或返回 } void Main() { // 初始化一个ref型的Vector4参数 Vector4 originalVector = new Vector4(1, 2, 3, 4); // 调用ConvertVector方法,并将原始的Vector4参数传递给它 ConvertVector(ref originalVector); } ``` 在这个例子中,我们首先定义了一个名为ConvertVector的方法,该方法接受一个ref型的Vector4参数。在方法内部,通过使用originalVector的x和y值来创建一个新的Vector2实例newVector。 然后,我们在Main方法中初始化了一个ref型的Vector4参数originalVector,并将其传递给ConvertVector方法。 通过这种方式,我们成功地使用Vector4的x和y值创建了一个新的Vector2实例,并解决了无法直接将ref型的Vector4转换为ref型的Vector2的问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值