Aizu-Progressive xr Lab blog

会津大学のVR部であるA-PxLの部員が持ち回りで投稿していくブログです。部員がそれぞれVRに関する出来事やVRにちなんだことについて学んだことを書いていきます。

「面白法人カヤックVR分室」としても活動しています。詳細はこちら

nfcpyを使って学生証から学籍番号を読み取る

こんにちは。A-PxL元代表の橋本です。先日の集会を最後に代表を引退することになりました。1年と半年、振り返ってみれば楽しいこと、辛いこと、うれしいことが色々ありましたが、どれもいい思い出たちばかりです。

さて、今週は私がブログ当番なので私の最近の話をしようと思います。内容は、学生証から学籍番号を読み取ったことについてです。

目次

動機

会津大では、毎年4月に新入生が入ってくると新入生のために歓迎会を開くことが通例となっており、この機会を使って上級生は新入生に向けて自身が所属するサークルの勧誘活動を行なっております。各サークルはブースを設けており、そこに新入生が行って内容を聞くということをしてます。そして、気になったサークルがあれば、そこのブースにある 紙の名簿に自身の学籍番号と名前を書き込みます。この名簿に書かれた学籍番号を使ってサークル関係者は学内メールを通してサークルの説明会や体験会についての連絡を新入生にするわけですね。

問題なのは、紙の名簿だということです。 メールを送信する際には、紙に書かれた学籍番号をPCに手打ちする作業が出てきます。書き込んでくれた学生が少ない場合は問題ないのですが、多いとそれだけ苦労するというわけです。2018年度の新歓では私たちの部にはなんと50名もの新入生が名簿に記入してくれました。嬉しかったのですが、その後の50人分の学籍番号の手打ち作業はとても辛かったですね(笑)

ということで、この手打ち作業をなくすべく、何かシステムを作らねば! というのが今回このシステムを作ろうと思ったきっかけです。

要件

個人的にNFCリーダーを使った何かをすることに興味がありました。そこで、学生証から学籍番号を読み取ることを考えました。また、読み取ったデータはスプレッドシートに書き込まれるようにするのがいいかと考え、読み込んだ学籍番号はGoogle Spread Sheetに書き込まれるようにしました。さらに、せっかくうちの部ではUnityを使ったアプリ開発を行なっているので、どうせなら読み込まれた学籍番号をUnity上で少し演出を加えて表示させようと思い、この実装も行うことにしました。(最後の1つはシステム的には蛇足ですけどね(笑))

f:id:aizu-vr:20190802165529p:plain

実は、この作品は私が大学で受けていた授業の最終プロジェクトとして作ったものです。そのプロジェクトは、ラズパイを使って何かしよう! というものでした。そのためこのシステムではラズパイを用いております。

今回はICカードリーダー周りについて書いていきます。

NFCFelicaについて

NFCとは、Near Field Communicationの略で、かざすことデータ交換をするために規定された近距離無線通信技術です。そして、FelicaNFCの規格をもとにしてSONYが作った規格です。特徴として、Felicaは通信速度が速く、NFCの2倍ほどと言われています。そのこともあって、日本国内では主にFelicaが使われることが多いです。SuicaPasmo, nanacoカード、WAONカードなどはすべてFelicaです。

詳しくはこちらの記事をお読みください。

[PASMO] FeliCa から情報を吸い出してみる - FeliCaの仕様編 [Android][Kotlin] - Qiita

学籍番号を読み取る

学籍番号を読み取るには読み取るための装置が必要です。手元になかったので買いました。ネットで色々調べた結果、以下の装置を購入しました。

ソニー SONY 非接触ICカードリーダー/ライター PaSoRi RC-S380

ソニー SONY 非接触ICカードリーダー/ライター PaSoRi RC-S380

意外と安く手に入るものなんですね。

さて、準備も整ったので、早速読み取ってみましょう。まずは環境を整えます。以下の記事を参考にして整えてみてください。

RaspberryPiで!SONYのPaSoRi(RC-S380)で(NFC)Felica情報を読み取る! - KOKENSHAの技術ブログ

次に、カードのどこの部分に学籍番号が書かれているかを知らなければなりません。そこで、ダンプしてカードの中のどこに学籍番号情報があるかを確認します。

コードはこちらの方のものを使わせていただきました。

Raspberry Pi 3にPaSoRiを接続してSuicaカードをダンプする | TomoSoft

会津大の学生証をダンプした結果

System 809E (unknown)
Area 0000--FFFE
  Area 1000--1FFF
    Random Service 64: write with key (0x1008)
    Random Service 68: write with key (0x1108)
    Random Service 72: write with key (0x1208)
    Random Service 76: write with key (0x1308)
    Random Service 128: write with key (0x2008)
    Area 3000--3FFF
    Random Service 192: write with key & read w/o key (0x3008 0x300B)
     0000: 31 30 30 30 31 32 35 3X 3X 3X 3X 30 30 30 30 30 |1000125XXXX00000|
System FE00 (Common Area)
Area 0000--FFFE
  Area 1A80--1AFF
    Area 1A81--1AFF
      Random Service 106: write with key & read w/o key (0x1A88 0x1A8B)
       0000: 30 31 30 30 31 32 35 3X 3X 3X 3X 00 00 00 30 31 |0100125XXX...01|
       0001: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
       0002: 30 3X 30 3X 3X 3X 3X 3X 3X 30 3X 3X 30 3X 30 3X |0X0XX0XXX0XX0X01|
       0003: 3X 30 3X 3X 30 3X 3X 31 3X 30 30 30 30 30 3X XX |X0XX0XXXX00000XX|
      Area 1BXX--1BXX
      Area 1XXX--1BXX
        Random Service 108: write with key & read with key (0x1BXX 0x1BXX)
        Area 1XXX--1BXX
        Area 1BXX--1B7F
          Random Service 109: write with key & read with key (0xXX48 0xXX4A)
          Area 4XX0--42XX
          Area 4XX1--42XX
            Random Service 267: write with key & read with key (0xXXC8 0x4XXX)
            Area X3X0--4X3F
            Area X30X--4X3F
              Random Service 268: write with key & read with key (0x43XX 0x4XXX)
              Area XXXX--43XX
              Area 43XX--4XX7
                Random Service 269: write with key & read w/o key (0x43XX 0xXX4B)
                 0000: 00 XX 00 00 XX 00 XX 00 XX 00 XX 00 XX 00 XX XX |................|
                 *     00 XX 00 XX 00 XX 00 XX 00 XX 00 XX 00 00 XX XX |................|
                 000X: 0X 0X 00 XX 00 00 XX 00 XX 00 XX XX 00 00 00 00 |................|

データ保護のためところどころにXを入れています。

どうやら、システム809Eのサービスコード0x300Bに学籍番号らしきものがあるようですね。この値を使って学籍番号を読み取ってみたいと思います。Pythonコードを書いていきます。

こちらの記事を参考にしました。

nfcpy で複数の System Code を持つ NFC タグを扱う方法 - uchan note

#!/usr/bin/env python
# -*- coding: utf-8 -*-
  
import binascii
import nfc
import time

# 学生証のサービスコード
service_code = 0x300B

def on_connect_nfc(tag):
  # タグのIDなどを出力する
  # print tag
  
  if isinstance(tag, nfc.tag.tt3.Type3Tag):
    try:
        sc = nfc.tag.tt3.ServiceCode(service_code >> 6 ,service_code & 0x3f)
        bc = nfc.tag.tt3.BlockCode(0,service=0)
        data = tag.read_without_encryption([sc],[bc])
        sid =  "s" + str(data[4:11])
        print sid
    except Exception as e:
      print "error: %s" % e
  else:
    print "error: tag isn't Type3Tag"
  
def main():
  clf = nfc.ContactlessFrontend('usb')
  while True:
    clf.connect(rdwr={'on-connect': on_connect_nfc})
    time.sleep(3)
  
if __name__ == "__main__":
  main()

このコードを使うことで会津大の学生証から学籍番号を読み取ることができます。このプログラムでは3秒毎に学生証の学籍番号を読み取ってコンソールに表示させています。

f:id:aizu-vr:20190802184316p:plain

まとめ

最初は難しいのかなと思っていたのですが、思ったほど難しくはなかったですね。先駆者様の方々のおかげです。今回はラズパイを使ったこともありPythonを使用しましたが、調べてみたところ、C#にもNFCを扱うライブラリがあるそうなので、時間があったらやってみたいと思ってます。

来年の新歓はこれで少しは楽になるといいなぁ〜

一年生対象の部内ハッカソンを開催しました!

こんにちは。A-PxL代表の橋本です。部名を改めてからの初の投稿となります。さて、私たちの部では7月13日と7月14日の二日間に渡って一年生対象の部内ハッカソンを開催しました。今回はそのハッカソンのレポート及びどのように企画したかについて記事を書こうと思います。

f:id:aizu-vr:20190724214300j:plain 今年から部名がVRからxRに変わったので集合写真のポーズもxRポーズにバージョンアップです!

目次

ハッカソン開催の目的

今回のハッカソンの目的は一年生に

  • 腕試しの機会を与える
  • 他の一年生との交流の機会を与える
  • チーム活動を経験させる

ことです。

今まで一年生には4月から6月までの2ヶ月間ほぼ毎週UnityやC#, Blender等のワークショップに参加していただきました。色々やっていただいたからこそ、今まで学んできたことの復習や、腕試しをする機会を与えたい! という思いがありました。その機会を与えることが今回のハッカソンを開いた目的の1つです。また、部で開いているワークショップは基本的に一人で完結してしまうものがほとんどでした。そのため、一年生同士の交流が若干少なかったり、チームでの開発をしたりしていませんでした。しかし、実際に部で活動をする際や今後就職して仕事をするようになった時は基本的にチームを組んで作業をすることになります。そして、チーム制作をする際にはチームメンバーとのコミュニケーションが重要になってきます。その練習を1年生にさせることが目的でもありました。

最初にしたこと

ハッカソンについてよく知らないという一年生がほとんどでした。そのため、開発をさせる前にハッカソンとはどういうものなのか、どんな目的で開催されるべきなのかについて教えることにしました。

(ちなみに、内容についてこちらの記事を参考にしました。今回のハッカソンを開催するにあたってこの記事の内容はとても参考になりましたし、共感を感じる部分が多々ありました。この記事の著者の方には感謝しています)

ハッカソンのテーマ

今回のハッカソン「既存のゲームを面白くハックしよう!」 というテーマを掲げて実施しました。内容としては、すでにある程度出来上がっているゲームをもとにしてどういう改良を施したら面白くなるか、ゲームっぽくなるかを考えて開発を進めるという感じです。0から新しいコンテンツを作らせることも考えたのですが、

  • 一年生のUnityを使った期間
  • プログラミング経験が大学入学前になかった人がほとんどであること
  • チーム開発の経験がないこと

などを考慮した結果、ある程度ベースとなっているものに機能を付け足していくとした方が開発がしやすいしアイディアも浮かびやすいのではないかと考え、このようなルールとしました。

こちらで用意したUnityパッケージは以下の3種です。なお、これらのプロジェクトは改良が施しやすいようある程度の中途半端さを兼ね備えるようにさせました。

  • 玉転がし

    Unity公式のチュートリアルのものです。玉を動かしてステージ上の全てのアイテムを拾ったらクリアというシンプルなゲームです。

  • 迷路

    部内で開催したUnityワークショップの最終回で使われた迷路のゲームです。Unityちゃんを操作して目的地まで到達できればクリアというとてもシンプルなゲームです。

  • Space Shooter

    こちらもUnity公式のチュートリアルのものです。宇宙船を操作して前から降ってくる隕石を避けたり弾を発射して隕石を壊したりするゲームです。なお、チュートリアルでは隕石を壊した際に得点を加算したり、音をつけたり、ゲームを再開したりする機能がありましたが、今回使用してもらったパッケージにはその部分はあえて含めませんでした。

f:id:aizu-vr:20190724213341j:plain 開発中の様子。中には帰宅せずにずっと会場に残って開発をしていた一年生もいました!

審査の方法について

上級生がコンテンツを評価して各チームの優劣をつけて優勝チームを決定することも考えたのですが、上記で述べたハッカソンについて書かれた記事を参考にして参加者、上級生全員で審査をすることにしました。

具体的な方法

  1. 各チームの審査フォームを用意する。
  2. フォームに記入をしてもらう。この時、1年生は自分が所属するチームの審査はしないで違うチームの評価のみする。
  3. 全員のフォームが出揃ったら得点を集計する。

フォームの内容

  • 動くものを作っていたか?

    "yes" or "no" で回答。"yes"なら2点。"no"なら1点。その結果を2倍した値が得点となる。

    ハッカソンで1番大事なことは、動くものを作ることであると思っています。そのため、一番最初の質問はこのようにし、一番倍率を大きくしました。倍率をつけた理由ですが、チーム間で得点が同じになってしまうことがないようにするためです。

  • チャレンジ点

    10段階で評価。つけた点数を1.5倍した値が得点となる。

    ハッカソン開催の根本の目的は上で述べた記事の通り、参加者に普段できないことややったことがないことを挑戦させるということにあると私も思います。そこで2つ目をチャレンジ点としました。

  • アイディアのユニーク点

    10段階で評価。つけた点数を1.2倍した値が得点となる。

    ハッカソンで一般的に重要視されるべき箇所としてユニーク性はマストだと思われたので3つ目をユニーク点としました。

  • コンテンツそのものの完成度

    10段階で評価。つけた点数がそのまま得点となる。

    コンテンツの完成度についても点をつけさせましたが、チャレンジ点のところで述べたとおり、ハッカソンは参加者にとって試す、チャレンジする機会であるべきと思います。そのため、今回はあまり重要視せず、倍率は1.0倍としました。

審査する前に、各チームには前に出てスライドを使っての発表を行ってもらいました。この場でコンテンツの内容やどんなところを頑張ったか、どこが難しかったか、どこに挑戦したかについて参加者全員に話してもらいました。その後、デモンストレーションの時間を取り、全員に全てのチームの作品を体験させました。

f:id:aizu-vr:20190724213432j:plain プレゼンの様子。

各チームの成果物

Space Shooterチーム

あえて既存のスペースシューターを完成させずに中途半端なところでパッケージを渡した結果、全く見たことがないスペースシューターのゲームが出来上がりました!

新要素

  • パワーアップアイテム

    移動速度上昇やサブ機体を横に付けたり、シールドを前方に付けたりといった新しいパワーアップアイテム要素を追加していました。

  • 大きなボスとその取り巻き

    ゲーム開始後一定時間経過でボスが出現します。画面のほとんどを覆うかのような巨大な敵で、弾を一発当てただけでは倒せません。ボス出現と同時に画面上部にボスの体力ゲージが追加され、とてもゲームらしい画面が現れます。さらに、ボスの取り巻きも現れ、プレイヤーの方にホーミングしてきます。

隕石はただまっすぐに上から下に流れてくるだけなのに対し、ボスはゆっくりと左右に動くので、こちらも動かないといけないんです。でも動くと隕石や取り巻きにやられるリスクが上がってしまう...。個人的にはこのボスの動きが素晴らしいと感じましたね。以前このような記事を読んだことがあるのですが、こちらの記事の「ゲーム性」を考えるのなら、このチームが一番ゲーム性を再現したと言えるのではないかと思いました。

f:id:aizu-vr:20190724213833j:plain スペースシューターチームのデモの様子。

玉転がしチーム

今回のハッカソンの優勝チームです。超!エキサイティン!! なとても白熱する2人対戦専用の球を使ったゲームでした。

ルール

  • プレイヤーは2人で、それぞれ「自信が動いた軌跡上に新たな球を生成する球」(以降プレイヤー1)と、「ぶつかることで相手が生成した球を消すことができる球」(以降プレイヤー2)を操作する。
  • ターン数は7ターンで、自分のターンに相手が操作する球をステージから落とせば無条件で自分の勝ちとなる。
  • ただし、7ターン以内に決着がつかない場合は、プレイヤー1がステージ上に15個以上の球を生成していた場合、プレイヤー1の勝利となり、15個未満であればプレイヤー2の勝利となる。

既存のゲームの改造というよりもはや全く新しいゲームの作成を行ってもらったといった感じですね(笑)。審査の結果、ユニーク点がとても高かったのが特徴的で、この要素が命運を分けたといった感じです。確かにこのルールの独自性はかなり高かったです。ちなみに、優勝商品はAmazonギフト券 1,500円分です!

f:id:aizu-vr:20190724213549j:plain 玉転がしチームのデモの様子

迷路チーム

ただクリアエリアに行けばクリアだったルールを変更し、条件満たしてからじゃないと脱出できないという脱出ゲームとなっていました!

新要素

  • ステージ上をうろつくゾンビが現れました。このゾンビがプレイヤーのことを追いかけます。もちろんぶつかった瞬間ゲームオーバーです。

  • スイッチ

    迷路の脱出ポイントに到達しても、スイッチを押していないと脱出できない仕様に生まれ替わっていました。

このチームの凄いところはゲームの完成度が高かったところです。ゲームがホラー路線であるからタイトルロゴをバイ○ハザード風にしたり、SEを自分で作ったり、クリア画面で使う画像を自分で描いたりといった風に、ゲームプレイ以外の細かい点にもとても気を使っていたのが好印象となったみたいです。審査の結果、一番完成度ポイントが高かったのはこちらのチームでした。また、他のチームはUnityパッケージのやりとりで開発をしていたのに対し、こちらのチームではGitを用いてチーム開発をしていたのもよかったですね!

f:id:aizu-vr:20190724213935j:plain 迷路チームのデモの様子。

各チームとも構成員2名のチームだったんですが、全チームとも2名とは思えないようなクオリティのコンテンツを作り上げてしまいました! 少なくとも私が1年だった頃のこの時期にここまではできていませんでした。ただただ脱帽です(笑)

まとめ

今までハッカソンを企画したことが無かったこともあり、うまくいくかどうか不安だらけでした。しかし、一年生は私たち上級生の予想をはるかに超える成長をしていました。プログラミングを始めてまだ数ヶ月であの出来ならば今後どのようになるのか...。とても未来が楽しみな一年生達でした。一年生には今後も内部、外部問わずハッカソンに出たりして腕試しをしたりチーム開発を経験していって成長してほしいと思っています。

P.S.

ハッカソン開催時の様子を見ていたところ、今回のハッカソンの3つの目的、

  • 腕試しの機会を与える
  • 他の一年生との交流の機会を与える
  • チーム活動を経験させる

は全て達成できたのではないかと思っています。この目的を達成できたのは目を見張る成長を見せてくれた一年生やその一年生のサポートをしてくれた上級生の方々、そして何より1年生向けにワークショップの資料を作って開催してくれた上級生の方々のおかげです。本当にありがとうございました。

Unityで状態管理フレームワークを作った

どうも,学部3年のうじまる(id:uzimaru0000)です. 今日はUnityの状態管理フレームワークUniTEA」のことを書きたいと思います. 主にどういうことを考えて作ったのかを書きたいと思います.

詳しい使い方は

qiita.com

を見てください.

なぜ作ったのか

部活のメンバーと一緒にSPAJAM東北予選に出場した際に久々にUnityを使ったのですが,「アプリケーションの状態管理がつらすぎる...」っとなったので普段お世話になっているElmというWebフロントエンドの言語とそのアーキテクチャの「The Elm Architecture」を参考に状態管理フレームワークを作ってみました.

あと,Unityってフレームワーク的なものあまり無いですよね.なので結構,開発方針をしっかりと定めないとグチャグチャになりがちだったりしますよね...(無いなら作ればワンチャン,メジャーになる??)

名前のTEAはこのアーキテクチャの頭文字をとってます.多分「ティー」と発音するので「UniTEA」で「ユニティー」と発音します.紛らわしいですね

設計方針

設計の方針としては「依存するライブラリをなくす」「最小限の構成にする」というものです.

依存ライブラリをなくす

このライブラリが依存するライブラリをなくすということです.端的にいうと,Unity単独で扱うことが出来るということです.

似たようなライブラリに「Unidux」というものがあるのですが,そのライブラリは「UniRx」に依存しています.

個人的にはライブラリに依存してしまうと,そのライブラリの知識が必要になり使用するまでのハードルが高くなってしまいます. また,ライブラリを開発・管理する際にもそのライブラリの更新を追っていかなければいけないのでコストがかかってしまいます.(UniRxは成熟しているライブラリなので破壊的変更をたくさん実装するようなアップデートは無いと思いますが...)

以上の理由から依存ライブラリをなくすように実装しました.

最小限の構成にする

依存ライブラリをなくすということは2つの選択肢があります

  • 大量の機能を提供して自分で機能を全て実装する
  • 最小限の機能を提供して最小限の実装にする

僕は後者を選択しました.

理由としては2つ

  • 大量の機能を実装する力がない
  • このライブラリが提供したいのは「The Elm Architecture」のみ

ということです.

大量の機能を実装する力がない

単純にたくさんの機能を実装・保守するだけの力が無いからです. 「その機能だったらこっちのライブラリのほうが優秀じゃん」みたいなことが起こったらこっちのライブラリは邪魔者になってしまいます.(内部で利用するにはいいかもしれないですが)

このライブラリが提供したいのは「The Elm Architecture」のみ

これにつきます.TEAしか提供したくないのです.継承するだけでシングルトンにしてくれるクラスは必要なら自分で実装すればいいのです(Uniduxが提供してます...) したがって,そもそも最低限の構成だけでいい,TEAを実装出来るだけの機能があれば十分なのです.

また,他の機能だったら今でてるライブラリで十分です.むしろそっちのほうが優秀です(それを提供するためだけ に全力を尽くしてるので)

だったらこちらも「TEAを提供するだけに全力を尽くします」

実装

以上のことを考えて実装しました. 結果,コアのクラスは50行くらいで終わりました(行数が全てではないですが)

作ったクラス・インターフェイス

  • UniTEA class
  • IMessenger interface
  • IUpdater interface
  • IRenderer interface
  • Cmd class
  • OneValueMsg

の6つです.OneValueMsgはメインのnamespaceではなくUniTEA.Utilsの中に入っています.

基本的な使い方としては,UniTEA class を継承するのではなく,MonoBehaviorのclassに持たせる形で使用します.各インターフェイスを実装してUniTEA classの初期化時に渡すという感じです.

詳しい使い方はQiitaの記事 を参考にしたり,ソースコードのExampleを見てみてください.

最後に

依存はなくすと言いましたが,実際に使う際は「UniRx」や「UniTask」や「Zenject」を使ったほうがうまく扱えると思います.それを想定しての「最小限の構成」です.必要なら自分で入れましょう・作りましょう.

issueやPRは絶賛募集中なのでじゃんじゃん投げてください!(ついでにスターも付けてくれると嬉しいです😊)

敵の編集を楽にしようと頑張ったお話

始め

Aizu-PxLの修士になりました、なおしです。
皆さんは敵の動きをどのように作成しますか?

  • プログラムを書く
  • NavMeshを使う
  • ランダムに動かす
  • etc

今まで私はこれらを活用して敵を作成したことがあります。ゲームにおいて敵の存在は切っても切れない存在だと思っていますが、作る上ではとても厄介なものだと感じています。

今回の内容は前半にこれまでの経験、後半に今やっていることをまとめます。

今まで敵を作成して感じたこと

NavMeshを使ったとき

敵をプレイヤーに向かわせるときNavMeshを使用することが多いと思います。もしくはプログラムでも実装するのはそう難しくはないかもしれません。

NavMeshを使用した際の利点として

  • 敵は必ずプレイヤーに向かう
  • プログラムを書くのが楽
  • 様々な敵の種類にも適用できる

があります。

しかし、ただプレイヤーに向かうだけの敵は想像以上に飽きるのが速いです。 また、NavMeshの弱点として地面に接地しない敵には使うことが出来ないところです。NavMesh使うのはプレイヤーを探索する時だけにして、一定距離に近づいたときに別の行動をするアルゴリズムにしたほうが面白くなるかなと思っています。(その分、作業量が増える)

個々の敵をプログラムする

個々の敵に対してプログラムを書くことによって

  • 様々な動きをする敵が作れる
  • 飽きにくい
  • 敵の種類に応じて動きを作成できる

という利点が生まれます。

しかし、プログラムで敵を動かす際に発生する欠点は

  • プログラムが複雑化したり、デバッグが大変になる
  • ゲームバランスの調整が難しい
  • 敵の種類を増やしにくい

と感じます。NavMeshを使ってプレイヤーに向かわせる、そこから敵に攻撃、プレイヤーが逃げたら追跡等モンスターの動きの幅が広がる一方でかなり編集に難があると思います。

ランダムに動かす

ランダムに敵を動かすプログラムを作るのは簡単ですが、それもアルゴリズムによりけりかなと感じました。例えば、Random関数などを使ってその方向に動かすとすればすぐに書けます。しかし、そのプログラムで動く敵はブルブル震えるだけになるでしょう。

アルゴリズムを考えて壁にぶつかるまで前進して、ぶつかった際はランダムで方向転換、そして前進するようなものにすればそれっぽく動くようになります。

ランダムに動かす場合の一番の問題点としてはゲームバランスの調整が先の2つに比べてかなり難しくなることだと思います。

簡単な総括

今までの開発経験を通して次のことが言えるのではないかって思っています。

  • 簡単にプログラムされた敵は編集、開発は楽であるが飽きやすい
  • 複雑なプログラムで作成された敵は飽きにくいが編集、開発が難しい

今やろうとしたこと

只今私は個人開発をしているのですが、その中で簡単に敵の動きを編集できるものを作ろうと頑張っています。だた、まだ完成してませんし完成する目途がまだ立っていない状態なのでご了承ください。

動きをクラスにする

今までは1つのプログラムに様々な動きを書いていました。そのプログラムを改良やリファクタリングした結果、敵の動きをクラスで表現するという結論に至りました。簡単なクラス図は次のようになります。

f:id:aizu-vr:20190603000933j:plain

まず、Monsterクラス、MonsterActionクラスを作成します。MonsterクラスはMonsterActionクラスのリストを保持します。MonsterActionクラスにはAction関数があり、MonsterActionクラスを継承したクラスはAction関数をオーバーライドします。最後にMonsterクラスはリストに入ったMonsterActionクラスのAction関数を呼び出し、多態性によりMonsterActionクラスを継承したクラスのAction関数を実行することが出来ます。


解説すると意味がわかりませんね。簡単に言うと動き(攻撃、移動など)をリストに保存してそれを順に実行していくということです。
ちなみに、このようなデザインパターンStateパターンと呼ぶそうです。
追記:もしかしたら違うかもしれません。間違っていたらごめんなさい

これらを参照しました。

ゲームプログラミングC++

ゲームプログラミングC++

増補改訂版Java言語で学ぶデザインパターン入門

増補改訂版Java言語で学ぶデザインパターン入門

エディタ拡張ReorderableListを使う

コンポーネントのリストをエディタで編集しようとすると結構めんどくさいです。また、今回はMonoBehaviorを継承していないものを編集するため普通のInspectorでは編集できません。

f:id:aizu-vr:20190603004259p:plain
要素の追加、入れ替えが面倒。そして見にくい

そこでReorderableListを使用したいと思います。

f:id:aizu-vr:20190603004555p:plain
Unityで見たことあると思います

これを使用することにより型によって表示する枠を変えたり、要素の入れ替えや追加が簡単になります。

ReorderableListについてやエディタ拡張については次を参照しました。 Unity エディター拡張入門

また、一度別の個人開発でも使用しました。Fire Commander!

今起きている問題

だた、まだこれが完成していません。今起きている問題が派生クラスの型が消えて基底クラスの型として表示されることです。始めは上手く動作しますが、リビルドされた際に型が消えてしまうというバグに悩まされています。

デバッグ用にメンバ変数(派生クラスも含む)をすべて表示する関数を用意しているのですが、それも派生クラスの関数が呼ばれていないので保存されているデータとしても基底クラスに変わっていしまっているみたいです。

過去に使った際は一つのクラスだけのリストでしたが今回はいくつかの派生クラスを保存するのでダウンキャストをしなければなりません。そして、UnityEditor上でどのようにデータが保存されているかまだ理解できていないことが原因だと思います。

解決策

考えうる解決策としてデザインパターンの変更を検討しています。Monsterクラスに保存するものをデータの構造体に変更し、そのデータを一度Factoryクラスに渡してMonsterActionクラスを生成するクラス図を考えています。

欠点としてデータの構造体にすべての動きに対応できるほどのメンバ変数を用意しないといけないこと、新しいMonsterActionクラスを作成した際にFactoryクラスも修正しないといけない点です。

最後に

みっともない話ですが、まだ今やろうとしていることが完成せずにブログにまとめています。ただ、エディタ拡張、デザインパターンを習得する価値は非常に高いと感じています。

この2つを使うことによってゲームの仕様変更やゲームバランスの調整、拡張が容易になるはずです。これからこれらも勉強していきますし、完成次第もう一度ブログにまとめ直す予定であります。

完成するまで応援して欲しい。

本格的VRキャラバン始動?!

お久しぶりです、会津VR部という名前のころの初代部長の秋山です。部のブログ投稿は本当に久しぶりですね。
今回は何度かブログにもでている「VRキャラバン活動」について書きたいと思います。


VRキャラバン活動とは

前提にVRキャラバン活動とは何かわからない方はこちらを読んでみてください。

aizu-vr.hatenablog.com


子どもの夢とおいしいもの祭り

www.minpo.jp

5/18, 19に「ふくしま産業省受賞企業プレゼンツ 2019 子どもの夢とおいしいもの祭り」が道の駅あいづ湯川・会津坂下にて開催されました。こちらのイベントで今回VRキャラバン活動を実施させてもらいました。


今までのキャラバン活動と違う点

今までのキャラバン活動を振り返ってみるとただ車で機材を搬入し、その場で会場のコンセントから延長コードを伸ばし電力を供給する普通すぎるやり方の、どの要素がキャラバンなんだろう...とつくづく思いますね。今回の展示はその点を改善すべくなんと電気自動車を使って展示をしてきました!
機材の運搬から電力供給をすべて電気自動車で行いました。タープを電気自動車の横に付けそれっぽい雰囲気にしようとしました!
f:id:aizu-vr:20190527153056j:plain

展示の様子

今回の展示に使用したHMDはVivePro。この機材に限りませんが直射日光は絶対に防ぎたいですね。そのためにタープとカーテンを用意しました。
f:id:aizu-vr:20190527131611j:plain
f:id:aizu-vr:20190527131617j:plain
突発的な提案だったのもあり見た目は非常に悪いですが、一応最低限の運用はすることができました。せっかくVRコンテンツを展示するのですからもっとサイバー感やコンテンツの雰囲気とあった(またはその全く逆)見た目にしたかったですね。次回までに揃えたいです。

今回の展示を通して

良かった点

  • 実際に直射日光が防げる簡易的な部屋を作ってしまえばプレイできることが確認できた

  • 屋外で展示することによって普段と違った点で展示コンテンツの改良点が見つかった

  • 屋外でタープを使用しての運用時や電気自動車を使用時の注意点が多く知れた

見つかった問題点/反省点

  • カーテンを2枚しか用意しなかったので日光の関係上、午前と午後で向きを変える必要性があった

  • カーテンでしきりを作るとタープの中が非常に暑くなってしまった。暑い時期には冷風機を用意すべき

  • 電気自動車のバッテリー残量が20%(多分ここは車種による)を切ると、省電力モードに自動で切り替わってしまう。省電力モードだと外部への電力供給ができなくなるので強制的に店仕舞いとなってしまった

  • プレイヤーのカメラの向きを変更するボタンを必ず作るべき。展示の関係上、タープの4辺の1辺は外部の方でも見れるように開けとく必要があるが、あまりにも日差しが強いとその方向を向いた瞬間にトラッキングが外れることがある。(コンテンツの質の問題。日光関係なしにカメラの方向転換ボタンは必ず作るべき)

  • 風が強くてタープが飛んでしまう。これが1番の問題だった。
    カーテンでしきると風を受ける面積が大きくなりタープが飛びやすくなった(よく考えれば事前にわかったはず)。
    今回ペットボトルに水をいれたものをタープの全足に括り付けたが、それだけでは全然足りなかった。旗の下によくある重石を常に用意しとくべき。カーテン用も含め10個あると安心できる。
    風を入れる穴をカーテンに開けると少しはましになった。

おわりに

電気自動車を使用したこのキャラバン活動はこれから本格的に始動していくと思います。
もし、来てほしい方がいらっしゃいましたらブログまたはTwitterなどで声をかけていただければご相談できると思います。その時はよろしくお願いします! f:id:aizu-vr:20190527131539j:plain

会津大学VR部の部員が持ち回りで投稿していくブログです。特にテーマに縛りを設けずに書いていきます!