書評してみる これからの「正義」の話をしよう

この本を一冊読み終わるのに結局3週間近くかかってしまった。 政治哲学の話で難しかったことと最近残業続きで本がなかなか読めなかったことが原因。土日に本を読んでも寝落ちして進まないのも原因。 あと著作権的にあんまりよくないかもしれないけど、YouTubeに上がっていたサンデル教授の講義もみた。

この作者が言いたかったことに関しては本屋に行って10章だけ読んでもらうか別の書評などで書かれていることだと思うからここでは省略。

僕の印象に残った個所

ハーバード大学の学生たちにサンデル教授が才能、そして努力までもが恣意的な要素によるものであることを説明するとき、「自分が第一子である人、手を挙げて」と手を上げさせるシーンが印象に残った。

ハーバード大学に行く8割が富裕層ハーバード大学に行く8割が第一子であった。(第一子:努力する人の割合が高いらしい) この事実から学生が、自分たちは自分の頑張りでこのハーバード大学に入ったと主張していた学生含め、反論できなくなった。

生まれながらにして人は恣意的な要素がある(不平等である)。 自分がどんな人間であるかをいったん忘れてしまい(無知のベール)考えると、自分が弱者側になってしまった時の事を考え、一定の補助をするべきだと考える。 これが一つの正義のあり方らしい。

それを形にしたのが現在当たり前のように天引きされている税金(累進課税)である。

感想

今まで税金とか本当の意味でどうして払う必要があるのかについて考えることがなく、払う必要があるのかとさえ思っていた。 しかし、こうやって勉強すると正義・公正の観点から確実に税金を納めること自体は良いことなんだなと感じた。(日本の税金の使い道に関しては多少問題があるだろうが)

本当に国語とか数学とかどうでもいいから、こういうこと学校で教えてほしかった。 国民投票があるような民主主義の国(日本など)の国民が無知であることは本当に怖いなと。

国民のあれしろ、これするな、という声の意図が、本当に国としてどうあるべきか、ということ考えての声であればよいが、そうでない場合のほうが多いだろうから。 政府を擁護するわけではないけれども、大変だろうなと思った。

UE_LOGでプリントして値確認するのってめんどくさいよね

UE4でprintデバッグしてますか?
もちろん優秀なデバッガーがVisualStudioにしろXcodeにしろあるのでそちらを使うべきですが、printで値を確認したい時はあるはず。
ざっと書いて確認してすぐ消す。
そういった用途で使用するときはUE_LOGでやるには少しめんどくさいですよね(名前の通りLOGなのでそもそもprintデバッグするためのものではない)

簡単にprintデバッグできるように簡単なコードを書いてみました。 ほとんどFString::Printfのパクリですが。

Debug.h

class Debug
{
public:
    static void Print(const TCHAR* Text, ...);
};

#define print(text, ...) Debug::Print(TEXT(text), ## __VA_ARGS__)

Debug.cpp

void Debug::Print(const TCHAR* Text, ...)
{
    const static int32 LOG_BUFFER_SIZE    = 512;
    int32   BufferSize                  = LOG_BUFFER_SIZE;
    TCHAR   StartingBuffer[LOG_BUFFER_SIZE];
    TCHAR*  Buffer                      = StartingBuffer;
    int32   Result                      = -1;
    
    GET_VARARGS_RESULT( Buffer, BufferSize, BufferSize-1, Text, Text, Result );
    
    if( Result == -1 )
    {
        Buffer = nullptr;
        while(Result == -1)
        {
            BufferSize *= 2;
            Buffer = (TCHAR*) FMemory::Realloc( Buffer, BufferSize * sizeof(TCHAR) );
            GET_VARARGS_RESULT( Buffer, BufferSize, BufferSize-1, Text, Text, Result );
        };
    }
    
    Buffer[Result] = 0;
    
    GEngine->AddOnScreenDebugMessage(-1, 1.5, FColor::White,Buffer);
    UE_LOG(LogTemp, Log, TEXT("%s"), Buffer);
    
    if( BufferSize != LOG_BUFFER_SIZE )
    {
        FMemory::Free( Buffer );
    }
}

上のコードを使用した例とUE_LOGを使用した例を見比べてみましょう。

UE_LOGを使用した例

UE_LOG(LogTemp, Warning, TEXT("%d"), num);

上のコードを使用した例

print("%d", num);

だいぶすっきりしました!
これでprintデバッグがはかどりますね!

バロンチェアを4ヶ月使ってみた感想

高級オフィスチェアである「バロンチェア」の座り心地。高いものだけれど一回座っただけじゃ分からないという人は多いのではないでしょうか。 そこで、今回はバロンチェア4ヶ月ユーザーの私が使用した感想をまとめてみました。

座ってみた感想

ヘッドレストが邪魔

意外とヘッドレストは邪魔に感じることが多い箇所でした。
後傾姿勢サイコー!ではありますが、それでも稀にちょくちょく前傾で作業することがあります。
前傾になるとヘッドレストが若干前に出てきているため、肩の上に頭が乗らず肩がこってしまいます。
折角可動ヘッドレストなのに、後ろ側に可動してくれず邪魔してくるというのはいかがなものかと。
ただ、念を押しておくと後傾姿勢の時のヘッドレストは最高。

ランバーサポートが痛い

支えてくれている感は確かにあるのですが、硬いものを押し付けられているという印象が強く、背骨にあたって痛くなり休憩、という状態でした。
我慢して数ヶ月使ってきましたが、結局外したほうが快適に座れるようになりました。
ただし、個人差はあると思うので実際に座って確かめてみることをおすすめします。

グラつきがある

後傾姿勢で作業しているときは全然気にならないのですが、前傾姿勢で作業している時に軸が緩んでいるのかグラつきを感じます。
高級オフィスチェアだからグラつきはないだろうと思い込んでいた分これが一番残念だった点です。
ただ、ネットで調べてみた限り同様の症状で悩んでいる人がいなかったので、グラつきやすい椅子、というわけではなさそう。

おわりに

いかがでしたでしょうか。
あまり良い点が書かれていないのはバロンチェアが良くないからでは決してなく、良いものである前提(値段的にも評判的にも)があるからです。
高い買い物であることは間違いないので、自分にあった椅子を買いたいですよね。
いろいろなところで言われていることではありますが、できれば何度も座らせてもらうのが一番です。
高級オフィスチェアの購入を考えている方の参考になれたら幸いです。

UE4で作ったアプリをパッケージ化してiPhoneで動かせるようにする

雑談

今日はじめてカレーメシを買って食べました。
Youtuberの瀬戸弘司(ミツアキTV)が出してるカレーメシの動画を見て、美味しそうで速攻買いに行きました。
たまに食べる分にはおいしくて良さそうです。似た商品でカップヌードル版もあったので、いつか食べてみたいです。

はじめに

この記事では、UE4で作成したアプリをiPhoneで動かす手順について解説していきます。
今回はMacを使ってipaを作成するところまで行いたいと思います。

目次

  1. provisioning profileとは?
  2. provisioning profileの生成
  3. UE4に生成したprovisioning profileを設定
  4. UE4でipaの生成

1. provisioning profileとは?

provisioning profile(プロビジョニングプロファイル)とは?と聞かれても私もよく知らないのですが、いわゆるAppleに対して使われる「証明書」です。
これがないとアプリを公開することができないばかりか、ipaファイルの作成さえできません。
これはUE4を使用しても同じように必要でprovisioning profileがないとipaの生成に失敗してしまいます。

provisioning profileは開発者登録(有料)をしなければ作成することはできなかったのですが、いつの間にか開発用に使う場合には無料で簡単に作成できるようになってしました。(お金払うだけならいいですが、開発機の登録だったり全部英語だったりとか面倒だったのでとても楽になりました)
UE4ではprovisioning profileは自動生成してもらえないので、Xcodeで別のプロジェクトでprovisioning profileを生成することができます。

2. provisioning profileの生成

まず、Xcodeを立ち上げます。(持ってない方はインストールしてください)
「Create a new Xcode project」を選択してプロジェクトを新規作成します。

f:id:u16kuma:20160618192748p:plain

こんな感じでプロジェクトのテンプレートを選択できるウィンドウが表示されるので、「Single View Application」を選択して「Next」を押します。
(おそらくiOS > Application内のテンプレートなら何でも良いはず)

f:id:u16kuma:20160618192713p:plain

プロジェクトの設定を入れるウィンドウが表示されます。
ここで大事なのは下の画像で赤枠の中にある「Product Name」と「Organization Identifier」です。
ここで入力する値は適当で構わないですが、ここで入力した赤枠は2つつなげて「Bundle Identifier」という識別子で使われます。

f:id:u16kuma:20160618193407p:plain

上の赤枠に先ほど入力した「Product Name」と「Organization Identifier」が繋げて「Bundle Identifier」という識別子が設定されています。
この値はあとで使用するので覚えておいてください。
下の赤枠に「Fix Issue」というボタンを押すことで、provisioning profileが作成されます。

f:id:u16kuma:20160618192506p:plain

Xcode > Preferences > Accountsの右下にある「View Detail」を押すとprovisioning profileのリストが表示されます。
今回作成したprovisioning profileを右クリックして「Show in Finder」を選択することでprovisioning profileが保存されている場所が開きます。
これもあとで使用するので、自分のわかる場所にコピーしておいてください。

3. UE4に生成したprovisioning profileを設定

1で作成したprovisioning profileとBundle Identifierをプロジェクトに設定していきます。
まず、Unreal Editor> 編集 > プロジェクト設定でプロジェクト設定ウィンドウを開きます。
プロジェクト設定 > プラットフォーム > iOSを選択します。

すると以下のような状態になっていると思います。
「Mobile Provision」内に「プロビジョニングプロファイルをインポートする」というボタンがあるので先ほど作成したプロビジョニングプロファイルを選択します。
「Bundle Infomation」内に「Bundle Identifier」という項目があるので、先ほどXcodeのプロジェクトで設定したBundle Identifierを設定します。

f:id:u16kuma:20160618193634p:plain

3. UE4でipaの生成

Unreal Editor > ファイル > プロジェクトをパッケージ化 > iOSを選択するとビルドが開始され、しばらく待つとipaが生成されます。

UE4で単体テストしてみよう!

はじめに

GameServerDevelopersという勉強会に参加してきました!
あんまりサーバーとかよくわからないですが、いろいろ勉強になりました!
この高揚が収まらないうちに全く関係ない記事を書き終えようと思います!
それでは、UE4とC++にて単体テストを書いていきましょう!

環境

Windows10
Visual Studio 2015
Unreal Engine 4. 11.2

ソースファイルの作成

[プロジェクト名]/Private/Testsフォルダを作成してその階層化にMyTest.cppを作成します。
このファイルにテストをこれから実際に書いていきます。
ヘッダーファイルも同時に作成した場合は、特に使うことはないのでゴミ箱にポイしてください。

[プロジェクト名]/Private/Tests/MyTest.cpp

プログラムを書いてみる

MyTest.cpp

// 単体テスト用マクロ
// このマクロを書くことで単体テスト用のクラスが生成される
IMPLEMENT_SIMPLE_AUTOMATION_TEST( FMyTest, "FMyTest.Hello World", EAutomationTestFlags::EditorContext | EAutomationTestFlags::ProductFilter );

bool FMyTest::RunTest( const FString& Parameters )
{
    // ここにテストを記述していく
    return true;
}

テストを実行してみる

f:id:u16kuma:20160528235146p:plain

右のほうの矢印のプルダウンメニューからProduct Testsを選択してあげることで今回作成したテストが見やすくなると思います。

今回作成したテストの左に表示されているチェックボックスにチェックを入れてテストを実行してみましょう!

以下のウィンドウが表示されAutomation Test Succeded (Hello World)と表示されれば成功です!

f:id:u16kuma:20160528235144p:plain

テストのフィルターをProduct Tests以外に変更したい場合は、IMPLEMENT_SIMPLE_AUTOMATION_TESTの引数にあるEAutomationTestFlags::ProductFilterを変更することで変えることができます。

注意点

コンパイルしてからエディターを再起動しないと反映されません。
変更してコンパイルしたけど作成したテストが表示されない、テストを書き換えたけど結果が反映されない、といったことがあった場合はコンパイルして再起動してみることをおすすめします。

まとめ

一度使い方がわかってしまえばよい機能ではあるのだけれども、公式ドキュメントを見ても書いてほしいことが書いてなくて地味に悩んだ。
あとテスト用のソースファイルの自動生成が存在しないのはなぜ?

C++で入力を検知する2つの方法

はじめに

今回は、C++でキー入力を検知してログを表示するプログラムを2つご紹介します。
どちらが良いというわけではなく、時と場合によって使いわけるようにしましょう。

1つめの方法

1つめはSetupPlayerInputComponentにて入力されたキーと関数を紐付けて取得する方法です。
APlayerController::ClientRestartに引数として渡したポーンまたはGameModeのコンストラクタでDefaultPawnClassに設定したポーンだけSetupPlayerInputComponentでバインドしたキー入力が受け取ることができます。
入力を受け取るポーンを切り替えたい時にこれを使うと良いです。

MyPawn.h

#pragma once

#include "GameFramework/Pawn.h"
#include "MyPawn.generated.h"

UCLASS()
class MYPROJECT2_API AMyPawn : public APawn
{
    GENERATED_BODY()

public:
    AMyPawn();
    virtual void BeginPlay() override;
    virtual void Tick( float DeltaSeconds ) override;
    virtual void SetupPlayerInputComponent( class UInputComponent* InputComponent ) override;

private:
    void PressedAButton();
    void ReleasedAButton();

private:
    bool bAButtonPressed;
};

MyPawn.cpp

#include "MyProject2.h"
#include "MyPawn.h"

AMyPawn::AMyPawn()
{
    PrimaryActorTick.bCanEverTick = true;
}

void AMyPawn::BeginPlay()
{
    Super::BeginPlay();
}

void AMyPawn::Tick( float DeltaTime )
{
    Super::Tick( DeltaTime );

    if ( bAButtonPressed )
    {
        UE_LOG( LogTemp, Display, TEXT( "output1: %s" ), L"Aキーが押されている" );
    }
}

void AMyPawn::SetupPlayerInputComponent( class UInputComponent* InputComponent )
{
    Super::SetupPlayerInputComponent( InputComponent );

    // 入力と関数を紐付ける
    // "AButton"は設定→プロジェクト設定→インプットで設定することができます
    InputComponent->BindAction( "AButton", IE_Pressed, this, &AMyPawn::PressedAButton );
    InputComponent->BindAction( "AButton", IE_Released, this, &AMyPawn::ReleasedAButton );
}

void AMyPawn::PressedAButton()
{
    bAButtonPressed = true;
    UE_LOG( LogTemp, Display, TEXT( "output1: %s" ), L"Aキーが押された" );
}

void AMyPawn::ReleasedAButton()
{
    bAButtonPressed = false;
    UE_LOG( LogTemp, Display, TEXT( "output1: %s" ), L"Aキーが離された" );
}

2つめの方法

2つめはAPlayerControllerから入力を取得する方法です。
こちらは1つめで設定されたInputComponentを取得してきて入力を受け取ります。
UGameplayStatics::GetPlayerControllerでPlayerControllerを取得してくることでポーンに限らずどこでも入力を受け取ることができます。

MyPawn2.h

#pragma once

#include "GameFramework/Pawn.h"
#include "MyPawn2.generated.h"

UCLASS()
class MYPROJECT2_API AMyPawn2 : public APawn
{
    GENERATED_BODY()

public:
    AMyPawn2();
    virtual void BeginPlay() override;
    virtual void Tick( float DeltaSeconds ) override;
    virtual void SetupPlayerInputComponent( class UInputComponent* InputComponent ) override;
};

MyPawn2.cpp

#include "MyProject2.h"
#include "MyPawn2.h"

AMyPawn2::AMyPawn2()
{
    PrimaryActorTick.bCanEverTick = true;
}

void AMyPawn2::BeginPlay()
{
    Super::BeginPlay();
}

void AMyPawn2::Tick( float DeltaTime )
{
    Super::Tick( DeltaTime );

    APlayerController* PlayerController = Cast<APlayerController>( Controller );
    if ( PlayerController != nullptr )
    {
        FKey Key = EKeys::A;
        if ( PlayerController->WasInputKeyJustPressed( Key ) )
        {
            // Aキーが押された時true
            UE_LOG( LogTemp, Display, TEXT( "output2: %s" ), L"Aキーが押された" );
        }
        if ( PlayerController->IsInputKeyDown( Key ) )
        {
            // Aキーが押されている間true
            UE_LOG( LogTemp, Display, TEXT( "output2: %s" ), L"Aキーが押されている" );
        }
        if ( PlayerController->WasInputKeyJustReleased( Key ) )
        {
            // Aキーを離した時true
            UE_LOG( LogTemp, Display, TEXT( "output2: %s" ), L"Aキーが離された" );
        }
    }
}

void AMyPawn2::SetupPlayerInputComponent( class UInputComponent* InputComponent )
{
    Super::SetupPlayerInputComponent( InputComponent );
}

ポーンを操作して遊んでみようぜ!

前提

Unreal Engine 4.11.2 Visual Studio 2015

はじめに

おそらくどのエンジンを使っても一番最初にやるであろう、移動、回転、拡縮をこの記事では扱っていきます。

移動、回転、拡縮

Tickメソッド内に以下のコードを記述するだけでオブジェクトの移動、回転、拡縮を実現することができます。

移動

FVector Location = GetActorLocation();
Location.Y = Sin * 50;
SetActorLocation( Location );

回転

FRotator Rotate = GetActorRotation();
Rotate.Yaw += DeltaTime * 100;
SetActorRotation( Rotate );

拡縮

FVector Scale = FVector( 1, 1, 1 ) * (Sin / 2 + 1);
SetActorScale3D( Scale );

ソースコード

FloatPawn.h

#pragma once

#include "GameFramework/Pawn.h"
#include "FloatPawn.generated.h"

UCLASS()
class SETUPENV_API AFloatPawn : public APawn
{
    GENERATED_BODY()

public:
    AFloatPawn();
    virtual void BeginPlay() override;
    virtual void Tick( float DeltaSeconds ) override;
    virtual void SetupPlayerInputComponent(class UInputComponent* InputComponent) override;

private:
    // 経過時間
    float TotalTime;
    
};

FloatPawn.cpp

#include "SetupEnv.h"
#include "FloatPawn.h"

AFloatPawn::AFloatPawn()
{
    PrimaryActorTick.bCanEverTick = true;
}

void AFloatPawn::BeginPlay()
{
    Super::BeginPlay();
}

void AFloatPawn::Tick( float DeltaTime )
{
    Super::Tick( DeltaTime );

    // 経過時間の計算
    TotalTime += DeltaTime;
    float Sin = FMath::Sin( TotalTime );

    // 横移動
    FVector Location = GetActorLocation();
    Location.Y = Sin * 50;
    SetActorLocation( Location );

    // 拡縮
    FVector Scale = FVector( 1, 1, 1 ) * (Sin / 2 + 1);
    SetActorScale3D( Scale );

    // 回転
    FRotator Rotate = GetActorRotation();
    Rotate.Yaw += DeltaTime * 100;
    SetActorRotation( Rotate );
}

void AFloatPawn::SetupPlayerInputComponent( class UInputComponent* InputComponent )
{
    Super::SetupPlayerInputComponent( InputComponent );
}

まとめ

移動、回転、拡縮について見ていきました。
UE4でC++といえども、他のゲームエンジンフレームワークとさほど変わらないと思います。
基本的な処理の実装方法を覚えていくまでがしんどいですが、頑張っていきましょう。