|
发表于 2022-12-28 13:57:22
|
显示全部楼层
前言
——首先铺垫一下,在U3D中,场景内能拖来拖去的物体基本都是GameObject这个类下的,UE与之对应的是个叫Actor的类,它们之下也都有关于物体的平移、旋转、缩放的空间变换组件Transform。
——然后U3D和UE的坐标系都是左手系,但U3D是y朝上,UE是z朝上。
——最后是单位长度。U3D的1单位长度对应1米,UE则是100单位长度对应1米。
——下面拿一部分方法来讲解。
UE蓝图
1、平移旋转缩放

——不管平移旋转还是缩放,基本就三类节点:GetXXX是获取;SetXXX是直接设置;AddXXX是基于现有数值进行增量变化,而后两者又分世界坐标与层级中的相对坐标。(左下的三个分量拆分可以右键->Split Struct Pin)
——Sweep和Teleport和物理碰撞啥的有关,暂时先不管。
——上图示例的只是Actor对应的方法,其他类型的组件名称会略有不同,比如StaticMesh的变换如下。

2、绕轴旋转
——我没找到UE有什么一气呵成的API,所以可能要稍微多绕几个弯子。下面先公开旋转中心,旋转轴,旋转半径,旋转速度四个参数。

——因为没有旋转中心和旋转半径相关的参数,所以关于这俩的计算如果需要的话,一定程度上都需要我们手撸一下。具体方法可以参考下面的【其他方式】中的数学过程,起手算了个向量到旋转平面的投影向量,前面的方法就不演示了。(简单来说要先想办法把物体SetActorLocation到旋转平面上,然后才是下面的步骤,否则旋转中心和半径无意义,而只是下面这样单纯照着给定轴来转)
增量旋转——关键节点:RotateVectorAroundAxis

其他方式——也可以通过创建父子层级或者数学解一切来搞。比如下面这样搞了个函数蓝图RotateAround。


3、朝向设置
——首先下面是获取,分别对应x、y、z轴向的世界空间方向。

——然后设置的话目前实验可用的主要一些MakeXXX方法。(图中的FindLookAtRotation也有效果,但因为这个方法应该是只设置了x轴向,相当于MakeRotFromX,所以会有意料之外的“侧翻”)

——当然,上面只是基于向量构造了一套欧拉角,之后还得SetActorRotation。
UE C++
——C++API的方法名和节点中的基本一致,借着代码提示敲一敲试一试就好(所以这就是用英文的好处- -···)。还有种方式是鼠标悬停在节点上,他会显示这个节点引用的哪个方法库。

——因为UE的C++里有很多组件都是指针形式的,所以调方法经常要用【->】(如果不是指针类型那就和C#一样用【.】,如果是调静态或者const之类的东西则是用类名(命名空间)+域运算符【::】,目前大概是这么总结- -)。顺便UE好像习惯变量开头大写。
//移动
Actor->SetActorLocation(FVector(1, 2, 3));//设置绝对世界坐标
Actor->SetActorRelativeLocation(FVector(4, 5, 6));//设置相对父组件的局部坐标
Actor->AddActorWorldOffset(FVector::OneVector);//沿指定向量移动
//旋转
Actor->SetActorRotation(FQuat::Identity);//四元数默认值,实际使用可能需要用到一些向量,欧拉角,四元数互相转换的API
UKismetMathLibrary::RotateAngleAxis(Actor->GetActorLocation(), 90, FVector::UpVector);//即上面蓝图中的RotateVectorAroundAxis节点的原型
//需要#include <Runtime/Engine/Classes/Kismet/KismetMathLibrary.h>才能用
//缩放
Actor->SetActorRelativeScale3D(FVector::OneVector);//设置相对缩放
Actor->SetActorScale3D(2 * FVector::OneVector);//设置绝对缩放
//朝向
FVector X = Actor->GetActorForwardVector();
FVector Y = Actor->GetActorRightVector();
FVector Z = Actor->GetActorUpVector();
UKismetMathLibrary::MakeRotFromXZ(-Actor->GetActorLocation(), FVector::OneVector);//同上面的绕轴旋转
U3D
——功能对照上面的UE C++。
//移动
transform.position = new Vector3(1,2,3);//个人习惯这样直接赋值,改的是【世界坐标】。不能x、y、z单拿出来赋值
transform.localPosition = new Vector3(4,5,6);//改的是【相对Hierarchy中父层级的坐标】
transform.Translate(Vector3.one, Space.World);//沿指定向量移动(可配置坐标空间)
//旋转
transform.rotation = Quaternion.identity;//四元数形式的rotation,不直观,一般不这么用
transform.RotateAround(Vector3.zero, Vector3.up, 10);//以点(0,0,0)为旋转中心,向量(0,1,0)为旋转轴旋转10度。如果还要求在旋转平面上也需要手撸
//缩放
transform.localScale = Vector3.one;//改的是【相对Hierarchy中父层级的缩放】
print(transform.lossyScale);//绝对缩放,但U3D只读不能改
//朝向
transform.right/up/forward;//本地x/y/z轴的世界空间坐标
transform.LookAt(Vector3.zero, new Vector3(1, 1, 1));//让该物体看向(0,0,0)点,同时指定up为(1,1,1) |
|