今回は、9月19日・20日のM5Stackハッカソンで作ったものの作り方を書きます。
作ったもの
作品名
バーチャル・ランニング
https://protopedia.net/prototype/07a9d3fed4c5ea6b17e80258dee231fa
動画
【一週一創】先日の #m5stack ハッカソンで作ったものの作り方を公開します。 #UnityChan #protoout #ヒーローズリーグ #一週一創https://t.co/NT4jInmgqI pic.twitter.com/6oDnRVgDIZ
— たつや @9/18 cluster広島LT大会 (@tatsuya1970) September 23, 2020
M5Stackをポケットに忍ばせ、ランニングすると、M5Stackの加速度センサーがある閾値をこえると、PCの中のキャラクター(ユニティちゃん)が走ります。 ちょっとでもサボると、ユニティちゃんも止まります。
システム
環境
- Windows 10
- Unity 2017 4.28f1
- Ruby on Rails
使ったもの
Unityアセット
- HQ Fighting Animation FREE
- JsonObject
構成図
M5Stackの加速度センサーがある閾値を超えると「走ってるフラグ1」、止まったら「走ってるフラグゼロ」をRuby on Railsで構築したデータベースMySQLへPOST通信し保存します。
PC上のUnityはフレーム毎にMySQLにGET通信し、今の状態を確認、走ってるフラグが1ならユニティちゃんを走らせ、フラグがゼロならユニティちゃんを止まらせます。
言い訳
おそらく、こんな非効率なやり方よりももっと良いやり方があるはずだと思います。
走ってるか走ってないかを確認するだけのために、1フレーム毎にGET通信したり、走った走らないでデータベースにPOST書き込みなんて、すぐにHerokuのリクエスト制限超過になります。
しかしながら、私にはあまり通信やデータベースに知識がなく、ハッカソンという限られた時間の範囲内では、このような非効率だけど自分の知識を総動員して一応動くことができるものを作ることを優先にしました。
3年前に自分が構築したRuby on Rails + MySQL のデータベースがHeroku上に生きていたので、その生きているRuby on Railsのプログラムに、ルーティングを付け加えました。
ということで、これはハッカソン用の暫定措置のシステムですので、もっと良い方法がありましたら、ヒントだけでもいただければ幸いです。
コード
M5Stack側
ポイントはHttpRequest
注意ポイントを別途こちらに書いてます。
M5Stack UIFlowでHTTP(POST)通信
https://qiita.com/tatsuya1970/items/737b9af78191846d4556
サーバー側
Ruby on Rails + mySQLをHeroku内に構築しています。(詳細は割愛)
ちょっと古いですが、3年前に私が書いたブログが参考になると思います。
(多分今でも大丈夫だと思います・・・)
ルーティング
Rails.application.routes.draw do
post '/m5hack/' => 'uchiwas#m5hack_post'
get '/m5hack/' => 'uchiwas#m5hack_get'
end
HTTPリクエストに対する処理
class MfivesController < ApplicationController
require 'net/http'
require 'uri'
require 'json'
def m5hack_post
# mySQlにMfiveというデータベース、idが500(500という数字に今はない)のところにrunningFlagというカラムを設定している
message =params[:runningFlag]
mfive = Mfive.find_by(id:500)
mfive.runningFlag = message
mfive.save
end
def m5hack_get
mfive = Mfive.find_by(id:500)
render :json => mfive
end
end
Unity側
ポイントはHTTP通信です。
こちらに記事を書いてます。
UnityでHTTP(GET)通信によるJSONデータ取得
https://qiita.com/tatsuya1970/items/afa299a260d09c4672aa
ユニティちゃんの格闘モーションのアセット
HQ Fighting Animation FREE
についているプログラムにHTTP通信のプログラムを入れただけです。
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
//
// アニメーション簡易プレビュースクリプト
// 2015/4/25 quad arrow
//
// Require these components when using this script
[RequireComponent(typeof(Animator))]
public class IdleChanger : MonoBehaviour
{
private Animator anim; // Animatorへの参照
private AnimatorStateInfo currentState; // 現在のステート状態を保存する参照
private AnimatorStateInfo previousState; // ひとつ前のステート状態を保存する参照
// Use this for initialization
void Start()
{
// 各参照の初期化
anim = GetComponent<Animator>();
currentState = anim.GetCurrentAnimatorStateInfo(0);
previousState = currentState;
}
void Update()
{
StartCoroutine(connect("URL"));
}
IEnumerator connect(string url)
{
WWW www = new WWW(url);
yield return www;
JSONObject json = new JSONObject(www.text);
JSONObject runningFlag = json.GetField("runningFlag");
if (runningFlag.n > 1)
{
anim.SetBool("Run", true);
}
else
{
anim.SetBool("Run", false);
}
}
}