WASD添加力到组件上让整个物体移动(油门Throttle):
通过WASD传入一个值作为油门的大小,通过函数(DriveTrack)来设置力
先在项目设置中Axis Mappings(想达到按的大小轻重不同,前进后退的速度不同)加
创对应的组件(TankTrack履带)C++项目(StaticMeshComponent)
UCLASS(ClassGroup = (Custom), meta = (BlueprintSpawnableComponent)) //暴露给蓝图用于加到对应的物体上
UFUNCTION(BlueprintCallable,Category="Input")
void SetThrottle(float Throttle); //设置油门大小的函数
void DriveTrack(); //赋予力到组件(物体)的函数
UPROPERTY(EditAnywhere,Category="Setup")
float TankMaxDrivingForce=40000000.0f; //受到的力的默认值
float ThrottleToDrive = 0;
void UTankTrack::SetThrottle(float Throttle) {
ThrottleToDrive = FMath::Clamp(ThrottleToDrive + Throttle, -1, 1);
}
void UTankTrack::DriveTrack() { //按键的时候是设置油门
auto ForceApplied = TankMaxDrivingForce * ThrottleToDrive * GetForwardVector(); //auto是系统自己判断是什么类型
auto ForceLocation = GetComponentLocation();
auto RootCompOnent= Cast(GetOwner()->GetRootComponent()); //
RootComponent->AddForceAtLocation(ForceApplied, ForceLocation);
}
因为是让整个TankBody移动,所以GetOwner()后得到对应的Track在GetRootComponent得到TankBody,此时返回的值是USceneComponent类型(只拥有位置信息Transform,层级信息Attachment,没有显示mesh的功能和碰撞的功能),所以要转换成UprimitiveComponent(就拥有物理的属性了,才有AddForceAtLocation这个方法)
接下来再创用于移动的组件(TankMoveComponent)(MovementCompont)
(如果要AI自动寻路要NavMovementComponent)
UCLASS(ClassGroup = (Custom), meta = (BlueprintSpawnableComponent))
private:
UFUNCTION(BlueprintCallable, Category = "Setup")
void Initialise(UTankTrack* LeftTrackToSet, UTankTrack* RightTrackToSet); //在蓝图中赋值给对应的组件LeftTrack/RightTrack
UFUNCTION(BlueprintCallable, Category = "Input")
void MoveForward(float Throttle);
UFUNCTION(BlueprintCallable, Category = "Input")
void MoveRight(float Throttle);
UTankTrack * LeftTrack = nullptr;
UTankTrack * RightTrack = nullptr;
void UTankMovementComponent::Initialise(UTankTrack* LeftTrackToSet, UTankTrack* RightTrackToSet) {
if (LeftTrackToSet == nullptr || RightTrackToSet == nullptr)return;
LeftTrack = LeftTrackToSet;
RightTrack = RightTrackToSet;
}
void UTankMovementComponent::MoveForward(float Throttle) {
LeftTrack->SetThrottle(Throttle);
RightTrack->SetThrottle(Throttle); //前后移动只需左右履带同时前进即可
}
void UTankMovementComponent::MoveRight(float Throttle) {
LeftTrack->SetThrottle(Throttle);
RightTrack->SetThrottle(-Throttle);
}
编译后在蓝图中加入对应的组件(上述写的两个)
OnHit移动事件绑定:
蓝图中:
C++:
h:
virtual void BeginPlay() override; //
UFUNCTION()
void OnHit(UPrimitiveComponent* HitComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit);
cpp:
void UTankTrack::BeginPlay() {
Super::BeginPlay();
OnComponentHit.AddDynamic(this,&UTankTrack::OnHit); //添加碰撞事件,加函数要加&(参数)
}
void UTankTrack::OnHit(UPrimitiveComponent* HitComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit) {
DriveTrack();
ThrottleToDrive = 0;
}//当碰到东西的时候才会执行DriveTrack(开车)