技術ブログを目指すブログ

toncrimentan_w’s blog

maya での 言語設定の変更方法 と 判別方法

英語版mayaを起動したい場合環境変数を書き換えればよいです。

 

システムの環境変数の設定値)

名前:MAYA_UI_LANGUAGE

値: en_US

名前:MAYA_UI_LANGUAGE

値: ja_JP

 

じゃあ逆に現在の言語設定をmelで取得したい場合はどうするのかというと

getenv コマンドを使用して環境変数を取得すればよいです。 

 

melでの判別方法)

if( `getenv MAYA_UI_LANGUAGE` == "ja_JP" )
 print "成功っす";
if( `getenv MAYA_UI_LANGUAGE` == "en_US" )
 print "successっす";

 

 

アンリアルエンジン のスポーン(インゲームでのキャラ生成)

スポーンって何

goo英和辞典で調べると 産卵 などが出てきます。

 

アンリアルエンジンでのスポーンとは、

アクターの生成のことです。

 

もしアクターが最初から配置されているものではなく

ゲーム途中で生成されるものだったら、

もしアクターが外部ツールで作成した配置情報に基づいて

生成されるものだったら、

もしアクターが一定時間ごとにに

ポップポイントから生成されるものだったら

そういう時に使うんだとおもわれる。

 

テストコード)

 /// オートポップエネミーのスポーン
 FTransform transform( FQuat::Identity, FVector::ZeroVector, FVector(1.0f) ) ;
 FActorSpawnParameters param;
 param.Name = "autoPopEnemy";
 AActorEnemy* actor = (AActorEnemy*)GetWorld()->SpawnActor(

     AActorEnemy::StaticClass(),

     &transform,

     param );

 

実行結果)

f:id:toncrimentan_w:20170329001515j:plain

 

削除したい場合は

DestroyActorやRemoveActorをつかうんだとおもわれる。

 

参考)

https://docs.unrealengine.com/latest/JPN/Programming/UnrealArchitecture/Actors/Spawning/index.html

アンリアルエンジン のオブジェリストのアクセス方法

アンリアルエンジンのプログラミングでは

指定したオブジェクトに順にアクセスすることができる。

 

必然的にこれは

ObjectListというクラスを開発者側では持たなくてよいものと思われる(?)

 

 /// アクターエネミーリストの表示
 UE_LOG( LogTemp, Log, TEXT("---------- AActorEnemyList ----------") );
 for (TObjectIterator<AActorEnemy> It; It; ++It)
 {
  UObject* CurrentObject = *It;
  UE_LOG( LogTemp, Log, TEXT("AActorEnemy: %s"), *CurrentObject->GetName() );
 }
 UE_LOG( LogTemp, Log, TEXT("---------------------------------") );

 

 /// アクターリストの表示
 UE_LOG( LogTemp, Log, TEXT("---------- AActorList ----------") );
 for (TObjectIterator<AActor> It; It; ++It)
 {
  UObject* CurrentObject = *It;
  UE_LOG( LogTemp, Log, TEXT("AActor: %s"), *CurrentObject->GetName() );
 }
 UE_LOG( LogTemp, Log, TEXT("---------------------------------") );

 

 

アンリアルエンジン の変数定義メモ

 /// 整数型
 int8 i8 = 0;
 int16 i16 = 0;
 int32 i32 = 0;
 int64 i64 = 0;

 /// 文字列型
 FString string = TEXT("0"); //std::stringライク
 FString Str2 = FString::Printf(TEXT("Hello, %s! You have %i points."), *string, i32 );

 /// 配列型
 TArray<FString> ActorArray;
 ActorArray.Push( string );
 ActorArray.Push( string );
 int32 num = ActorArray.Num();

 enum class TYPE
 {
  TYPE_A,
  TYPE_B,
  TYPE_C,
 };

 

アンリアルエンジン のブルーシートからc++の呼び出し

おそらく! おそらくだが

実際の担当分岐はこのようになると思われる

 

まずC++プログラマによるエネミー攻撃処理

.hの実装

 /**
  * @brief  攻撃
  */
 UFUNCTION(BlueprintCallable, Category="Action")
 void playAttack();

 /**
  * @brief  防御
  */
 UFUNCTION(BlueprintCallable, Category="Action")
 void playDefence();

 

.cppの実装

/**
 * @brief  攻撃
 */
UFUNCTION(BlueprintCallable, Category="Action")
void AActorEnemy::playAttack()
{
 UE_LOG( LogTemp, Log, TEXT("攻撃しました") );
}

/**
 * @brief  防御
 */
UFUNCTION(BlueprintCallable, Category="Action")
void AActorEnemy::playDefence()
{
 UE_LOG( LogTemp, Log, TEXT("防御しました") );
}

 

エディターによる攻撃関数の実装

f:id:toncrimentan_w:20170328004108j:plain

 

エディターによるエネミー攻撃処理の呼び出し

f:id:toncrimentan_w:20170328004109j:plain

 

問題なくアウトプットログには

「LogTemp: 攻撃しました」

と出力された。

アンリアルエンジン のコマンド入力によるデバッグ表示方法

メニューバー > ウィンドウ > デべロッパーツール > アウトプットログ

からアウトプットログのフォームを表示することができる。

f:id:toncrimentan_w:20170327032208j:plain

 

stat memoryなどのデバッグ表示コマンドを使用することで

デバッグ表示を行うことができます。

こりゃ便利。 消したいときは同じコマンドを入力することで消えます。

(オンラインゲームみたいでよいかも)

f:id:toncrimentan_w:20170327032215j:plain

そのほかたくさんのコマンドがある

・stat levels

・stat memory

・stat fps

・stat unit

・stat raw

・stat game

・profile gpu

などなど調べてみると多々あるらしい。

 

 

それはそうと前の参考書がおわりに近づいてきたので

新しい参考書を買いました。

 

ゲームデザイナー

アーティスト

プログラマー必携ってことは

プログラマが3番目ってことか 残念・・

f:id:toncrimentan_w:20170327032224j:plain

アンリアルエンジン のC++の想定される量産設計(仮)

実際にアンリアルエンジンで開発が決まった場合における

C++プログラマ側の量産体制テストコードを書いて検証してみる

 

図はエネミーの処理)

 

メンバ変数はm_idのみReadWriteエディタ側からの指定を有効とするため

それ以外のメンバ変数はReadOnly IDからデータベースを介して設定されるべき。

 

また公開したい変数は public にする必要があるようだ

 

postInitProperty PostEditChangeProperty

からはステータスの更新処理の呼び出し

インスタンスが生成された場合 と エディタでIDを変更された場合の処理を記入

 

文字列はFStringで定義

 

この調子ならUE4の採用もありでプログラマの仕事のなくならない? 

 

ActorEnemy.h

/**
 * @file  ActorEnemy.h
 * @brief  アクター(エネミー)
 */

#pragma once

#include "GameFramework/Character.h"
#include "ActorEnemy.generated.h"

/**
 * @brief  アクター(エネミー)
 */
UCLASS()
class FIELDTEST01_API AActorEnemy
 : public ACharacter
{
public :

    GENERATED_BODY()

    /// エネミーID ※ブループリント開発者に指定してもらうためReadWriteとします。
    UPROPERTY( EditAnywhere, BlueprintReadWrite, Category="Status" )
    int32 m_id;

    /// 名前   ※IDからデータベースを介して設定されるためブループリント開発者からはreadOnlyとなります。
    UPROPERTY( BlueprintReadOnly, VisibleAnywhere, Transient, Category="Status" )
    FString m_name;

    /// HP   ※IDからデータベースを介して設定されるためブループリント開発者からはreadOnlyとなります。
    UPROPERTY( BlueprintReadOnly, VisibleAnywhere, Transient, Category="Status" )
    int32 m_hp;

    /// 攻撃力   ※IDからデータベースを介して設定されるためブループリント開発者からはreadOnlyとなります。
    UPROPERTY( BlueprintReadOnly, VisibleAnywhere, Transient, Category="Status" )
    int32 m_atk;

    /// 防御力   ※IDからデータベースを介して設定されるためブループリント開発者からはreadOnlyとなります。
    UPROPERTY( BlueprintReadOnly, VisibleAnywhere, Transient, Category="Status" )
    int32 m_def;


public:

    /**
     * @brief  コンストラクタ
     */
    AActorEnemy();


    ///
    /// Actor.hからの継承
    ///

    /**
     * @brief  プロパティのポスト初期化イベント
     */
    virtual void PostInitProperties() override;

#if WITH_EDITOR
    /**
    * @brief  アンリアルエディタによるプロパティの変更イベント
    * @param[in] PropertyChangedEvent パラメータ
    */
    virtual void PostEditChangeProperty( FPropertyChangedEvent& PropertyChangedEvent ) override;
#endif

    /**
     * @brief  入力イベント
     *    http://u16kuma.hateblo.jp/entry/2016/05/21/211810
     */
    virtual void SetupPlayerInputComponent( class UInputComponent* PlayerInputComponent ) override;

    /**
     * @brief  再生開始イベント
     *    (アクタがプレイ可能なステートになったことを知らせるイベント)
     */
    virtual void BeginPlay() override;

    /**
    * @brief  更新イベント
    */
    virtual void Tick( float DeltaSeconds ) override;


    ///
    /// ステータスの操作
    ///

    /**
     * @brief  HPの増減
     * @param[in] val   値
     */
    UFUNCTION(BlueprintCallable, Category="Status")
    void addHp( int32 val );

    /**
     * @brief  HPの取得
     * @return  HP
     */
    UFUNCTION(BlueprintCallable, Category="Status")
    int32 getHp() const ;


private :

    ///
    /// ステータスの操作
    ///

    /**
     * @brief  ステータスのセットアップ
     */
    void setupStatus();

};

 

 ActorEnemy.cpp

/**
 * @file  ActorEnemy.h
 * @brief  アクター(エネミー)
 */

#include "FieldTest01.h"
#include "ActorEnemy.h"


/**
 * @brief  コンストラクタ
 */
AActorEnemy::AActorEnemy()
 : m_id( 1 ) ///< IDは1~
{
    /// Tickイベントの有効化
    PrimaryActorTick.bCanEverTick = true;

    /*
     bCanEverTickをtrueにしないことで処理を軽減することができます。
     https://docs.unrealengine.com/latest/JPN/Programming/Introduction/index.html
    */
}


///
/// Actor.hからの継承
///

/**
 * @brief  入力イベント
 *    http://u16kuma.hateblo.jp/entry/2016/05/21/211810
 */
void AActorEnemy::SetupPlayerInputComponent( UInputComponent* PlayerInputComponent )
{
    UE_LOG( LogTemp, Warning, __FUNCTIONW__ );

    Super::SetupPlayerInputComponent(PlayerInputComponent);

}

/**
 * @brief  プロパティのポスト初期化イベント
 */
void AActorEnemy::PostInitProperties()
{
    UE_LOG( LogTemp, Warning, __FUNCTIONW__ );

    Super::PostInitProperties();

    /// ステータスのセットアップ
    setupStatus();
    /*
     インスタンスが生成された直後に
     ステータスが更新される必要があるため呼び出しています。
     */
}

#if WITH_EDITOR
/**
 * @brief  アンリアルエディタによるプロパティの変更イベント
 * @param[in] PropertyChangedEvent パラメータ
 */
void AActorEnemy::PostEditChangeProperty( FPropertyChangedEvent& PropertyChangedEvent )
{
    UE_LOG( LogTemp, Warning, __FUNCTIONW__ );

    Super::PostEditChangeProperty( PropertyChangedEvent );

    /// ステータスのセットアップ
    setupStatus();
    /*
     デザイナによるプロパティが呼ばれたときは
     ステータスが更新される必要があるため呼び出しています。
     */
}
#endif

/**
 * @brief  再生開始イベント
 *    (アクタがプレイ可能なステートになったことを知らせるイベント)
 */
void AActorEnemy::BeginPlay()
{
    Super::BeginPlay();
}

/**
 * @brief  更新イベント
 */
void AActorEnemy::Tick( float DeltaTime )
{
    Super::Tick( DeltaTime );
}


///
/// ステータスの操作
///

/**
 * @brief  ステータスのセットアップ
 */
void AActorEnemy::setupStatus()
{
    /// IDからエネミーごとのステータスを更新する
    switch( m_id )
    {
    case 1:
     m_name = "inu";
     m_hp = 100;
     break ;
    case 2:
     m_name = "saru";
     m_hp = 200;
     break ;
    case 3:
     m_name = "kiji";
     m_hp = 300;
     break ;
    default :
     m_name = "unknown";
     break ;
    }

    //UE_LOG( LogTemp, Warning, TEXT("%s:ステータスを更新"), __FUNCTIONW__ );
}

/**
 * @brief  HPの増減
 * @param[in] val   値
 */
void AActorEnemy::addHp( int32 val )
{
    m_hp += val;
    if( m_hp < 0 )
     m_hp = 0;
}

/**
 * @brief  HPの取得
 * @return  HP
 */
UFUNCTION(BlueprintCallable, Category="Status")
int32 AActorEnemy::getHp() const
{
    return m_hp;
}