Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Header File:
- // Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.
- #pragma once
- #include "GameFramework/Actor.h"
- #include "CodeBounceBallProjectile.generated.h"
- UCLASS(config=Game)
- class ACodeBounceBallProjectile : public AActor
- {
- GENERATED_BODY()
- /** Sphere collision component */
- UPROPERTY(VisibleDefaultsOnly, Category=Projectile)
- class USphereComponent* CollisionComp;
- //Mesh component
- UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Projectile, meta = (AllowPrivateAccess = "true"))
- class UStaticMeshComponent* ProjectileMesh;
- /** Projectile movement component */
- UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Movement, meta = (AllowPrivateAccess = "true"))
- class UProjectileMovementComponent* ProjectileMovement;
- public:
- ACodeBounceBallProjectile();
- /** called when projectile hits something */
- UFUNCTION()
- void OnHit(UPrimitiveComponent* HitComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit);
- float TakeDamage(float DamageAmount, struct FDamageEvent const & DamageEvent, class AController * EventInstigator, AActor * DamageCauser) override;
- //Changes the material instance dynamic's color
- void ChangeMaterialColor(FColor Color);
- void SetToDestroy();
- UFUNCTION()
- void OnRep_WallsHit();
- /** Returns CollisionComp subobject **/
- FORCEINLINE class USphereComponent* GetCollisionComp() const { return CollisionComp; }
- /** Returns ProjectileMovement subobject **/
- FORCEINLINE class UProjectileMovementComponent* GetProjectileMovement() const { return ProjectileMovement; }
- private:
- UPROPERTY(ReplicatedUsing = OnRep_WallsHit)
- uint8 WallsHit;
- UPROPERTY(EditDefaultsOnly)
- float BaseDamage;
- //Lifespan after the projectile became useless
- UPROPERTY(EditDefaultsOnly)
- float ExtraLifespan;
- //Notify whether or not the projectile has become useless
- uint8 bIsUseless : 1;
- UMaterialInstanceDynamic* ProjectileMID;
- //Neutral projectile color
- UPROPERTY(EditAnywhere)
- FColor NeutralColor;
- //Color of the projectile for friendlies after it hit a wall once
- UPROPERTY(EditAnywhere)
- FColor AllyColor_1;
- //Color of the projectile for friendlies after it hit a wall twice
- UPROPERTY(EditAnywhere)
- FColor AllyColor_2;
- //Color of the projectile for enemies after it hit a wall once
- UPROPERTY(EditAnywhere)
- FColor FoeColor_1;
- //Color of the projectile for enemies after it hit a wall twice
- UPROPERTY(EditAnywhere)
- FColor FoeColor_2;
- protected:
- };
- //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- C++ File:
- // Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.
- #include "CodeBounceBall.h"
- #include "CodeBounceBallProjectile.h"
- #include "GameFramework/ProjectileMovementComponent.h"
- #include "GameWall.h"
- #include "CodeBounceBallCharacter.h"
- ACodeBounceBallProjectile::ACodeBounceBallProjectile()
- {
- // Use a sphere as a simple collision representation
- CollisionComp = CreateDefaultSubobject<USphereComponent>(TEXT("SphereComp"));
- CollisionComp->InitSphereRadius(5.0f);
- CollisionComp->BodyInstance.SetCollisionProfileName("Projectile");
- CollisionComp->OnComponentHit.AddDynamic(this, &ACodeBounceBallProjectile::OnHit); // set up a notification for when this component hits something blocking
- RootComponent = CollisionComp;
- // Players can't walk on it
- CollisionComp->SetWalkableSlopeOverride(FWalkableSlopeOverride(WalkableSlope_Unwalkable, 0.f));
- CollisionComp->CanCharacterStepUpOn = ECB_No;
- ProjectileMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("ProjectileMesh"));
- ProjectileMesh->SetupAttachment(RootComponent);
- // Use a ProjectileMovementComponent to govern this projectile's movement
- ProjectileMovement = CreateDefaultSubobject<UProjectileMovementComponent>(TEXT("ProjectileComp"));
- ProjectileMovement->UpdatedComponent = RootComponent;
- ProjectileMovement->InitialSpeed = 3000.f;
- ProjectileMovement->MaxSpeed = 3000.f;
- ProjectileMovement->bRotationFollowsVelocity = true;
- ProjectileMovement->bShouldBounce = true;
- // Die after 3 seconds by default
- InitialLifeSpan = 3.0f;
- ///////////////////////////////////////////////////////////////////////////////////
- static ConstructorHelpers::FObjectFinder<UStaticMesh> StaticMeshAsset(TEXT("StaticMesh'/Game/StarterContent/Shapes/Shape_Sphere.Shape_Sphere'"));
- static ConstructorHelpers::FObjectFinder<UMaterialInterface> MaterialAsset(TEXT("Material'/Game/FirstPerson/Meshes/BaseMaterial.BaseMaterial'"));
- if (MaterialAsset.Object && StaticMeshAsset.Object)
- {
- ProjectileMesh->SetStaticMesh(StaticMeshAsset.Object);
- ProjectileMID = ProjectileMesh->CreateDynamicMaterialInstance(0, MaterialAsset.Object);
- ProjectileMesh->SetMaterial(0, ProjectileMID);
- }
- bReplicates = true;
- bReplicateMovement = true;
- bAlwaysRelevant = true;
- bNetLoadOnClient = true;
- WallsHit = 0;
- BaseDamage = 20.f;
- ExtraLifespan = .5f;
- bIsUseless = false;
- NeutralColor = FColor::Yellow;
- AllyColor_1 = FColor::Green;
- AllyColor_2 = FColor::Blue;
- FoeColor_1 = FColor::Red;
- FoeColor_2 = FColor::Black;
- ChangeMaterialColor(NeutralColor);
- }
- void ACodeBounceBallProjectile::GetLifetimeReplicatedProps(TArray< FLifetimeProperty > & OutLifetimeProps) const
- {
- Super::GetLifetimeReplicatedProps(OutLifetimeProps);
- DOREPLIFETIME(ACodeBounceBallProjectile, WallsHit);
- }
- void ACodeBounceBallProjectile::OnHit(UPrimitiveComponent* HitComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit)
- {
- if (HasAuthority()) {
- //If the projectile hits a wall
- if (AGameWall* Wall = Cast<AGameWall>(OtherActor)) {
- if (0 <= WallsHit && WallsHit < 2 && !bIsUseless) {
- WallsHit++;
- }
- }
- //If the projectile hits a player
- else if (ACodeBounceBallCharacter* Player = Cast<ACodeBounceBallCharacter>(OtherActor)) {
- //If the projectile is supposed to do damage
- if (GetInstigator() != Player && WallsHit != 0 && !bIsUseless) {
- if (!Player->GetShield()) {
- if (HasAuthority()) {
- Player->TakeDamage(BaseDamage * WallsHit, FDamageEvent(UDamageType::StaticClass()), GetInstigatorController(), this);
- SetToDestroy();
- }
- }
- else {
- Player->ToogleShield(false);
- if (GetInstigator() != Player && !bIsUseless) {
- //PlayBreakSound();
- }
- SetToDestroy();
- }
- }
- else {
- if (GetInstigator() != Player && !bIsUseless) {
- //PlaySqueakSound();
- }
- SetToDestroy();
- }
- }
- else if (ACodeBounceBallProjectile* Projectile = Cast<ACodeBounceBallProjectile>(OtherActor)) {
- Projectile->SetToDestroy();
- SetToDestroy();
- }
- }
- }
- float ACodeBounceBallProjectile::TakeDamage(float DamageAmount, FDamageEvent const & DamageEvent, AController * EventInstigator, AActor * DamageCauser)
- {
- GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("Taken Damage"));
- if (HasAuthority()) {
- }
- return 0.0f;
- }
- void ACodeBounceBallProjectile::ChangeMaterialColor(FColor Color)
- {
- ProjectileMID->SetVectorParameterValue("DiffuseColor", Color);
- }
- void ACodeBounceBallProjectile::SetToDestroy()
- {
- bIsUseless = true;
- WallsHit = 0;
- SetLifeSpan(ExtraLifespan);
- }
- void ACodeBounceBallProjectile::OnRep_WallsHit()
- {
- APawn* Player = Cast<APawn>(UGameplayStatics::GetPlayerCharacter(this, 0));
- if (Player) {
- switch (WallsHit){
- case 0:
- ChangeMaterialColor(NeutralColor);
- break;
- //If the projectile hit the wall once
- case 1:
- if (GetInstigator() == Player) {
- ChangeMaterialColor(AllyColor_1);
- }
- else {
- ChangeMaterialColor(FoeColor_1);
- }
- break;
- //If the projectile hit the wall twice
- case 2:
- //GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString::Printf(TEXT("%s"), GetInstigator()->GetName()));
- if (GetInstigator() == Player) {
- ChangeMaterialColor(AllyColor_2);
- }
- else {
- ChangeMaterialColor(FoeColor_2);
- }
- break;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement