FlashLight

Hello Folks,

i´m new to UnrealEngine but did some practice in the last few days. what i
now want to do is to create a flashlight class which is editable over
blueprint and/or editor. So far i know some of the macros to get this
things working in Unrealeditor and Blueprint but what i want to know is
how i setup a flashlight. like a recipe. I think i go in the wrong
direction so maybe someone can help me.

so what i did so far:

setup a project (done)
add a cpp-file which derived from Actor (done)
added some code and compile it (done)

Header - File:


// Fill out your copyright notice in the Description page of Project
Settings.

#pragma once

#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")
    float m_batteryValue;

    UPROPERTY(EditAnywhere, Category = "Info")
    float m_outerAngle;

    UPROPERTY(EditAnywhere, Category = "Info")
    float m_innerAngle;
};

CPP-File


// 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));

}

// Called when the game starts or when spawned
void AFlashLight::BeginPlay()
{
    Super::BeginPlay();
    
}

// Called every frame
void AFlashLight::Tick( float DeltaTime )
{
    Super::Tick( DeltaTime );

}

ok, that´s it for now. i´ve some membervariables which should be editable
like the inner- and outerangle and a value of the batterylifetime which
can be decrement in the tick methode. i know that i need to implement some
more functions like to set on the light or off. but is this the right way
i´m pointing and can someone give some tips how i can attach this
Actor/Mesh to my FirstPersonCharacter form the Templates?

Many thanks in advance

Best Regards

change


   m_SpotLight->AttachTo(RootComponent);

to


 m_Spotlight->AttachParent = RootComponent; 

That’s the better way to setup child component relationships.

But it looks like you’re doing everything pretty much right. At this point I would edit your character/pawn class, and get a way to attach the flashlight. Here’s a headstart, this code should spawn your flashlight to your character when you spawn. But you’ll have to do some editing to get it right.

YourCharacter.cpp=



#include "AFlashLihgt.h" //this tells your character that the flashlight exists.

void YourCharacter::BeginPlay()
{
 Super::BeginPlay(); //calls everything in the parent class version of this function

 AFlashLight* Flashlight = GetWorld()->SpawnActor<AFlashLight>(AFlashLight::StaticClass());

if(Flashlight) //make sure we spawned
{
 Flashlight->AttachRootComponentToActor(this);
 Flashlight->SetActorLocation(GetActorLocation());
 Flashlight->SetActorRotation(GetActorRotation());
}
}


I’m not so sure this is true, from what I can tell ‘AttachTo’ boils down to setting the ‘AttachParent’ but does some extra checking, has more features and calls the ‘OnAttachmentChanged’ method.

That very well may be. As I haven’t done an in-depth look at it. But I was under the impression that you use AttachParent during the construction script and then during the construction, the engine code goes in and does all the needed AttachTo stuff in a much safer manner for construction as well as make sure it’s good to go when you make a blueprint class off of it and do all the editor-based stuff.

AttachTo() is definitely what you use during RunTime. But I believe AttachParent is for Construction.

But I could be wrong!

Hello you two,

thanks for the reply and i will look into it. i have another question, maybe i understand unreal engine wrong with his component-system. but what i want to do now, is to attach in the constructor a mesh object, like a flashlight model, to the “UStaticMeshComponent”. is this the wrong way to do that? here is an update source code



// 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 decrementBatterValue(float DeltaTime);

	UFUNCTION(BlueprintNativeEvent, Category = "Info")
	void changeColor(float value);

	//check if the color should change over the time;
	UPROPERTY(EditAnywhere, Category = "Info")
	bool m_changeColor;

	UPROPERTY(EditAnywhere, Category = "Info")
	float m_batteryValue;

	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);
	}
	decrementBatterValue(DeltaTime);

}

#if WITH_EDITOR
void AFlashLight::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent)
{
	Super::PostEditChangeProperty(PropertyChangedEvent);
}
#endif


void AFlashLight::changeColor_Implementation(float value)
{
	m_SpotLight->SetLightColor(FLinearColor(0,value*10.0f,0));
}

void AFlashLight::decrementBatterValue_Implementation(float DeltaTime)
{

	if (GetWorld())
	{
		if (m_SpotLight->IsActive())
		{
			float deltaSeconds = DeltaTime;//GetWorld()->GetTimeSeconds();
			m_batteryValue -= deltaSeconds;
			FString tmpString = FString::SanitizeFloat(m_batteryValue);
			m_Text->SetText(tmpString);
			if (m_batteryValue <= 0)
			{
				m_SpotLight->SetVisibility(false);
				m_SpotLight->SetActive(false);
				Destroy();
			}
		}
	}
	

}

Best Regards and thanks

hello folks,

i update my source. so here you have (thanks to IrishKilter) the source code. it isn´t pretty nice but for the first it does it´s job.

FlashLight Header-File


// 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 decrementBatterValue(float DeltaTime);

	UFUNCTION(BlueprintNativeEvent, Category = "Info")
	void changeColor(float value);

	void setBatteryValue(float value);
	bool isFlashLightOn();

	void setFlashLightState(bool value);

private:
	//check if the color should change over the time;
	UPROPERTY(EditAnywhere, Category = "Info")
	bool m_changeColor;

	UPROPERTY(EditAnywhere, Category = "Info")
	float m_batteryValue;

	UPROPERTY(EditAnywhere, Category = "Info")
	float m_outerAngle = 25.f;

	UPROPERTY(EditAnywhere, Category = "Info")
	float m_innerAngle = 10.f;
};


FlashLight Cpp-File


// 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);
	}
	decrementBatterValue(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::decrementBatterValue_Implementation( float DeltaTime )
{

	UWorld* const world = GetWorld();
	if (world)
	{
		if (isFlashLightOn())
		{
			float deltaSeconds = DeltaTime;//GetWorld()->GetTimeSeconds();
			m_batteryValue -= deltaSeconds;
			FText tmpString = FText::AsNumber(m_batteryValue);
			m_Text->SetText(tmpString);
			GLog->Log(tmpString);
			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->SetActive(value);
}

some changes have to be done in the playerclass

Character Header File


// 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();

	/** 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; }

};



Character Cpp-File


// 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);
	

	// 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->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::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();

	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());
			m_flashLight->setBatteryValue(100.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

Add something like this to your constructor to set the draw mesh.

ConstructorHelpers::FObjectFinder<UStaticMesh> FlashlightBodyObject(TEXT(“copy the mesh reference by right clicking and paste it here”));

m_MeshComponent->SetMesh(FlashlightBodyObject.Object);

I’m typing this from memory so it might be a bit off.

EDIT
If you are using a skeletal mesh for your flashlight then just replace UStaticMesh with USkeletalMesh and SetMesh with SetSkeletalMesh I think.

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

hey,

one more question. do i have to delete the pointers manually like m_MeshComponent or m_Spotlight? If i set this object to be “destory” the pointer won´t be set free?!

King Regards

Objects in unreal engine are reference counted and garbage collected.

If you destroy the character the flashlight will have no references and it will be destroyed eventually as well.