Gaming Life

一日24時間、ゲームは10時間

UE4の乱数生成BPの実装を見てみる(1)(Random integer in range)

 なんとなくUE4Minecraftのようなランダム地形生成アルゴリズムを実装してみたい、という気持ちになり、最近乱数について調べている。その中で、UE4の乱数生成はどうやっているのか見ておく必要があるだろう、ということでエンジンソースを時間を見つけて読んでいる。個人的なメモ程度の情報しかないが、暫くシリーズとして乱数生成の実装を見て、将来的にパーリンノイズやらよく使われるノイズ関数の実装、最終的には地形生成アルゴリズムを作っていきたいと思う。

 第一回はRandom integer in rangeについて。


  • UKismetMathLibrayにブループリントのMathLibraryの実装が載っている (UE_4.18\Engine\Source\Runtime\Engine\Classes\Kismet)

  • int32 RandomIntegerInRange(int32 Min, int32 Max){ return FMath::RandRange(Min,Max);}

 ブループリント本体。

  • int32 RandRange(Min,Max)
    {
    const int32 Range = (Max - Min) + 1;
    return Min + RandHelper(Range);
    }

  • int32 RandHelper(int32 A)
    {
    return A>0 ? Min(TruncToInt(FRand() * A), A-1) : 0;
    }

  • float FRand() {retrun Rand() / (float)RAND_MAX;}
    (UE_4.18\Engine\Source\Runtime\Core\Public\GenericPlatform\GenericPlatformMath.h)

コメント:Returns a random float between 0 and 1, inclusive.

  • int32 Rand() {return rand();}

コメント:Returns a random interger between 0 and Rand_Max,inclusive

  • int32 TruncToInt(float F){ return (int32)F;}

 なんとstd::rand()を使って乱数生成していることが判明。以前の記事でも触れたがstd::rand()は生成範囲が狭く、線形合同法と呼ばれるあまりよろしくない乱数生成アルゴリズムを採用しており、このせいで、乱数の周期があまり長くないという問題がある。より良い地形生成をしようと思ったらUE4標準の乱数生成ライブラリに頼らず、MT法などを使った乱数生成アルゴリズムを自前で書いたほうが良さそう……。

 ちなみに以前書いた乱数についての研究記事は以下。

ai-gaminglife.hatenablog.com

ai-gaminglife.hatenablog.com

 次回はfloat乱数を見てみようと思う。