发射物设计思路


  我们要想我们的发射物也就是我们的子弹要拥有什么,首先生成的时候我们要给它一个初始的速度,然后要让它有碰撞的反馈,既然要有速度,那么就要有移动组件,而且我们的发射物也可以绑定一个模型上去,于是我们就有了以下FirstProjectProjectile.h的代码


    // 球形碰撞组件
    UPROPERTY(VisibleDefaultsOnly, Category=Projectile)
        class USphereComponent* CollisionComp;
    // 物体的移动组件
    UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Movement, meta = (AllowPrivateAccess = "true"))
        class UProjectileMovementComponent* ProjectileMovement;

public:
    // 构造函数
    AFirstProjectProjectile();

    // 碰撞函数
    UFUNCTION()
        void OnHit(UPrimitiveComponent* HitComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit);

    // 返回球形组件
    FORCEINLINE class USphereComponent* GetCollisionComp() const { return CollisionComp; }
    // 返回移动组件
    FORCEINLINE class UProjectileMovementComponent* GetProjectileMovement() const { return ProjectileMovement; }
						

  在FirstProjectProjectile.cpp中:


    // 构造函数
    AFirstProjectProjectile::AFirstProjectProjectile() {
        // 生成球形碰撞组件
        CollisionComp = CreateDefaultSubobject<USphereComponent>(TEXT("SphereComp"));
        // 设置组件的半径
        CollisionComp->InitSphereRadius(5.0f);
        // 设置碰撞的文件
        CollisionComp->BodyInstance.SetCollisionProfileName("Projectile");
        // 绑定碰撞后调用的函数
        CollisionComp->OnComponentHit.AddDynamic(this, &AFirstProjectProjectile::OnHit);

        // 不允许任何角色在这个物体上行走(避免Bug)
        CollisionComp->SetWalkableSlopeOverride(FWalkableSlopeOverride(WalkableSlope_Unwalkable, 0.f));
        CollisionComp->CanCharacterStepUpOn = ECB_No;

        // 设置碰撞球形组件为根组件
        RootComponent = CollisionComp;

        // 实例化移动组件
        ProjectileMovement = CreateDefaultSubobject<UProjectileMovementComponent>(TEXT("ProjectileComp"));
        // 设置组件调用的是球形碰撞组件
        ProjectileMovement->UpdatedComponent = CollisionComp;
        // 设置生成后的初始速度
        ProjectileMovement->InitialSpeed = 3000.f;
        // 设置移动过程中的最大速度
        ProjectileMovement->MaxSpeed = 3000.f;
        // 设置在移动过程中弹丸会旋转
        ProjectileMovement->bRotationFollowsVelocity = true;
        // 模拟碰撞,开启这个属性碰到墙壁会反弹
        ProjectileMovement->bShouldBounce = true;

        // 3秒后销毁自己
        InitialLifeSpan = 3.0f;
    }
	
    // 碰撞函数
    void AFirstProjectProjectile::OnHit(UPrimitiveComponent* HitComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit){
        // 如果碰撞物体存在且不是自己并且移动组件存在
        if ((OtherActor != NULL) && (OtherActor != this) && (OtherComp != NULL) && OtherComp->IsSimulatingPhysics()){
            // 给予碰撞物体一个冲量(一个冲击的力),传入参数为力的大小和给予的力的位置
            OtherComp->AddImpulseAtLocation(GetVelocity() * 100.0f, GetActorLocation());
            // 销毁自己
            Destroy(this);
        }
    }
						

  这样我们就做好了我们的发射物,现在就剩下如何“开火”,即如何在枪口生成。