hey folks,
thanks PumpyBird for the information i will look into it later. i updated my code again. now it is possible to turn on and off the flashlight. beside this the intensity of the flashlight depends on the value of the flashlight battery. to turn off or on the flashlight you need to edit the input configurations. Input->BindAction-> add “ToggleFlashLight” and a key.
FlashLight.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "Engine.h"
#include "GameFramework/Actor.h"
#include "FlashLight.generated.h"
UCLASS()
class MYTESTFLASH_API AFlashLight : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
AFlashLight();
// Called when the game starts or when spawned
virtual void BeginPlay() override;
// Called every frame
virtual void Tick( float DeltaSeconds ) override;
UPROPERTY(EditAnywhere, Category = "Info")
UStaticMeshComponent * m_MeshComponent;
UPROPERTY(EditAnywhere, Category = "Info")
USpotLightComponent* m_SpotLight;
UPROPERTY(EditAnywhere, Category = "Info")
UTextRenderComponent* m_Text;
#if WITH_EDITOR
virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override;
#endif
UFUNCTION(BlueprintNativeEvent, Category = "Info")
void decrementBatteryValue(float DeltaTime);
UFUNCTION(BlueprintNativeEvent, Category = "Info")
void changeColor(float value);
void setBatteryValue(float value);
bool isFlashLightOn();
void setFlashLightState(bool value);
void calculateIntensity();
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Info")
float m_batteryValue;
private:
//check if the color should change over the time;
UPROPERTY(EditAnywhere, Category = "Info")
bool m_changeColor;
UPROPERTY(EditAnywhere, Category = "Info")
float m_outerAngle = 25.f;
UPROPERTY(EditAnywhere, Category = "Info")
float m_innerAngle = 10.f;
};
// Fill out your copyright notice in the Description page of Project Settings.
#include "myTestFlash.h"
#include "FlashLight.h"
// Sets default values
AFlashLight::AFlashLight()
{
// 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;
m_MeshComponent = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("FlashLightBody"));
m_MeshComponent->SetWorldScale3D(FVector(2.f, 2.0f,2.f));
RootComponent = m_MeshComponent;
m_SpotLight = CreateDefaultSubobject<USpotLightComponent>(TEXT("SpotLight"));
m_SpotLight->AttachTo(RootComponent);
m_SpotLight->InnerConeAngle = m_innerAngle;
m_SpotLight->OuterConeAngle = m_outerAngle;
m_SpotLight->SetRelativeLocation(FVector(10.0f, 0.0f, 0.0f));
m_SpotLight->SetRelativeRotation(FRotator(0.0f, 0.0f, 0.0f));
m_SpotLight->SetVisibility(true);
m_SpotLight->SetLightColor(FLinearColor(1.0f, 0.0f, 0.0f));
m_SpotLight->SetActive(true);
m_Text = CreateDefaultSubobject<UTextRenderComponent>(TEXT("TEXT"));
m_Text->SetVisibility(true);
m_Text->SetRelativeRotation(FRotator(0.0f, 180.0f, 0.0f));
m_Text->SetText(TEXT("TimerLightSource"));
m_Text->AttachTo(m_SpotLight);
m_batteryValue = 10.0f;
}
// Called when the game starts or when spawned
void AFlashLight::BeginPlay()
{
Super::BeginPlay();
}
// Called every frame
void AFlashLight::Tick( float DeltaTime )
{
Super::Tick( DeltaTime );
if (m_changeColor)
{
changeColor(DeltaTime);
}
decrementBatteryValue(DeltaTime);
}
#if WITH_EDITOR
void AFlashLight::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent)
{
Super::PostEditChangeProperty(PropertyChangedEvent);
}
#endif
void AFlashLight::changeColor_Implementation(float value)
{
float tmpA, tmpB, tmpC;
tmpA = FMath::RandRange(0, 255);
tmpB = FMath::RandRange(0, 255);
tmpC = FMath::RandRange(0, 255);
m_SpotLight->SetLightColor(FLinearColor(tmpA,tmpB,tmpC));
}
void AFlashLight::decrementBatteryValue_Implementation( float DeltaTime )
{
UWorld* const world = GetWorld();
if (world)
{
if (isFlashLightOn())
{
float deltaSeconds = DeltaTime;//GetWorld()->GetTimeSeconds();
m_batteryValue -= 0.001f;
m_Text->SetText(FText::AsNumber(m_batteryValue));
calculateIntensity();
if (m_batteryValue <= 0)
{
m_SpotLight->SetVisibility(false);
m_SpotLight->SetActive(false);
Destroy();
}
}
}
}
void AFlashLight::setBatteryValue(float value)
{
m_batteryValue = value;
}
bool AFlashLight::isFlashLightOn()
{
return m_SpotLight->IsActive();
}
void AFlashLight::setFlashLightState(bool value)
{
m_SpotLight->SetVisibility(value);
m_SpotLight->SetActive(value);
}
void AFlashLight::calculateIntensity()
{
float intensityValue = FMath::Cos(FMath::Clamp(m_batteryValue, 0.0f, 1.0f) + 0.5f * 3.14f);
intensityValue = FMath::Abs(intensityValue);
GLog->Log(FText::AsNumber(intensityValue));
intensityValue *= 100000.f;
if (intensityValue>=1800.f && intensityValue<=2100.f)
{
m_SpotLight->SetIntensity(0.0f);
}
else
{
m_SpotLight->SetIntensity(intensityValue);
}
}
Character.h
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
#pragma once
#include "GameFramework/Character.h"
#include "myTestFlashCharacter.generated.h"
class UInputComponent;
UCLASS(config=Game)
class AmyTestFlashCharacter : public ACharacter
{
GENERATED_BODY()
/** Pawn mesh: 1st person view (arms; seen only by self) */
UPROPERTY(VisibleDefaultsOnly, Category=Mesh)
class USkeletalMeshComponent* Mesh1P;
/** Gun mesh: 1st person view (seen only by self) */
UPROPERTY(VisibleDefaultsOnly, Category = Mesh)
class USkeletalMeshComponent* FP_Gun;
UPROPERTY(VisibleDefaultsOnly, Category = Mesh)
class AFlashLight* m_flashLight;
/** First person camera */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true"))
class UCameraComponent* FirstPersonCameraComponent;
public:
AmyTestFlashCharacter();
/** 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 AmyTestFlashProjectile> 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();
void OnFlashLight();
/** 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);
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
/** Returns Mesh1P subobject **/
FORCEINLINE class USkeletalMeshComponent* GetMesh1P() const { return Mesh1P; }
/** Returns FirstPersonCameraComponent subobject **/
FORCEINLINE class UCameraComponent* GetFirstPersonCameraComponent() const { return FirstPersonCameraComponent; }
};
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
#include "myTestFlash.h"
#include "myTestFlashCharacter.h"
#include "myTestFlashProjectile.h"
#include "Animation/AnimInstance.h"
#include "GameFramework/InputSettings.h"
#include "FlashLight.h"
DEFINE_LOG_CATEGORY_STATIC(LogFPChar, Warning, All);
//////////////////////////////////////////////////////////////////////////
// AmyTestFlashCharacter
AmyTestFlashCharacter::AmyTestFlashCharacter()
{
// 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;
// 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->AttachParent = FirstPersonCameraComponent;
Mesh1P->bCastDynamicShadow = false;
Mesh1P->CastShadow = false;
// Create a gun mesh component
//FP_Gun = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("FP_Gun"));
//FP_Gun->SetOnlyOwnerSee(false); // only the owning player will see this mesh
//FP_Gun->bCastDynamicShadow = false;
//FP_Gun->CastShadow = false;
//FP_Gun->AttachTo(Mesh1P, TEXT("GripPoint"), EAttachLocation::SnapToTargetIncludingScale, true);
//
//
//// Default offset from the character location for projectiles to spawn
//GunOffset = FVector(100.0f, 30.0f, 10.0f);
//m_flashLight = GetWorld()->SpawnActor<AFlashLight>(AFlashLight::StaticClass());
//UWorld* const world = GetWorld();
//if (world)
//{
// if (m_flashLight)
// {
// m_flashLight->AttachRootComponentToActor(this);
// m_flashLight->SetActorLocation(GetActorLocation());
// m_flashLight->SetActorRotation(GetActorRotation());
// }
//}
// 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++)
}
//////////////////////////////////////////////////////////////////////////
// Input
void AmyTestFlashCharacter::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->BindTouch(EInputEvent::IE_Pressed, this, &AmyTestFlashCharacter::TouchStarted);
if( EnableTouchscreenMovement(InputComponent) == false )
{
InputComponent->BindAction("Fire", IE_Pressed, this, &AmyTestFlashCharacter::OnFire);
}
InputComponent->BindAction("ToggleFlashLight", IE_Pressed, this, &AmyTestFlashCharacter::OnFlashLight);
InputComponent->BindAxis("MoveForward", this, &AmyTestFlashCharacter::MoveForward);
InputComponent->BindAxis("MoveRight", this, &AmyTestFlashCharacter::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, &AmyTestFlashCharacter::TurnAtRate);
InputComponent->BindAxis("LookUp", this, &APawn::AddControllerPitchInput);
InputComponent->BindAxis("LookUpRate", this, &AmyTestFlashCharacter::LookUpAtRate);
}
void AmyTestFlashCharacter::OnFlashLight()
{
if (m_flashLight)
{
if (m_flashLight->isFlashLightOn())
{
m_flashLight->setFlashLightState(false);
}
else
{
m_flashLight->setFlashLightState(true);
}
}
}
void AmyTestFlashCharacter::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<AmyTestFlashProjectile>(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 AmyTestFlashCharacter::BeginPlay()
{
Super::BeginPlay();
UWorld* const world = GetWorld();
m_flashLight = world->SpawnActor<AFlashLight>(AFlashLight::StaticClass());
if (world)
{
if (m_flashLight)
{
m_flashLight->AttachRootComponentTo(this->Mesh1P);
m_flashLight->SetActorLocation(GetActorLocation());
m_flashLight->SetActorRotation(GetActorRotation());
m_flashLight->setBatteryValue(1.0f);
m_flashLight->m_SpotLight->SetLightColor(FLinearColor(0.0f, 1.0f, 0.0f));
}
}
}
void AmyTestFlashCharacter::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 AmyTestFlashCharacter::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 AmyTestFlashCharacter::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 AmyTestFlashCharacter::MoveForward(float Value)
{
if (Value != 0.0f)
{
// add movement in that direction
AddMovementInput(GetActorForwardVector(), Value);
}
}
void AmyTestFlashCharacter::MoveRight(float Value)
{
if (Value != 0.0f)
{
// add movement in that direction
AddMovementInput(GetActorRightVector(), Value);
}
}
void AmyTestFlashCharacter::TurnAtRate(float Rate)
{
// calculate delta for this frame from the rate information
AddControllerYawInput(Rate * BaseTurnRate * GetWorld()->GetDeltaSeconds());
}
void AmyTestFlashCharacter::LookUpAtRate(float Rate)
{
// calculate delta for this frame from the rate information
AddControllerPitchInput(Rate * BaseLookUpRate * GetWorld()->GetDeltaSeconds());
}
bool AmyTestFlashCharacter::EnableTouchscreenMovement(class UInputComponent* InputComponent)
{
bool bResult = false;
if(FPlatformMisc::GetUseVirtualJoysticks() || GetDefault<UInputSettings>()->bUseMouseForTouch )
{
bResult = true;
InputComponent->BindTouch(EInputEvent::IE_Pressed, this, &AmyTestFlashCharacter::BeginTouch);
InputComponent->BindTouch(EInputEvent::IE_Released, this, &AmyTestFlashCharacter::EndTouch);
InputComponent->BindTouch(EInputEvent::IE_Repeat, this, &AmyTestFlashCharacter::TouchUpdate);
}
return bResult;
}
Best Regards