一、为什么使用sin函数来计算高度的浮动
sin函数曲线相较于普通直线函数的加减是平滑的,到最高处和最低处呈现缓慢趋势
二、为什么是这样使用sin
1、为什么不直接使用sin(deltatime)来计算每帧增加的高度
如果直接用sin(deltatime),deltatime是距离上一帧的时间,如果帧数稳定则其值也是稳定即固定的
因为每帧之间的运行时间间隔不会过大,所以sin求出来的数就是正数
除非你的电脑每帧运行时间间隔超过了3.14秒以上,求出来就是负数(ue4.27.2实测,最终3.14为估值,还可以往小数点后推算)
2、为什么不直接使用sin(runningtime)来计算每帧增加的高度
如果直接用sin(runningtime)
那么runningtime的数值只会无限增长下去,他的sin范围是(-1,1)
这样造成的后果是你要把每帧增加的高度数值要调小一点即DeltaHeight * 20.0f 中的20.0f
否则NewLocation.Z得出的数值会变得很大
3、使用两个sin值的差
因为我们要用一个sin的函数曲线来限定上下浮动的范围,而且这个sin的取值也不能过大,所以可以使用两个sin之间的差来把最终值的范围限定小一点,而不是直接使用sin(deltatime)
float DeltaHeight = (FMath::Sin(RunningTime + DeltaTime) - FMath::Sin(RunningTime));
此处的deltatime起到的作用除了限定sin的范围,还用来充当时间增量计算每帧浮动的高度 NewLocation.Z += DeltaHeight * 20.0f;
(时间增量保证每秒增加的高度不会因为每秒帧数的浮动而改变,所以每秒增加的高度应该是一致的)
void AmyFloatingActor::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
//获取物体当前位置
FVector NewLocation = GetActorLocation();
//获取物体当前的旋转
FRotator NewRotation = GetActorRotation();
//获取当前物体的运行时间
float RunningTime = GetGameTimeSinceCreation();
float DeltaHeight = (FMath::Sin(RunningTime + DeltaTime) - FMath::Sin(RunningTime));
//float DeltaHeight = FMath::Sin(DeltaTime); // sin(deltatime)的值基本是正的,所以不会上下浮动,只会一直向上
//RunningTime += DeltaTime;
//float DeltaHeight = FMath::Sin(RunningTime); // sin的范围是(-1,1)
NewLocation.Z += DeltaHeight * 20.0f; //把高度以20的系数进行缩放
float DeltaRotation = DeltaTime * 20.0f; // 旋转度数也必须用时间增量来达到帧同步的效果
NewRotation.Yaw += DeltaRotation;
//设置位置和旋转
SetActorLocationAndRotation(NewLocation, NewRotation);
}