#include "UnrealCPPCharacter.h" #include "UnrealCPPProjectile.h" #include "Animation/AnimInstance.h" #include "Camera/CameraComponent.h" #include "Components/CapsuleComponent.h" #include "Components/InputComponent.h" #include "GameFramework/InputSettings.h" #include "HeadMountedDisplayFunctionLibrary.h" #include "Kismet/GameplayStatics.h" #include "MotionControllerComponent.h" #include "XRMotionControllerBase.h" // for FXRMotionControllerBase::RightHandSourceId #include "Kismet/KismetMathLibrary.h" #include "TimerManager.h" DEFINE_LOG_CATEGORY_STATIC(LogFPChar, Warning, All); ////////////////////////////////////////////////////////////////////////// // AUnrealCPPCharacter AUnrealCPPCharacter::AUnrealCPPCharacter() { // Set size for collision capsule GetCapsuleComponent()->InitCapsuleSize(55.f, 96.0f); // set our turn rates for input BaseTurnRate = 45.f; BaseLookUpRate = 45.f; // Create a CameraComponent FirstPersonCameraComponent = CreateDefaultSubobject<UCameraComponent>(TEXT("FirstPersonCamera")); FirstPersonCameraComponent->SetupAttachment(GetCapsuleComponent()); FirstPersonCameraComponent->RelativeLocation = FVector(-39.56f, 1.75f, 64.f); // Position the camera FirstPersonCameraComponent->bUsePawnControlRotation = true; // Create a mesh component that will be used when being viewed from a '1st person' view (when controlling this pawn) Mesh1P = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("CharacterMesh1P")); Mesh1P->SetOnlyOwnerSee(true); Mesh1P->SetupAttachment(FirstPersonCameraComponent); Mesh1P->bCastDynamicShadow = false; Mesh1P->CastShadow = false; Mesh1P->RelativeRotation = FRotator(1.9f, -19.19f, 5.2f); Mesh1P->RelativeLocation = FVector(-0.5f, -4.4f, -155.7f); // Create a gun mesh component FP_Gun = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("FP_Gun")); FP_Gun->SetOnlyOwnerSee(true); // only the owning player will see this mesh FP_Gun->bCastDynamicShadow = false; FP_Gun->CastShadow = false; // FP_Gun->SetupAttachment(Mesh1P, TEXT("GripPoint")); FP_Gun->SetupAttachment(RootComponent); FP_MuzzleLocation = CreateDefaultSubobject<USceneComponent>(TEXT("MuzzleLocation")); FP_MuzzleLocation->SetupAttachment(FP_Gun); FP_MuzzleLocation->SetRelativeLocation(FVector(0.2f, 48.4f, -10.6f)); // Default offset from the character location for projectiles to spawn GunOffset = FVector(100.0f, 0.0f, 10.0f); // Note: The ProjectileClass and the skeletal mesh/anim blueprints for Mesh1P, FP_Gun, and VR_Gun // are set in the derived blueprint asset named MyCharacter to avoid direct content references in C++. // Create VR Controllers. R_MotionController = CreateDefaultSubobject<UMotionControllerComponent>(TEXT("R_MotionController")); R_MotionController->MotionSource = FXRMotionControllerBase::RightHandSourceId; R_MotionController->SetupAttachment(RootComponent); L_MotionController = CreateDefaultSubobject<UMotionControllerComponent>(TEXT("L_MotionController")); L_MotionController->SetupAttachment(RootComponent); // Create a gun and attach it to the right-hand VR controller. // Create a gun mesh component VR_Gun = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("VR_Gun")); VR_Gun->SetOnlyOwnerSee(true); // only the owning player will see this mesh VR_Gun->bCastDynamicShadow = false; VR_Gun->CastShadow = false; VR_Gun->SetupAttachment(R_MotionController); VR_Gun->SetRelativeRotation(FRotator(0.0f, -90.0f, 0.0f)); VR_MuzzleLocation = CreateDefaultSubobject<USceneComponent>(TEXT("VR_MuzzleLocation")); VR_MuzzleLocation->SetupAttachment(VR_Gun); VR_MuzzleLocation->SetRelativeLocation(FVector(0.000004, 53.999992, 10.000000)); VR_MuzzleLocation->SetRelativeRotation(FRotator(0.0f, 90.0f, 0.0f)); // Counteract the rotation of the VR gun model. // Uncomment the following line to turn motion controllers on by default: //bUsingMotionControllers = true; } void AUnrealCPPCharacter::BeginPlay() { // Call the base class Super::BeginPlay(); FullHealth = 1000.0f; Health = FullHealth; HealthPercentage = 1.0f; PreviousHealth = HealthPercentage; bCanBeDamaged = true; FullMagic = 100.0f; Magic = FullMagic; MagicPercentage = 1.0f; PreviousMagic = MagicPercentage; MagicValue = 0.0f; bCanUseMagic = true; if (MagicCurve) { FOnTimelineFloat TimelineCallback; FOnTimelineEventStatic TimelineFinishedCallback; TimelineCallback.BindUFunction(this, FName("SetMagicValue")); TimelineFinishedCallback.BindUFunction(this, FName{ TEXT("SetMagicState") }); MyTimeline.AddInterpFloat(MagicCurve, TimelineCallback); MyTimeline.SetTimelineFinishedFunc(TimelineFinishedCallback); } //Attach gun mesh component to Skeleton, doing it here because the skeleton is not yet created in the constructor FP_Gun->AttachToComponent(Mesh1P, FAttachmentTransformRules(EAttachmentRule::SnapToTarget, true), TEXT("GripPoint")); // Show or hide the two versions of the gun based on whether or not we're using motion controllers. if (bUsingMotionControllers) { VR_Gun->SetHiddenInGame(false, true); Mesh1P->SetHiddenInGame(true, true); } else { VR_Gun->SetHiddenInGame(true, true); Mesh1P->SetHiddenInGame(false, true); } } void AUnrealCPPCharacter::Tick(float DeltaTime) { Super::Tick(DeltaTime); MyTimeline.TickTimeline(DeltaTime); } ////////////////////////////////////////////////////////////////////////// // Input void AUnrealCPPCharacter::SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) { // set up gameplay key bindings check(PlayerInputComponent); // Bind jump events PlayerInputComponent->BindAction("Jump", IE_Pressed, this, &ACharacter::Jump); PlayerInputComponent->BindAction("Jump", IE_Released, this, &ACharacter::StopJumping); // Bind fire event PlayerInputComponent->BindAction("Fire", IE_Pressed, this, &AUnrealCPPCharacter::OnFire); // Enable touchscreen input EnableTouchscreenMovement(PlayerInputComponent); PlayerInputComponent->BindAction("ResetVR", IE_Pressed, this, &AUnrealCPPCharacter::OnResetVR); // Bind movement events PlayerInputComponent->BindAxis("MoveForward", this, &AUnrealCPPCharacter::MoveForward); PlayerInputComponent->BindAxis("MoveRight", this, &AUnrealCPPCharacter::MoveRight); // We have 2 versions of the rotation bindings to handle different kinds of devices differently // "turn" handles devices that provide an absolute delta, such as a mouse. // "turnrate" is for devices that we choose to treat as a rate of change, such as an analog joystick PlayerInputComponent->BindAxis("Turn", this, &APawn::AddControllerYawInput); PlayerInputComponent->BindAxis("TurnRate", this, &AUnrealCPPCharacter::TurnAtRate); PlayerInputComponent->BindAxis("LookUp", this, &APawn::AddControllerPitchInput); PlayerInputComponent->BindAxis("LookUpRate", this, &AUnrealCPPCharacter::LookUpAtRate); } void AUnrealCPPCharacter::OnFire() { // try and fire a projectile if (ProjectileClass != NULL && !FMath::IsNearlyZero(Magic, 0.001f) && bCanUseMagic) { UWorld* const World = GetWorld(); if (World != NULL) { if (bUsingMotionControllers) { const FRotator SpawnRotation = VR_MuzzleLocation->GetComponentRotation(); const FVector SpawnLocation = VR_MuzzleLocation->GetComponentLocation(); World->SpawnActor<AUnrealCPPProjectile>(ProjectileClass, SpawnLocation, SpawnRotation); } else { const FRotator SpawnRotation = GetControlRotation(); // MuzzleOffset is in camera space, so transform it to world space before offsetting from the character location to find the final muzzle position const FVector SpawnLocation = ((FP_MuzzleLocation != nullptr) ? FP_MuzzleLocation->GetComponentLocation() : GetActorLocation()) + SpawnRotation.RotateVector(GunOffset); //Set Spawn Collision Handling Override FActorSpawnParameters ActorSpawnParams; ActorSpawnParams.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AdjustIfPossibleButDontSpawnIfColliding; // spawn the projectile at the muzzle World->SpawnActor<AUnrealCPPProjectile>(ProjectileClass, SpawnLocation, SpawnRotation, ActorSpawnParams); // try and play the sound if specified if (FireSound != NULL) { UGameplayStatics::PlaySoundAtLocation(this, FireSound, GetActorLocation()); } // try and play a firing animation if specified if (FireAnimation != NULL) { // Get the animation object for the arms mesh UAnimInstance* AnimInstance = Mesh1P->GetAnimInstance(); if (AnimInstance != NULL) { AnimInstance->Montage_Play(FireAnimation, 1.f); } } SetMagicChange(-20.0f); } } } } void AUnrealCPPCharacter::OnResetVR() { UHeadMountedDisplayFunctionLibrary::ResetOrientationAndPosition(); } void AUnrealCPPCharacter::BeginTouch(const ETouchIndex::Type FingerIndex, const FVector Location) { if (TouchItem.bIsPressed == true) { return; } if ((FingerIndex == TouchItem.FingerIndex) && (TouchItem.bMoved == false)) { OnFire(); } TouchItem.bIsPressed = true; TouchItem.FingerIndex = FingerIndex; TouchItem.Location = Location; TouchItem.bMoved = false; } void AUnrealCPPCharacter::EndTouch(const ETouchIndex::Type FingerIndex, const FVector Location) { if (TouchItem.bIsPressed == false) { return; } TouchItem.bIsPressed = false; } //Commenting this section out to be consistent with FPS BP template. //This allows the user to turn without using the right virtual joystick //void AUnrealCPPCharacter::TouchUpdate(const ETouchIndex::Type FingerIndex, const FVector Location) //{ // if ((TouchItem.bIsPressed == true) && (TouchItem.FingerIndex == FingerIndex)) // { // if (TouchItem.bIsPressed) // { // if (GetWorld() != nullptr) // { // UGameViewportClient* ViewportClient = GetWorld()->GetGameViewport(); // if (ViewportClient != nullptr) // { // FVector MoveDelta = Location - TouchItem.Location; // FVector2D ScreenSize; // ViewportClient->GetViewportSize(ScreenSize); // FVector2D ScaledDelta = FVector2D(MoveDelta.X, MoveDelta.Y) / ScreenSize; // if (FMath::Abs(ScaledDelta.X) >= 4.0 / ScreenSize.X) // { // TouchItem.bMoved = true; // float Value = ScaledDelta.X * BaseTurnRate; // AddControllerYawInput(Value); // } // if (FMath::Abs(ScaledDelta.Y) >= 4.0 / ScreenSize.Y) // { // TouchItem.bMoved = true; // float Value = ScaledDelta.Y * BaseTurnRate; // AddControllerPitchInput(Value); // } // TouchItem.Location = Location; // } // TouchItem.Location = Location; // } // } // } //} void AUnrealCPPCharacter::MoveForward(float Value) { if (Value != 0.0f) { // add movement in that direction AddMovementInput(GetActorForwardVector(), Value); } } void AUnrealCPPCharacter::MoveRight(float Value) { if (Value != 0.0f) { // add movement in that direction AddMovementInput(GetActorRightVector(), Value); } } void AUnrealCPPCharacter::TurnAtRate(float Rate) { // calculate delta for this frame from the rate information AddControllerYawInput(Rate * BaseTurnRate * GetWorld()->GetDeltaSeconds()); } void AUnrealCPPCharacter::LookUpAtRate(float Rate) { // calculate delta for this frame from the rate information AddControllerPitchInput(Rate * BaseLookUpRate * GetWorld()->GetDeltaSeconds()); } bool AUnrealCPPCharacter::EnableTouchscreenMovement(class UInputComponent* PlayerInputComponent) { if (FPlatformMisc::SupportsTouchInput() || GetDefault<UInputSettings>()->bUseMouseForTouch) { PlayerInputComponent->BindTouch(EInputEvent::IE_Pressed, this, &AUnrealCPPCharacter::BeginTouch); PlayerInputComponent->BindTouch(EInputEvent::IE_Released, this, &AUnrealCPPCharacter::EndTouch); //Commenting this out to be more consistent with FPS BP template. //PlayerInputComponent->BindTouch(EInputEvent::IE_Repeat, this, &AUnrealCPPCharacter::TouchUpdate); return true; } return false; } float AUnrealCPPCharacter::GetHealth() { return HealthPercentage; } float AUnrealCPPCharacter::GetMagic() { return MagicPercentage; } FText AUnrealCPPCharacter::GetHealthIntText() { int32 HP = FMath::RoundHalfFromZero(HealthPercentage * 100); FString HPS = FString::FromInt(HP); FString HealthHUD = HPS + FString(TEXT("%")); FText HPText = FText::FromString(HealthHUD); return HPText; } FText AUnrealCPPCharacter::GetMagicIntText() { int32 MP = FMath::RoundHalfFromZero(MagicPercentage*FullMagic); FString MPS = FString::FromInt(MP); FString FullMPS = FString::FromInt(FullMagic); FString MagicHUD = MPS + FString(TEXT("/")) + FullMPS; FText MPText = FText::FromString(MagicHUD); return MPText; } void AUnrealCPPCharacter::SetDamageState() { bCanBeDamaged = true; } void AUnrealCPPCharacter::DamageTimer() { GetWorldTimerManager().SetTimer(MemberTimerHandle, this, &AUnrealCPPCharacter::SetDamageState, 2.0f, false); } void AUnrealCPPCharacter::SetMagicValue() { TimelineValue = MyTimeline.GetPlaybackPosition(); CurveFloatValue = PreviousMagic + MagicValue*MagicCurve->GetFloatValue(TimelineValue); MagicPercentage = CurveFloatValue; MagicPercentage = FMath::Clamp(MagicPercentage, 0.0f, 1.0f); } void AUnrealCPPCharacter::SetMagicState() { bCanUseMagic = true; MagicValue = 0.0; if(GunDefaultMaterial) { FP_Gun->SetMaterial(0, GunDefaultMaterial); } } bool AUnrealCPPCharacter::PlayFlash() { if(redFlash) { redFlash = false; return true; } return false; } void AUnrealCPPCharacter::ReceivePointDamage(float Damage, const UDamageType * DamageType, FVector HitLocation, FVector HitNormal, UPrimitiveComponent * HitComponent, FName BoneName, FVector ShotFromDirection, AController * InstigatedBy, AActor * DamageCauser, const FHitResult & HitInfo) { bCanBeDamaged = false; redFlash = true; UpdateHealth(-Damage); DamageTimer(); } void AUnrealCPPCharacter::UpdateHealth(float HealthChange) { Health += HealthChange; Health = FMath::Clamp(Health, 0.0f, FullHealth); PreviousHealth = HealthPercentage; HealthPercentage = Health/FullHealth; } void AUnrealCPPCharacter::UpdateMagic(float MagicChange) { Magic += MagicChange; Magic = FMath::Clamp(Magic, 0.0f, FullMagic); PreviousMagic = MagicPercentage; MagicPercentage = Magic/FullMagic; } void AUnrealCPPCharacter::SetMagicChange(float MagicChange) { bCanUseMagic = false; Magic += MagicChange ; Magic = FMath::Clamp(Magic, 0.0f, FullMagic); PreviousMagic = MagicPercentage; MagicValue += (MagicChange/FullMagic); if(GunOverheatMaterial) { FP_Gun->SetMaterial(0, GunOverheatMaterial); } MyTimeline.PlayFromStart(); }
Write, Run & Share C++ code online using OneCompiler's C++ online compiler for free. It's one of the robust, feature-rich online compilers for C++ language, running on the latest version 17. Getting started with the OneCompiler's C++ compiler is simple and pretty fast. The editor shows sample boilerplate code when you choose language as C++
and start coding!
OneCompiler's C++ online compiler supports stdin and users can give inputs to programs using the STDIN textbox under the I/O tab. Following is a sample program which takes name as input and print your name with hello.
#include <iostream>
#include <string>
using namespace std;
int main()
{
string name;
cout << "Enter name:";
getline (cin, name);
cout << "Hello " << name;
return 0;
}
C++ is a widely used middle-level programming language.
When ever you want to perform a set of operations based on a condition If-Else is used.
if(conditional-expression) {
//code
}
else {
//code
}
You can also use if-else for nested Ifs and If-Else-If ladder when multiple conditions are to be performed on a single variable.
Switch is an alternative to If-Else-If ladder.
switch(conditional-expression){
case value1:
// code
break; // optional
case value2:
// code
break; // optional
......
default:
code to be executed when all the above cases are not matched;
}
For loop is used to iterate a set of statements based on a condition.
for(Initialization; Condition; Increment/decrement){
//code
}
While is also used to iterate a set of statements based on a condition. Usually while is preferred when number of iterations are not known in advance.
while (condition) {
// code
}
Do-while is also used to iterate a set of statements based on a condition. It is mostly used when you need to execute the statements atleast once.
do {
// code
} while (condition);
Function is a sub-routine which contains set of statements. Usually functions are written when multiple calls are required to same set of statements which increases re-usuability and modularity. Function gets run only when it is called.
return_type function_name(parameters);
function_name (parameters)
return_type function_name(parameters) {
// code
}