zer0から始めるプログラミング生活

UE4,unityなどいろいろメモ

【Unreal C++】③イテレータ【UE4】

今回はレベル内のActorやObjectを検索する方法を書いていきます。
BPではGet All Actors of Classを用いて検索していました。
docs.unrealengine.com

下準備

検索元をhoge、検索先のActorをhogeActorという名前でC++クラスを作成します。
例としてhogeActorのStaticMeshComponentの位置を取得してみたいと思います。
hoge.h

#include "CoreMinimal.h"
#include "hoge.generated.h"

UCLASS()
class HOGEPROJECT_API hoge : public AActor
{
GENERATED_BODY()
	
public:	
	// Sets default values for this actor's properties
	hoge();

protected:
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;

public:	
	// Called every frame
	virtual void Tick(float DeltaTime) override;

protected:
	UPROPERTY(EditAnywhere)
		USceneComponent*Scene;
	
         UPROPERTY(EditAnywhere)
		UStaticMeshComponent* StaticMesh;
};

.cpp

#include "hoge.h"

//Set default values
hoge::hoge()
{
	// 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;
        
        Scene = CreateDefaultSubobject<USceneComponent>(TEXT("Scene"));
	RootComponent = Scene;
        StaticMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("StaticMesh"));
	StaticMesh->SetupAttachment(RootComponent);

	
}

hogeActor.h

#include "CoreMinimal.h"
#include "hogeActor.generated.h"

UCLASS()
class HOGEPROJECT_API hogeActor : public AActor
{
GENERATED_BODY()
	
public:	
	// Sets default values for this actor's properties
	hogeActor();

protected:
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;

public:	
	// Called every frame
	virtual void Tick(float DeltaTime) override;
};

hogeActor.cpp

#include "hogeActor.h"

//Set default values
hogeActor::hogeActor()
{
	// 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;
}

Iterators

UE4イテレータにはActorIteratorとObjectIteratorがあります。

ActorIterator


hoge.h

#include "CoreMinimal.h"
#include "EngineUtils.h" //TActorIterator
#include "hoge.generated.h"

UCLASS()
class HOGEPROJECT_API hoge: public AActor
{
GENERATED_BODY()
	
public:	
	// Sets default values for this actor's properties
	hogeActor();

protected:
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;
  
        UPROPERTY()
       UWorld* World;

        UPROPERTY()
        AhogeActor* hogeAct;

       UPROPERTY()
       FVector Loc;

public:	
	// Called every frame
	virtual void Tick(float DeltaTime) override;
};

TActorIteratorを使用するためにEngineUtils.hをインクルードします。
UWorld型とAhogeActor型とFVector型の変数を宣言します。


hoge.cpp

// Called when the game starts or when spawned
void Ahoge::BeginPlay()
{
	Super::BeginPlay();
	
	World = GEngine->GameViewport->GetWorld();

	for (TActorIterator<AhogeActor>hogeActorItr(World); hogeActorItr; ++hogeActorItr)
	{
		hogeAct = *hogeActorItr;
                Loc=hogeAct->StaticMesh->GetComponentLocation();
	}
}

GetWorld()でビューポート内のコンテンツを返します。
よく World=GetWorld(); だけなのを見ますが、
ver4.18現在では GEngine->GameViewport->GetWorld(); でないとダメみたいです。

BeginPlay時にWorld内に存在していれば、ヘッダファイルで宣言し、BeginPlayで検索することによって使い回せます。

	for (TActorIterator<AhogeActor>hogeActorItr(World); hogeActorItr; ++hogeActorItr)
	{
	AhogeActor* hogeAct = *hogeActorItr;
	}

のようにするとfor文の間でしか使えないので注意です。

ObjectIterator

使い方はActorIteratorと同様です。

for ( TObjectIterator<UStaticMeshComponent> Itr; Itr; ++Itr )
{
	// Access the subclass instance with the * or -> operators.
	UStaticMeshComponent *StaticMesh = *Itr;

}

【Unreal C++】②Overlapイベント【UE4】

今回はOverlapイベントについて書いていこうと思います。

分かりやすいようにTriggerBoxを作成し、そこに何かがオーバラップ(接触)したという例を示したいと思います。
docs.unrealengine.com

TriggerBoxの作成

TriggerBoxを親クラスにするとうまくいかなかったのでActorを親クラスにしてBoxコンポーネントを追加しました。
(TriggerBoxを親クラスにした場合のやり方を知ってる方は教えていただけると幸いです。)

hoge.h

#include "CoreMinimal.h"
#include "Components/BoxComponent.h"//UBoxComponent
#include "hoge.generated.h"


UCLASS()
class HOGEPROJECT_API hoge : public AActor
{
GENERATED_BODY()
	
public:	
	// Sets default values for this actor's properties
	hoge();

protected:
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;

	UPROPERTY()
		USceneComponent* Scene;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
		UBoxComponent* BoxComp;

public:	
	// Called every frame
	virtual void Tick(float DeltaTime) override;


};

UBoxComponentを使用するにはBoxComponent.hをインクルードする必要があります。
ヘッダファイルの場所は(エンジンをインストールしたフォルダ)/Engine/Source/Runtime/Engine/Classes/Components/BoxComponent.hです。


.cpp

#include "hoge.h"

//Set default values
hoge::hoge()
{
	// 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;
	Scene = CreateDefaultSubobject<USceneComponent>(TEXT("Scene"));
	RootComponent = Scene;
	BoxComp = CreateDefaultSubobject<UBoxComponent>(TEXT("CollisionComp"));
	BoxComp->SetupAttachment(RootComponent);
}

Overlapイベント

OnComponentBeginOverlap

このイベントは対象のコンポーネントに何かがOverlap(接触する)と実行されます。
BPでは↓のようなノードです。
f:id:bigden:20171116225714p:plain

hoge.h

//OnComponentBeginOverlap
	UFUNCTION()
		void OnOverlapBegin(UPrimitiveComponent* OverlappedComponent,AActor* OtherActor,UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult &SweepResult);

OnOverlapBegin関数を追加し、Overlapした際に実行したいイベントを書いていきます。
ちなみにUFUNCTION()がないとクラッシュします。

hoge.cpp

hoge::hoge()
{
	// 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;
	Scene = CreateDefaultSubobject<USceneComponent>(TEXT("Scene"));
	RootComponent = Scene;
	BoxComp = CreateDefaultSubobject<UBoxComponent>(TEXT("CollisionComp"));
	BoxComp->SetupAttachment(RootComponent);
        //↓追加
        BoxComp->OnComponentBeginOverlap.AddDynamic(this, &Ahoge::OnOverlapBegin);
}

void Ahoge::OnOverlapBegin(UPrimitiveComponent* OverlappedComponent,AActor* OtherActor,UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult &SweepResult)
{
//Overlapした際に実行したいイベント
}

AddDynamicによってOnComponentBeginOverlapと呼びたい関数をバインディングします。
これによってOverlapするとOnOverlapBeginが呼ばれます。

docs.unrealengine.com

OnComponentEndOverlap

このイベントは対象のコンポーネントへのOverlapが終了すると実行されます。
BPでは↓のようなノードです。
f:id:bigden:20171117003654p:plain

基本的にはOnComponentBeginOverlapと実装方法は同じだと思います。
Overlapした際に実行したいイベントを書く関数の引数を次のように変更します。

OnComponentOverlapEnd(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex);

OnActorBeginOverlap

このイベントは対象のActorに何かがOverlapすると実行されます。
BPでは↓のようなノードです。
f:id:bigden:20171117002843p:plain

基本的にはOnComponentBeginOverlapと実装方法は同じだと思います。
Overlapした際に実行したいイベントを書く関数の引数を次のように変更します。

OnActorOverlapBegin(AActor* OverlappedActor, AActor* OtherActor);

OnActorEndOverlap

このイベントは対象のActorへのOverlapが終了すると実行されます。
BPでは↓のようなノードです。
f:id:bigden:20171117003343p:plain

基本的にはOnComponentBeginOverlapと実装方法は同じだと思います。
Overlapした際に実行したいイベントを書く関数の引数を次のように変更します。

OnActorOverlapEnd(AActor* OverlappedActor, AActor* OtherActor);

【Unreal C++】①C++クラス作成&Component追加【UE4】

だいぶUnreal C++に慣れてきたので、備忘録として書いていこうと思います。
ver4.18を使用しています。

C++クラス作成

新しいC++クラスの追加は「コンテンツブラウザの新規追加→新しいC++クラスを追加→親クラスを選択→名前をつける→クラスを作成」で作成できます。

親クラスにActorを選択し、hogeActorと名前をつけました。

hoge.h

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "hogeActor.generated.h"

UCLASS()
class hogeProject_API AhogeActor : public AActor
{
	GENERATED_BODY()
	
public:	
	// Sets default values for this actor's properties
	AhogeActor();

protected:
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;

public:	
	// Called every frame
	virtual void Tick(float DeltaTime) override;

};

以上のコードは作成時に自動的に書いてくれています。

ちなみにver4.15からの仕様変更でCoreMinimal.hのincludeが必須に
詳しくは↓
miyahuji111.hatenablog.com


.cpp

#include "hogeActor.h"


// Sets default values
AhogeActor::AhogeActor()
{
 	// 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;

	
}

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

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

}

cppの方も以上のコードが作成時に自動的に書いてくれています。

PrimaryActorTick.bCanEverTick をtrueにしておくと、Tick処理が呼び出されます。
必要ないときはfalseにしておいたほうが高速に動くようです。

コンポーネントはコンストラクタに書いていきます。
*BeginPlayなど他の場所に書くとクラッシュします。(error吐いてほしい...)

Component追加

.h

UPROPERTY(EditAnywhere)
USceneComponent* Scene;

UFUNCTION()
void hogeFunc();

UPROPERTY()は変数のオプションを指定できます。

オプション 説明
EditAnywhere エディタ(BP,Level)内で編集○
VisibleAnywhere エディタ内で表示○、編集☓
BlueprintReadWrite BPで読み取り○、変更○
BlueprintReadOnly BPで読み取り○、変更☓
Category=" " カテゴリを指定

他にもありますが、とりあえず良く使いそうなものだけ。

.cpp

Scene = CreateDefaultSubobject<USceneComponent>(TEXT("Scene"));
RootComponent = Scene;
Widget = CreateDefaultSubobject<UWidgetComponent>(TEXT("Widget"));
Widget->SetupAttachment(RootComponent);
WidgetInteraction = CreateDefaultSubobject<UWidgetInteractionComponent>(TEXT("WidgetInteraction"));
Widget->SetupAttachment(RootComponent);

CreateDefaultSubobjectでコンポーネントを作成します。<>内はクラス名。TEXT内の("")はエディタ内で表示される名前です。
RootComponentで最上層のコンポーネントに設定します。
SetupAttachment(hoge)でhogeの下の層に設定します。

何か間違っていることがあればご指摘頂けると幸いです。

C++ (Unreal C++)エラー対処まとめ

C++のエラーの対処法をどんどん追加していきます。
UE4を使ってるのでどちらかというとunreal C++での対処法かもしれません。

コード 説明 対処法
不完全クラス型へのポインターは使用できません インクルードを忘れている。
LINK2019 未解決の外部シンボル _hoge1 が関数 _hoge2 で参照されました。 _hoge1のDocumentにModuleが書いてあるのでそれをBuild.csのPublicDependencyModuleNames.AddRangeに追加
Circular dependency detected for filename .../hoge1.h hoge1.hでhoge2.hをinclude、hoge2.hでhoge1.hをincludeしている。(このエラーでue4のプロジェクト(ver4.17)がクラッシュした)

Unreal C++ まとめ

UE4C++勉強中なので分かったことをここにどんどん追加していきます。
なにか間違いがあればご指摘お願いします。

AActor

TakeDamage(ダメージ受ける側)

.h

float Health;

.cpp

float AMyActor::TakeDamage(float Damage, struct FDamageEvent const& DamageEvent, class AController* EventInstigator, class AActor* DamageCauser)  
{  
    // Call the base class - this will tell us how much damage to apply  
    const float ActualDamage = Super::TakeDamage(Damage, DamageEvent, EventInstigator, DamageCauser);     
    if (ActualDamage > 0.f)  
    {  
        Health -= ActualDamage;    
        if (Health <= 0.f)  
        {  
           //体力が0以下になったときの処理
        }     
    }  

    return ActualDamage;  
}  

InflictDamage(ダメージを与える側)

.h

void InflictDamage();

.cpp

void AMyCharacter::InflictDamage()  
{  
    APlayerController* PlayerController = Cast<APlayerController>(GetController());  
    if (PlayerController != nullptr)  
    {  
        // Perform a trace @See LineTraceSingle  
        FHitResult TraceResult(ForceInit);  
        TraceHitForward(PlayerController, TraceResult);  

        // If the trace return an actor, inflict some damage to that actor  
        AActor* ImpactActor = TraceResult.GetActor();  //fResult(LineTraceSingleByChannelのFHitResultを使用してもいい)
        if ((ImpactActor != nullptr) && (ImpactActor != this))  
        {  
            // Create a damage event  
            TSubclassOf<UDamageType> const ValidDamageTypeClass = TSubclassOf<UDamageType>(UDamageType::StaticClass());  
            FDamageEvent DamageEvent(ValidDamageTypeClass);  

            const float DamageAmount = 25.0f; //ダメージ量  
            ImpactActor->TakeDamage(DamageAmount, DamageEvent, PlayerController, this);  
        }  
    }  
}  


BehaviorTree

Characterクラスのhoge_AICharacterとAIControllerクラスのhoge_AIControllerを作成

.h

UCLASS()
class hogeProject_API hoge_AIController : public AAIController
{
	GENERATED_BODY()

public:
	hoge_AIController(const class FObjectInitializer& ObjectInitializer);

	// UProperty 値が自動的に書き込みまたは読み出されることを許可しない
	UPROPERTY(Transient)
		class UBlackboardComponent* BlackboardComp;

	UPROPERTY(Transient)
		class UBehaviorTreeComponent* BehaviorComp;

	virtual void Possess(class APawn* InPawn);

	// BlackboardCompのKeyに対し値を設定する
	void SetEnemy(class APawn* InPawn);

	// BluePrint側でこの関数を呼び出せるように設定
	UFUNCTION(BlueprintCallable, Category = Behavior)
		void SearchForEnemy();

protected:
	uint8 EnemyKeyID;               // BlackBoardで定義したKeyID
	uint8 EnemyLocationID;  // BlackBoardで定義したKeyID
};

.cpp

hoge_AIController::hoge_AIController(const class FObjectInitializer& ObjectInitializer)
	: Super(ObjectInitializer)
{
	BlackboardComp = ObjectInitializer.CreateDefaultSubobject<UBlackboardComponent>(this, TEXT("BlackBoardComp"));

	BehaviorComp = ObjectInitializer.CreateDefaultSubobject<UBehaviorTreeComponent>(this, TEXT("BehaviorComp"));
}

void hoge_AIController::Possess(class APawn* InPawn)
{
	Super::Possess(InPawn);

	AAICharacter* Bot = Cast<AAICharacter>(InPawn);

	if (Bot && Bot->AIBehavior)
	{
		BlackboardComp->InitializeBlackboard(*Bot->AIBehavior->BlackboardAsset);

		EnemyKeyID = BlackboardComp->GetKeyID("Enemy");
		EnemyLocationID = BlackboardComp->GetKeyID("Destination");

		BehaviorComp->StartTree(*Bot->AIBehavior);
	}
}

void hoge_AIController::SearchForEnemy()
{
	APawn* MyBot = GetPawn();
	if (MyBot == NULL)
		return;

	const FVector MyLoc = MyBot->GetActorLocation();
	float BestDistSq = MAX_FLT;
	hogeCharacter* BestPawn = NULL;

	//Get All pawm in the world
	for (FConstPawnIterator It = GetWorld()->GetPawnIterator(); It; ++It)
	{
		hoge_Character* TestPawn = Cast<hoge_Character>(*It);


		if (TestPawn)
		{
			//Calculate between player and AI
			const float DistSq = FVector::Dist(TestPawn->GetActorLocation(), MyLoc);

			if (DistSq < BestDistSq)
			{
				BestDistSq = DistSq;
				BestPawn = TestPawn; // Default: BestPawn=NULL
			}
		}
	}

	if (BestPawn)
	{
		SetEnemy(BestPawn);
	}
}

void hoge_AIController::SetEnemy(class APawn* InPawn)
{
	//Store player pointer
	BlackboardComp->SetValue<UBlackboardKeyType_Object>(EnemyKeyID, InPawn);
	//Store player Location
	BlackboardComp->SetValue<UBlackboardKeyType_Vector>(EnemyLocationID, InPawn->GetActorLocation());
}

FHitResult

.cpp

//変数一覧
	FVector_NetQuantize HitLocation = fHitResult.Location;
	FVector_NetQuantize HitImpactPoint = fHitResult.ImpactPoint;
	FVector_NetQuantizeNormal HitNormal = fHitResult.Normal;
	FVector_NetQuantizeNormal HitImpactNormal = fHitResult.ImpactNormal;
        TWeakObjectPtr<AActor> HitActor = fHitResult.Actor;
	TWeakObjectPtr<UPrimitiveComponent> HitComponent = fHitResult.Component;
	FName HitBoneName = fHitResult.BoneName;
	bool HitbBlockkingHIt = fHitResult.bBlockingHit;
	int32 HitbStartPenetraing = fHitResult.bStartPenetrating;
	float HitDistance = fHitResult.Distance;
	int32 HitFaceIndex = fHitResult.FaceIndex;
	int32 HitItem = fHitResult.Item;
	float HitPenetrationDepth = fHitResult.PenetrationDepth;
	TWeakObjectPtr<UPhysicalMaterial> HitPhysMaterial = fHitResult.PhysMaterial;//if you need it functional, set fCollisionQueryParams.bReturnPhysicalMaterial = true;
	float HitTime = fHitResult.Time;
	FVector_NetQuantize HitTraceEnd = fHitResult.TraceEnd;
	FVector_NetQuantize HitTraceStart = fHitResult.TraceStart;

Log

OutputLog

「ウィンドウ→デベロッパーツール→アウトプットログ」でウィンドウを出せます。

GLog->Log("aaa");

出力:aaa

float value =1.0f;
GLog->Log(FString::SanitizeFloat(value));

出力:1.0f





FTimerManager

SetTimer(スタート)

.h

FTimerHandle _RateTimerHandle;
float CallRate = 0.1f;
bool Loop = true;

.cpp

UWorld* World = GetWorld();
	if (World)
	{
		if (mAim == true && mSprint == false) {
			World->GetTimerManager().SetTimer(_RateTimerHandle, this, &ACharacter::Fire(呼びたい処理), CallRate, Loop);
		}
	}

ClearTimer(ストップ)

.cpp

UWorld* World = GetWorld();
	World->GetTimerManager().ClearTimer(_RateTimerHandle);

USoundWave

SoundWave(インポートした音源)

.h

USoundWave* FireSound;


.cpp

static ConstructorHelpers::FObjectFinder<USoundWave>FireSoundWave(TEXT("SoundWave'/Game/Sounds/Weapon_AssaultRifle/Stereo/AssaultRifle_Shot01_Stereo.AssaultRifle_Shot01_Stereo'"));
	FireSound = FireSoundWave.Object;

//FireSoundWaveの部分は適当な名前で結構です。
//パスは目的のものを右クリック→リファレンスをコピーでとれるのでそれをTEXT("ここ")の部分に貼り付けてください。

UAnimMotage

AnimInstanceを親クラスとしたものを作成

AnimInst.h

#include "Animation/AnimInstance.h"
#include "AnimInst.generated.h"

UCLASS(transient, Blueprintable, hideCategories = AnimInstance, BlueprintType)
class hogeProject_API UAnimInst : public UAnimInstance
{
	GENERATED_UCLASS_BODY()
		
};


AnimInst.cpp

#include "(プロジェクト名).h"
#include "AnimInst.h"

UAnimInst::UAnimInst(const FObjectInitializer& ObjectInitializer)
	: Super(ObjectInitializer)
{
}

実装先

Character.h

UAnimMontage* hoge_AnimMotage;
void Fire();


Character.cpp

#include "Animation/AnimInstance.h"

ACharacter::ACharacter()
{
Mesh=CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("Mesh"));
static ConstructorHelpers::FObjectFinder<UObject>hogeMontage(TEXT("AnimMontage'(パス)'"));
	hoge_AnimMotage = (UAnimMontage*)hogeMontage.Object;
//FObjectFinder<UAnimMontage>ではエラーを吐くので、
//FObjectFinder<UObject>で取得してオブジェクトを作成するときにUAnimMontageに型を変換します。
}

void ACharacter::Fire()
{
UAnimInst* AnimInst = Cast<UAnimInst>(Mesh->GetAnimInstance());
AnimInst->Montage_Play(hoge_AnimMotage, 1.0f);

//if(AnimInst->Montage_IsPlaying(hoge_AnimMotage)){}でAnimMontageが再生しているかどうか

}

USpringArm

h

UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true"))
class USpringArmComponent* CameraBoom;


Character.cpp

CameraBoom = CreateDefaultSubobject<USpringArmComponent>(TEXT("CameraBoom"));
CameraBoom->SetupAttachment(RootComponent);
CameraBoom->TargetArmLength = 200.0f; //カメラがどのくらい後ろの位置で追従するか	
CameraBoom->bUsePawnControlRotation = true; // Rotate the arm based on the controller

UTimeline

.h

#include "Components/TimelineComponent.h"

UPROPERTY()
UTimelineComponent* ScoreTimeline;
UPROPERTY()
UCurveFloat* fCurve;
FOnTimelineFloat InterpFunction{};
UFUNCTION()
void TimelineFloatReturn(float val);


.cpp

#include "Components/TimelineComponent.h"

ACharacter::ACharacter(){
static ConstructorHelpers::FObjectFinder<UCurveFloat> Curvy(TEXT("CurveFloat'(パス)'"));
	if (Curvy.Object) {
		fCurve = Curvy.Object;
	}
	ScoreTimeline = CreateDefaultSubobject<UTimelineComponent>(TEXT("TimelineScore"));

	//Bind the Callbackfuntion for the float return value
	InterpFunction.BindUFunction(this, FName{ TEXT("TimelineFloatReturn") });
}

void ACharacter::TimelineFloatReturn(float val)
{
//タイムラインの値がここに返るvoid ACharacter::PlayTimeLineFunc()
{
         ScoreTimeline->AddInterpFloat(fCurve, InterpFunction, FName{ TEXT("Floaty") });
	 ScoreTimeline->Play();
	}
}

void A4Character::ReverseTimeLineFunc()
{
	
		ScoreTimeline->AddInterpFloat(fCurve, InterpFunction, FName{ TEXT("Floaty") });
		ScoreTimeline->Reverse();
	
}

UWorld

LineTraceSingleByChannel

.h

public:
	UPROPERTY(EditAnywhere)
		float RayLineLength = 1000;
	UPROPERTY(EditAnywhere)
		FLinearColor fLineColor;

	FHitResult fHitResult;
	FVector fStartLocation;
	FVector fEndLocation;
	float Duration;
	float Thickness;


.cpp

//get Camera
        UCameraComponent* CameraComp = this->FindComponentByClass<UCameraComponent>();

//DebugLine
	fStartLocation = CameraComp->GetComponentLocation();//ラインの始まり
	fEndLocation = fStartLocation + (CameraComp->GetForwardVector() * RayLineLength);//ラインの終わり
        fLineColor = FLinearColor(0.0, 255.0, 0.0, 0.0); //ラインの色
	Duration = 0.5; //継続時間
	Thickness = 1.0f; //ラインの厚さ

	UKismetSystemLibrary::DrawDebugLine(GetWorld(), fStartLocation, fEndLocation, fLineColor, Duration, Thickness);

//LineTrace
	FCollisionQueryParams fCollisionQueryParams;

	fCollisionQueryParams.TraceTag = FName("");
	fCollisionQueryParams.OwnerTag = FName("");
	fCollisionQueryParams.bTraceAsyncScene = false;
	fCollisionQueryParams.bTraceComplex = false;
	fCollisionQueryParams.bFindInitialOverlaps = false;
	fCollisionQueryParams.bReturnFaceIndex = false;
	fCollisionQueryParams.bReturnPhysicalMaterial = false;
	fCollisionQueryParams.bIgnoreBlocks = false;
	fCollisionQueryParams.IgnoreMask = 0;
	fCollisionQueryParams.AddIgnoredActor(this);

	GetWorld()->LineTraceSingleByChannel(fHitResult, fStartLocation, fEndLocation, ECollisionChannel::ECC_Visibility, fCollisionQueryParams);

	if (fHitResult.Actor == nullptr)
	{
		return;
	}

//OutputLog
	GLog->Log("On Hit an Actor of " + fHitResult.Actor->GetName() + "   " + FString::SanitizeFloat(my_Distance));																												

Unityまとめ

Unityの関数などをまとめ。

時間関係

ポーズ

Time.timeScale==0;//ポーズ
Time.timeScale==1;//ポーズ解除

 

delay 

---------180フレーム後に****の処理を行う---------

using UniRx;
Observable.TimerFrame(180).Subscribe(_ =>
{
****;      //delay後の処理
}).AddTo(this);

 

---------0.2秒後に****の処理を行う---------

Observable.Timer(TimeSpan.FromSeconds(0.2)).Subscribe(_ =>
{
****;     //delay後の処理
}).AddTo(this);

 

オーディオ関係

再生、停止

AudioSource BGM = GameObject.Find("****").GetComponent<AudioSource>();
BGM.Play();再生開始
BGM.Stop();一時停止

 

シーン移動

移動したいSceneを開き、「File→Build Setting→Add open scene」

SceneManager.LoadScene(1); //Build Settingのシーン番号

 

出現、消滅 

******.enabled= true;
******.enabled= false;

PCで絵を書く方法

ペンタブを使って絵を書き始めたので紹介。

 PCで絵を描くには

①ペンタブor液タブ  (マウスで描けないこともないがあったほうがいい)

②ペイントソフト

が必要です。とりあえず自分が使っているのを紹介。

 

WACOM社のIntuos Draw  (ペンタブ)

価格とメジャーな会社の製品なので選びました。必要システムを下記に示します。ドライバのインストール方法も下に示します。

どれを選べばいいか分からないって方はとりあえずWACOM社のIntuous シリーズを選べばいいかと思います。

 

ペンタブの必要システム

OS:Windows7,8,10 もしくは Mac OS X 10.8.5 以降

USBポート搭載

インターネット接続

 

②Medibang paint pro

無料で割と機能もそろっているので選びました。有料ではPhotoshop,Illustrator,Clip Studio,SAIなどがあります。ここらへんはいろんな情報がネットに落ちているので

価格と情報量の多さを比べて好みで選んでください。無料はこちらから

www.gigafree.net

 

どちらかというとこっちの必要環境を気にしたほうがいいと思います。

 

 

ペンタブのドライバのインストール

そのままUSBで繋いでも使えないので使えるようにしてあげなければいけません。

付属のCDを使うかHPからダウンロードするかの2択です。付属のCDを使う場合は説明するほどではないと思うのでHPからダウンロードする方法を紹介します。

  1. https://tablet.wacom.co.jp/download/down1.html にアクセス

  2. 自分の買ったペンタブの型番をクリック→自分のOSを選択→検索をクリック

    f:id:bigden:20161227214925p:plain

  3. 最新(一番上)のドライバのダウンロードページへをクリック

    f:id:bigden:20161227215721p:plain

  4. 下にスクロールしていくと画像のようなダウンロードボタンがあるのでクリック

    f:id:bigden:20161227215835p:plain

  5. ドライバがダウンロードされるので開く
  6. 指示にしたがってインストール(同意するぐらいなので特に気にしなくてもいい)
  7. 再起動を促されるので再起動

で完了です。