へなちょこプログラマ blog

ゲーム制作・プログラミング・趣味について記載するブログ

【Unity】UGUI キー入力上手くいかない

目次

概要

UIメインのアプリケーションを作成時に、とあるボタンの動作でトラブった時の解決策のメモです。

状況

クリックで操作していたボタンに対して下記の操作を追加

        // Enterキーを押した際にでクリックで操作と同じ関数を呼び出す
        if (Input.GetKeyDown(KeyCode.Return)) {
            OnClickButton();
        }

発生した問題

Enterキーで同じ処理を呼び出しただけなのに、
Enterキーで処理させたい処理と+α別の処理が動いている⁉

意味わかんねー‼

色々調べてみると

色々試してみると、どうやら下記の2つの処理が動いてしまっていたようだ。

  1. Enterキーを押した際にスクリプトに記述した処理
  2. Enterキーを押すまでの手順で最後にクリックしたボタンの処理

Event Systemのナビゲーションのせい?
で最後に押したボタンにフォーカスが残っている。

そのせいでEnterを押した際に

  • Input.GetKeyDown()

  • 最後に押したボタンのクリックイベント

が同時に動作しているせいでおかしなことになっていたようだ。

そんなんしらんやん...  

解決した方法

Event System > Send Navigation Eventsのチェックを外す f:id:pandoraxssscan-929:20191218231614p:plain

個人的なメモですが、誰かの役に立てば幸いです。

 

【Unity】Conditional

目次

Conditionalの紹介の前に属性(Attribute)

属性(Attribute)とはクラスやメンバーなどに追加で情報を与えることができるものです。今回の「Conditional」、以前紹介した「HidenInspector」など様々なものがあります。

 

 

 

Conditionalとは?

では、本題の「Conditional」ですが、これは定数が定義されていたら実行をし、そうでない場合は何もしない。

名前空間「System.Diagnostics」に存在する。

 

Unityで使用するなら

例えば、Unityエディター上ではログを出力したいが、ビルド後はログを出力させたくないような場合。

Debug.logをラッピングしたクラスがあるとします。

 

public static class MyDebug {

 public static void Log(object o) {

    Debug.logger.log(o); 

   }
}

⇑こんな感じのクラス

これを下記のように変更すると

 

public static class MyDebug {

 [Conditional("UNITY_EDITOR")]

 public static void Log(object o) {

    Debug.logger.log(o); 

   }
}

これでビルド後はログが出力されなくなります。

こうすることで、いちいちコード上に散らばるログ出力の部分を消さなくて済むし、コンパイラがビルド時にメソッドの呼び出しを無視してくれるようなので、メソッドの呼び出しにかかるコストもなくすことができるようです!!

 

 

間違い、ご意見など気軽にお書き込みください。

 

 

 

 

【Xenko】Xenkoについて大雑把に書いてみた

目次

この記事について

この記事ではXenkoエンジンについて、Unityと比較しながら見ていきたいと思います。

(※この記事には間違ったことを記述してしまっている可能性がありますのですべてを鵜呑みにしないでください)

(参照:

Xenko for Unity® developers | Xenko

 

Xenkoの概要

XenkoはC#でコーディングできる。Unityとは多くの部分で共通点があるようです。Visual Studioと同様にタブをドラッグしてレイアウトをカスタマイズすることができるようです。

用語比較

  • Hierarchy panel         →   Entity tree
  • Inspector      → Property  grid
  • Project browser →   Asset view
  • Scene view          →   Scene editor
  • Game object        →   Entity
  • MonoBehavior     → SyncScript, AsyncScript, StartupScript

スクリプトについて

Xenkoは、Unityと同様にコンポーネントとしてスクリプトをEntity(UnityでいうGameObject)に追加する。

SyncScript

Unityでは、スクリプトを作成すると2つの基本機能「Start()」と「Update()」がありますが、Xenkoでは同様に機能するSyncScriptがあります。

AsyncScript

非同期用のスクリプトらしいのですが詳しくはまだ使用していないので・・・

StartupScript

起動時にシーンとコンテンツを初期化する

 

最後に

大雑把ではありますが、Xenkoの概要を書かせていただきました。

何か新しい発見があればまた記事を書きたいなと思います。

 

【C++】dynamic_pointer_cast

目次

dynamic_pointer_castとは?

 

間違ったことを書いている可能性があるので参考程度にお願いします。

 

現在DirectX11で作っているゲームの中でポリモーフィズムを利用するのにActorクラスを継承してPlayerやらEnemyを作っていたのですが、Player固有の関数を呼びたくてdynamic_castする必要が出てきました(しなくていいコードがかければ・・・)。shared_ptrを使っていたのでshared_ptrをdynamic_castすることになり、最初は以下のようなコードでキャストしていたのですが・・・

 

Player* player = dynamic_cast<Player*>(root->getChild(L"Player").get());

※「root->getChild(L"Player")」は木構造で作っているのでrootからPlayerを取ってくるため

 

動くには動くのですが色々調べているとdynamic_pointer_castなるものが見つかりました。

dynamic_pointer_castはshared_ptrへの動的なキャストを行うものらしい

参照したサイト https://msdn.microsoft.com/ja-jp/library/bb982967.aspx

dynamic_pointer_castに書き直しました。

 

  std::shared_ptr<Player> player = std::dynamic_pointer_cast<Player>(root->getChild(L"Player"));

正直なところ僕のレベルでは違いがあまりわかりませんが、分れるようなレベルになりたいですし、誰かがこの記事を読んで気が付くきっかけになればうれしいです。

 

 

【Unity】HidenInInspector

目次

HidenInInspectorって?

今回面白いものを見つけたのでご紹介させていただきたいと思います。

ご紹介させていただくのは「HidenInInspector」です。

こいつをプロパティ宣言の前に追加すると、プロパティがたとえpublicであったとしてもインスペクター上で非表示となります。僕はインスペクター上で、数値をいじくるのが嫌いなので(特に理由はありませんが(笑))これは素晴らしいなと思いました。

 

例      [HidenInInspector]

         public float speed; // インスペクター上で表示されない。

 

 

 

 

【Unity】ゲームオブジェクトの作成と削除

目次 

どんな時に使う?

自分の例で例えると、まず作成は「クリックを押すと球を発射」、「敵の出現」・・・みたいなときに使いました。

次に削除ですが「発射した弾の削除」、「倒した敵の削除」、「ゲットしたアイテムの削除」などなど。

使いどころが色々あって面白い関数だと思いました。

 

ゲームオブジェクトの作成

Instantiate(コピーしたいオブジェクト、位置、向き);

 第二、第三引数は無しでも可能(ない場合はデフォルトの値が入る)。

 

弾の発射を例にして見ていきたいと思います。

 

public GameObject bullet; // エディター上で弾のプレハブをドラッグ

public Transform spawn; // 弾が発射される座標(エディター上でドラッグ)

float bulletSpeed = 50.0f; // 弾速

void Start() {

 

}

 

void Update() {

      if(Input.GetMouseButton(0)) { // 左クリックが押されたら

            GameObject obj = Instantiate(bullet, spawn.position, spawn.rotation) as GameObject; // 弾の生成

            force = gameObject.transform.forward * bulletSpeed; 
            obj.GetComponent<Rigidbody>().AddForce(force, ForceMode.Impulse); 

      }

}

 

 もっといいやり方があるかもしれませんが、とりあえずこんな感じです。

 

ゲームオブジェクトの削除

Destroy(削除するオブジェクト、削除するまでの時間);

第二引数は無しの場合即消去。

 

発射した弾の削除を例として見ていきたいと思います。

void Update () {

      Destroy(gameObject, 3.0f); // 三秒後に削除

}

 

僕流のまとめ

  • Instantiate関数:オブジェクトを生成する
  • Destroy関数:オブジェクトを削除する

コンポーネントへのアクセス

目次

 

コンポーネント

コンポーネントってRigidbodyとかColliderのことですよね?これを追加したり、値を変更したりすることで、ゲームオブジェクトに新たな動きを加えたり、与えることができると思っています。あってるはず(笑)

コンポーネントにアクセス

コンポーネントをいじくるためには、クラスのインスタンスであるコンポーネントの参照を取得する必要がある。そこで登場するのGetComponent関数。

 

Transform trans; 

void Start() {

      trans = GetComponent<Transform>(); // コンポーネントを参照

}

void Update() {

      trans.position += Vector3.forward * Time.deltaTime; // 奥に移動

}

 

みたいな感じで使ってます。

と思っていて色々試していたのですが、一つ疑問が生まれました。

 

Transform trans;

void Start() {

      trans = GetComponent<Transform>();

}

void Update() {

      trans.position += Vector3.forward * Time.deltaTime; 

      transform.position += Vector3.forward * Time.deltaTime; // これだけで動く

}

 

「あれ、これだけで動いた!!」

Rigidbodyなどは、ちゃんとGetComponent関数で参照してからでないと使えなかったのですがTransformは「transform.~」みたいにいきなり使えました。今までは意識せずにとりあえずGetComponentして変数に取っておいてそこから使っていたので気が付きませんでした。

僕の考えではTransformはすべてのGameObjectが必ず持っているものなので参照しなくてもいいよみたいな・・・。

分かる方はコメントしていただけると幸いです。

僕流のまとめ

他にも、用途によっていろいろできそうなので機会があれば記事にしたいと思います。