-
-
Save koras/6a1d2b703abccbb51f81ae2bb62fb2f9 to your computer and use it in GitHub Desktop.
Usable Item
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved. | |
#include "ItemSample.h" | |
#include "ItemSampleCharacter.h" | |
#include "ItemSampleProjectile.h" | |
#include "Animation/AnimInstance.h" | |
#include "UsableItem.h" | |
#include "GameFramework/InputSettings.h" | |
DEFINE_LOG_CATEGORY_STATIC(LogFPChar, Warning, All); | |
////////////////////////////////////////////////////////////////////////// | |
// AItemSampleCharacter | |
AItemSampleCharacter::AItemSampleCharacter() | |
{ | |
// Set size for collision capsule | |
GetCapsuleComponent()->InitCapsuleSize(42.f, 96.0f); | |
// set our turn rates for input | |
BaseTurnRate = 45.f; | |
BaseLookUpRate = 45.f; | |
// Create a CameraComponent | |
FirstPersonCameraComponent = CreateDefaultSubobject<UCameraComponent>(TEXT("FirstPersonCamera")); | |
FirstPersonCameraComponent->AttachParent = GetCapsuleComponent(); | |
FirstPersonCameraComponent->RelativeLocation = FVector(0, 0, 64.f); // Position the camera | |
FirstPersonCameraComponent->bUsePawnControlRotation = true; | |
// Default offset from the character location for projectiles to spawn | |
GunOffset = FVector(100.0f, 30.0f, 10.0f); | |
// 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); // only the owning player will see this mesh | |
Mesh1P->AttachParent = FirstPersonCameraComponent; | |
Mesh1P->RelativeLocation = FVector(0.f, 0.f, -150.f); | |
Mesh1P->bCastDynamicShadow = false; | |
Mesh1P->CastShadow = false; | |
//Included in 4.7, needs to be added in 4.8 | |
PrimaryActorTick.bCanEverTick = true; | |
// Note: The ProjectileClass and the skeletal mesh/anim blueprints for Mesh1P are set in the | |
// derived blueprint asset named MyCharacter (to avoid direct content references in C++) | |
} | |
// Called every frame -- Included in 4.7, needs to be added in 4.8 | |
void AItemSampleCharacter::Tick(float DeltaTime) | |
{ | |
Super::Tick(DeltaTime); | |
AUsableItem* itemSeen = GetItemFocus(); | |
static AUsableItem* oldFocus = NULL; | |
oldFocus = ApplyPostProcessing(itemSeen, oldFocus); | |
} | |
////////////////////////////////////////////////////////////////////////// | |
// Input | |
void AItemSampleCharacter::SetupPlayerInputComponent(class UInputComponent* InputComponent) | |
{ | |
// set up gameplay key bindings | |
check(InputComponent); | |
InputComponent->BindAction("Jump", IE_Pressed, this, &ACharacter::Jump); | |
InputComponent->BindAction("Jump", IE_Released, this, &ACharacter::StopJumping); | |
InputComponent->BindAction("Take", IE_Pressed, this, &AItemSampleCharacter::Use); | |
//InputComponent->BindTouch(EInputEvent::IE_Pressed, this, &AItemSampleCharacter::TouchStarted); | |
if( EnableTouchscreenMovement(InputComponent) == false ) | |
{ | |
InputComponent->BindAction("Fire", IE_Pressed, this, &AItemSampleCharacter::OnFire); | |
} | |
InputComponent->BindAxis("MoveForward", this, &AItemSampleCharacter::MoveForward); | |
InputComponent->BindAxis("MoveRight", this, &AItemSampleCharacter::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 | |
InputComponent->BindAxis("Turn", this, &APawn::AddControllerYawInput); | |
InputComponent->BindAxis("TurnRate", this, &AItemSampleCharacter::TurnAtRate); | |
InputComponent->BindAxis("LookUp", this, &APawn::AddControllerPitchInput); | |
InputComponent->BindAxis("LookUpRate", this, &AItemSampleCharacter::LookUpAtRate); | |
} | |
void AItemSampleCharacter::Use(){ | |
if (GetItemFocus()){ | |
GetItemFocus()->GetStaticMeshComponent()->DestroyComponent(); | |
} | |
} | |
void AItemSampleCharacter::OnFire() | |
{ | |
// try and fire a projectile | |
if (ProjectileClass != NULL) | |
{ | |
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 = GetActorLocation() + SpawnRotation.RotateVector(GunOffset); | |
UWorld* const World = GetWorld(); | |
if (World != NULL) | |
{ | |
// spawn the projectile at the muzzle | |
World->SpawnActor<AItemSampleProjectile>(ProjectileClass, SpawnLocation, SpawnRotation); | |
} | |
} | |
// 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); | |
} | |
} | |
} | |
void AItemSampleCharacter::BeginTouch(const ETouchIndex::Type FingerIndex, const FVector Location) | |
{ | |
if( TouchItem.bIsPressed == true ) | |
{ | |
return; | |
} | |
TouchItem.bIsPressed = true; | |
TouchItem.FingerIndex = FingerIndex; | |
TouchItem.Location = Location; | |
TouchItem.bMoved = false; | |
} | |
void AItemSampleCharacter::EndTouch(const ETouchIndex::Type FingerIndex, const FVector Location) | |
{ | |
if (TouchItem.bIsPressed == false) | |
{ | |
return; | |
} | |
if( ( FingerIndex == TouchItem.FingerIndex ) && (TouchItem.bMoved == false) ) | |
{ | |
OnFire(); | |
} | |
TouchItem.bIsPressed = false; | |
} | |
void AItemSampleCharacter::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 (ScaledDelta.X != 0.0f) | |
{ | |
TouchItem.bMoved = true; | |
float Value = ScaledDelta.X * BaseTurnRate; | |
AddControllerYawInput(Value); | |
} | |
if (ScaledDelta.Y != 0.0f) | |
{ | |
TouchItem.bMoved = true; | |
float Value = ScaledDelta.Y* BaseTurnRate; | |
AddControllerPitchInput(Value); | |
} | |
TouchItem.Location = Location; | |
} | |
TouchItem.Location = Location; | |
} | |
} | |
} | |
} | |
void AItemSampleCharacter::MoveForward(float Value) | |
{ | |
if (Value != 0.0f) | |
{ | |
// add movement in that direction | |
AddMovementInput(GetActorForwardVector(), Value); | |
} | |
} | |
void AItemSampleCharacter::MoveRight(float Value) | |
{ | |
if (Value != 0.0f) | |
{ | |
// add movement in that direction | |
AddMovementInput(GetActorRightVector(), Value); | |
} | |
} | |
void AItemSampleCharacter::TurnAtRate(float Rate) | |
{ | |
// calculate delta for this frame from the rate information | |
AddControllerYawInput(Rate * BaseTurnRate * GetWorld()->GetDeltaSeconds()); | |
} | |
void AItemSampleCharacter::LookUpAtRate(float Rate) | |
{ | |
// calculate delta for this frame from the rate information | |
AddControllerPitchInput(Rate * BaseLookUpRate * GetWorld()->GetDeltaSeconds()); | |
} | |
bool AItemSampleCharacter::EnableTouchscreenMovement(class UInputComponent* InputComponent) | |
{ | |
bool bResult = false; | |
if(FPlatformMisc::GetUseVirtualJoysticks() || GetDefault<UInputSettings>()->bUseMouseForTouch ) | |
{ | |
bResult = true; | |
InputComponent->BindTouch(EInputEvent::IE_Pressed, this, &AItemSampleCharacter::BeginTouch); | |
InputComponent->BindTouch(EInputEvent::IE_Released, this, &AItemSampleCharacter::EndTouch); | |
InputComponent->BindTouch(EInputEvent::IE_Repeat, this, &AItemSampleCharacter::TouchUpdate); | |
} | |
return bResult; | |
} | |
AUsableItem* AItemSampleCharacter::ApplyPostProcessing(AUsableItem* itemSeen, AUsableItem* oldFocus){ | |
if (itemSeen){ | |
// An item is currently being looked at | |
if (itemSeen == oldFocus || oldFocus == NULL){ | |
//The item being looked at is the same as the one on the last tick | |
UStaticMeshComponent* mesh = itemSeen->GetStaticMeshComponent(); | |
mesh->SetRenderCustomDepth(true); | |
} | |
else if (oldFocus != NULL){ | |
// An item is being looked at and the old focus was not null (and not the same as the one on the last tick) | |
UStaticMeshComponent* mesh = itemSeen->GetStaticMeshComponent(); | |
mesh->SetRenderCustomDepth(true); | |
UStaticMeshComponent* oldMesh = oldFocus->GetStaticMeshComponent(); | |
oldMesh->SetRenderCustomDepth(false); | |
} | |
return oldFocus = itemSeen; | |
} | |
else{ | |
// No item currectly being looked at | |
if (oldFocus != NULL){ | |
//An item was looked at last tick but isn't being looked at anymore | |
UStaticMeshComponent* mesh = oldFocus->GetStaticMeshComponent(); | |
mesh->SetRenderCustomDepth(false); | |
} | |
return oldFocus = NULL; | |
} | |
} | |
AUsableItem* AItemSampleCharacter::GetItemFocus(){ | |
// Attempt to use Raycasts to view an object and echo it back | |
FVector CameraLocation; | |
FRotator CameraRotation; | |
Controller->GetPlayerViewPoint(CameraLocation, CameraRotation); | |
const FVector StartTrace = CameraLocation; | |
const FVector Direction = CameraRotation.Vector(); | |
const FVector EndTrace = StartTrace + Direction * 300; //where 300 is the distance it checks | |
FCollisionQueryParams TraceParams(FName(TEXT("")), true, this); | |
TraceParams.bTraceAsyncScene = true; | |
TraceParams.bReturnPhysicalMaterial = true; | |
FHitResult Hit(ForceInit); | |
GetWorld()->LineTraceSingleByChannel(Hit, StartTrace, EndTrace, COLLISION_VIEW, TraceParams); | |
return Cast<AUsableItem>(Hit.GetActor()); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved. | |
#pragma once | |
#include "GameFramework/Character.h" | |
#include "ItemSampleCharacter.generated.h" | |
class UInputComponent; | |
UCLASS(config=Game) | |
class AItemSampleCharacter : public ACharacter | |
{ | |
GENERATED_BODY() | |
/** Pawn mesh: 1st person view (arms; seen only by self) */ | |
UPROPERTY(VisibleDefaultsOnly, Category=Mesh) | |
class USkeletalMeshComponent* Mesh1P; | |
/** First person camera */ | |
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true")) | |
class UCameraComponent* FirstPersonCameraComponent; | |
public: | |
AItemSampleCharacter(); | |
/** Base turn rate, in deg/sec. Other scaling may affect final turn rate. */ | |
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category=Camera) | |
float BaseTurnRate; | |
/** Base look up/down rate, in deg/sec. Other scaling may affect final rate. */ | |
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category=Camera) | |
float BaseLookUpRate; | |
/** Gun muzzle's offset from the characters location */ | |
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=Gameplay) | |
FVector GunOffset; | |
/** Projectile class to spawn */ | |
UPROPERTY(EditDefaultsOnly, Category=Projectile) | |
TSubclassOf<class AItemSampleProjectile> ProjectileClass; | |
/** Sound to play each time we fire */ | |
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=Gameplay) | |
class USoundBase* FireSound; | |
/** AnimMontage to play each time we fire */ | |
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Gameplay) | |
class UAnimMontage* FireAnimation; | |
protected: | |
/** Fires a projectile. */ | |
void OnFire(); | |
// New Class for ItemSampleProject | |
void Use(); | |
/** Handles moving forward/backward */ | |
void MoveForward(float Val); | |
/** Handles stafing movement, left and right */ | |
void MoveRight(float Val); | |
/** | |
* Called via input to turn at a given rate. | |
* @param Rate This is a normalized rate, i.e. 1.0 means 100% of desired turn rate | |
*/ | |
void TurnAtRate(float Rate); | |
/** | |
* Called via input to turn look up/down at a given rate. | |
* @param Rate This is a normalized rate, i.e. 1.0 means 100% of desired turn rate | |
*/ | |
void LookUpAtRate(float Rate); | |
struct TouchData | |
{ | |
TouchData() { bIsPressed = false;Location=FVector::ZeroVector;} | |
bool bIsPressed; | |
ETouchIndex::Type FingerIndex; | |
FVector Location; | |
bool bMoved; | |
}; | |
void BeginTouch(const ETouchIndex::Type FingerIndex, const FVector Location); | |
void EndTouch(const ETouchIndex::Type FingerIndex, const FVector Location); | |
void TouchUpdate(const ETouchIndex::Type FingerIndex, const FVector Location); | |
TouchData TouchItem; | |
protected: | |
// APawn interface | |
virtual void SetupPlayerInputComponent(UInputComponent* InputComponent) override; | |
// End of APawn interface | |
/* | |
* Configures input for touchscreen devices if there is a valid touch interface for doing so | |
* | |
* @param InputComponent The input component pointer to bind controls to | |
* @returns true if touch controls were enabled. | |
*/ | |
bool EnableTouchscreenMovement(UInputComponent* InputComponent); | |
public: | |
/** Returns Mesh1P subobject **/ | |
FORCEINLINE class USkeletalMeshComponent* GetMesh1P() const { return Mesh1P; } | |
/** Returns FirstPersonCameraComponent subobject **/ | |
FORCEINLINE class UCameraComponent* GetFirstPersonCameraComponent() const { return FirstPersonCameraComponent; } | |
// Called every frame | |
virtual void Tick(float DeltaSeconds) override; | |
// New classes for ItemSampleProject | |
class AUsableItem* GetItemFocus(); | |
class AUsableItem* ApplyPostProcessing(AUsableItem* itemSeen, AUsableItem* oldFocus); | |
}; | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "lark.h" | |
#include "UsableItem.h" | |
// Sets default values | |
AUsableItem::AUsableItem(const class FObjectInitializer& PCIP) : Super(PCIP) | |
{ | |
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it. | |
PrimaryActorTick.bCanEverTick = true; | |
SetMobility(EComponentMobility::Movable); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include "GameFramework/Actor.h" | |
#include "UsableItem.generated.h" | |
UCLASS() | |
class AUsableItem : public AStaticMeshActor | |
{ | |
GENERATED_BODY() | |
public: | |
AUsableItem(const class FObjectInitializer& PCIP); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment