みどりゲーム

主にUnityについての覚え書きです。 @G_game8783

制作したゲーム「TICK TACK CHEVY」を振り返る

 このたびプログラマーとして制作に参加していたゲームの開発に区切りがついたので、個人的なまとめとして書きます。(なのでだらだらと読みにくいですがご勘弁を)

 

制作したゲームはこちら(結構古い情報ですが…4月終わりまでには変えたい)↓

TICK TACK CHEVY (チーム:メル変)

 

 区切りというのは、先日開催された「福岡ゲームコンテスト(GFF AWARD)」に応募し、最終選考まで進み、最終審査プレゼンを経て、

「優秀賞」

楽市楽座賞」(協賛企業様選出)

「市長賞」(会場300人の投票によるエキシビジョン)

を頂きました!

 

 そもそもこのゲームは、東京工科大学メディア学部のプロジェクト演習(有志が集まって制作して先生にフィードバックを貰える)にて、東京ゲームショウ2016出展のために制作したものになります。

 プランナー2、プログラマー4、グラフィッカー2、サウンド1の8人のチームで制作を開始しました。最初はチーム全員で紙一枚の企画書コンペ(ペラコン)を行い、そこでグラフィッカーのアイデアをもとに、膨らませていきました。

続きを読む

【Unity】【LeapMotion】③左右の手を分けてジェスチャ取得(ついでにトラッキング開始/終了も)

②ではとりあえず、片手での握る/離すジェスチャができました。

今度は左右分けて、どっちが開いて閉じたかを取得したい。

ということで、前回使った
「MotionCtrl.cs」
「IMotionCallback.cs」
を改造してみる。

「MotionCtrl.cs」

using Leap;
using UnityEngine;
using System.Collections.Generic;
using System.Linq;

public class MotionCtrl : MonoBehaviour
{
    public List<GameObject> motionCtrlObjectList;

    private List<IMotionCallback> motionCtrlList;
    private int motionCtrlCount;

    private Controller leapCtrl;
    private Frame leapFrame;
    private List<Hand> handList;
    private Hand R_Hand, L_Hand;

    private bool isTracking;
    private bool isGrabbed_R, isGrabbed_L;
    private bool lastTrackingStatus;
    private bool lastGrabbedStatus_R, lastGrabbedStatus_L;
    private Vector3 convertedValue = new Vector3(0, 0, 0);

    private Vector3 handPosition_R, handPosition_L;
    /*
    public Vector3 HandPosition
    {
        get { return handPosition; }
    }
    */
    private void Start()
    {
        // Trackingと手の状態変化を返す対象のClass.
        motionCtrlList = motionCtrlObjectList.Select(ctrlObject => ctrlObject.GetComponent<IMotionCallback>()).ToList();
        motionCtrlCount = motionCtrlList.Count - 1;

        // App起動時にLeapMotionに接続.
        leapCtrl = new Controller();
        // StartConnectionの実行は必要?
        leapCtrl.StartConnection();

        isTracking = false;
        isGrabbed_R = false;
        isGrabbed_L = false;

        lastTrackingStatus = false;
        lastGrabbedStatus_R = false;
        lastGrabbedStatus_L = false;
    }

    private void Update()
    {
        leapFrame = leapCtrl.Frame();
        handList = leapFrame.Hands;

        isTracking = (handList.Count > 0);

        if (isTracking != lastTrackingStatus)
        {
            // Trackingの開始・停止をCallbackで通知.
            if (isTracking)
            {
                for (var i = motionCtrlCount; i >= 0; i--)
                {
                    motionCtrlList[i].OnTrackingStarted();
                }
            }
            else
            {
                for (var i = motionCtrlCount; i >= 0; i--)
                {
                    motionCtrlList[i].OnTrackingStopped();
                }
                // 手の位置をリセット.
                handPosition_R.Set(0, 0, 0);
                handPosition_L.Set(0, 0, 0);
            }
            lastTrackingStatus = isTracking;
        }

        if (!isTracking)
        {
            // Tracking中でなければ手の位置などは取得しない.
            return;
        }
        for(int NumHands = 0; NumHands < handList.Count; NumHands++)
        {
            if (handList[NumHands].IsRight)
            {
                // Tracking中なら手(Hand0)の平の座標値を取得する.
                handPosition_R = ConvertToUnityVector3(handList[NumHands].PalmPosition);
                // 手を握っているか(誤検知を考慮して開いている指の本数が1以下ならTrue).
                isGrabbed_R = (handList[NumHands].Fingers.Where(finger => finger.IsExtended).Count() <= 1);
                if (isGrabbed_R != lastGrabbedStatus_R)
                {
                    if (isGrabbed_R)
                    {
                        for (var i = motionCtrlCount; i >= 0; i--)
                        {
                            motionCtrlList[i].OnRightHandGrabbed();
                        }
                    }
                    else
                    {
                        for (var i = motionCtrlCount; i >= 0; i--)
                        {
                            motionCtrlList[i].OnRightHandReleased();
                        }
                    }
                    lastGrabbedStatus_R = isGrabbed_R;
                }
            }

            if (handList[NumHands].IsLeft)
            {
                // Tracking中なら手(Hand0)の平の座標値を取得する.
                handPosition_L = ConvertToUnityVector3(handList[NumHands].PalmPosition);
                // 手を握っているか(誤検知を考慮して開いている指の本数が1以下ならTrue).
                isGrabbed_L = (handList[NumHands].Fingers.Where(finger => finger.IsExtended).Count() <= 1);
                if (isGrabbed_L != lastGrabbedStatus_L)
                {
                    if (isGrabbed_L)
                    {
                        for (var i = motionCtrlCount; i >= 0; i--)
                        {
                            motionCtrlList[i].OnLeftHandGrabbed();
                        }
                    }
                    else
                    {
                        for (var i = motionCtrlCount; i >= 0; i--)
                        {
                            motionCtrlList[i].OnLeftHandReleased();
                        }
                    }
                    lastGrabbedStatus_L = isGrabbed_L;
                }
            }
        }
    }

    private void OnApplicationQuit()
    {
        // Appの終了時は切断する.
        leapCtrl.StopConnection();
        leapCtrl.Dispose();
    }
    private Vector3 ConvertToUnityVector3(Vector originalValue)
    {
        // Leap.VectorからUnityのVector3に変換する.
        convertedValue.x = originalValue.x;
        convertedValue.y = originalValue.y;
        convertedValue.z = originalValue.z;
        return convertedValue;
    }
}

変更点は、handList[0](最初に認識した手 二番目ならhandList[1])のところをisLeft/isRightで左右に分けて、コールバックも分けたところです。それに伴い変数も増やしてforで回しています。


そしてコールバックがこちら
「IMotionCallback.cs」

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public interface IMotionCallback
{
    void OnTrackingStarted();
    void OnTrackingStopped();
    void OnRightHandGrabbed();
    void OnLeftHandGrabbed();
    void OnRightHandReleased();
    void OnLeftHandReleased();
}

それを使うには、前回と同様に、
GetGesture.cs

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GetGesture : MonoBehaviour, IMotionCallback
{
        public void OnTrackingStarted()
    {
        Debug.Log("StartTracking Hand");
    }

    public void OnTrackingStopped()
    {
        Debug.Log("StopTracking Hand");
    }

    public void OnLeftHandGrabbed()
    {
        Debug.Log("LeftHandGrabbed");
    }

    public void OnLeftHandReleased()
    {
        Debug.Log("LeftHandReleased");
    }

    public void OnRightHandGrabbed()
    {
        Debug.Log("RightHandGrabbed");
    }

    public void OnRightHandReleased()
    {
        Debug.Log("RightHandReleased");
    }
}

こんな感じで使います。
この「GetGesture.cs」のついたオブジェクトを「MotionCtrl.cs」の「motionCtrlObjectList」にポイすればOK
f:id:Green_Game:20170221000000j:plain
今回は手本体につけていた「GetGesture.cs」をCameraに移動しました。
f:id:Green_Game:20170221001219g:plain

左右でグーパーできた!!!
(人差し指の誤検知は気にしない)(誤検知多いときは部屋を暗くするといいぞ!)

【Unity】【LeapMotion】②とりあえず握る/離すジェスチャ取得編

ジェスチャ取得編(握る/離す)

①ではとりあえず手がでました。

次は簡単なジェスチャの握る/離すをとってみよう!


mslgt.hatenablog.commslgt.hatenablog.com


こちらのサイトを参考に、作ります。

GitHub - masanori840816/LeapMotionCtrl: Unityを使ってLeapMotionのジェスチャー操作を検出するサンプルです。


こちらで公開されている、

「IMotionCallback.cs」

「MotionCtrl.cs」

をプロジェクトに入れます。

そして、とりあえずサンプルシーンのCameraに「MotionCtrl.cs」をつけて、「Motion Ctrl Object List」のなかに、「CapsuleHand_R」を入れます。

f:id:Green_Game:20170208115602j:plain

次に、「CapsuleHand_R」に、「IMotionCallback.cs」を継承したスクリプト「GetGesture」をつけます。

GetGesture.cs

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GetGesture : MonoBehaviour, IMotionCallback
{
    public void OnHandGrabbed()
    {
        Debug.Log("Grabed");
    }

    public void OnHandReleased()
    {
        Debug.Log("Released");
    }

    public void OnTrackingStarted()
    {
    }

    public void OnTrackingStopped()
    {
    }
}

そして再生すると…?

f:id:Green_Game:20170208115841j:plain
グー
f:id:Green_Game:20170208115838j:plain
パー

できた!!

複雑なジェスチャは指の開いているかどうかや、動きで作っていくのかな?

あとはこれを使ってゲームを作ってみよう。

次回に続く

追記:この回では片手だけしか取れない 次回に両手を

【Unity】【LeapMotion】①ゲーム内に手のオブジェクトを出す編

ゲーム内に手のオブジェクトを出す編

 

LeapMotion (Orion Beta)を買ったはいいが放置していた。 せっかくなので遊んでみる。

 

今回はとりあえず、ゲーム内に手のオブジェクトがでるよってとこだけをやってみよう。

 

といっても手を出すのは簡単で、LeapMotion をPCに繋げて、

Unity — Leap Motion Developer

UNITY CORE ASSETS をダウンロード。(2017年2月7日時 4.1.5)

f:id:Green_Game:20170207193335j:plain

UnityのプロジェクトにダウンロードしたPackageを入れると、こうなるはず。

f:id:Green_Game:20170207193726j:plain

あとはサンプルのデスクトップ版を開けば...f:id:Green_Game:20170207194448j:plain

はい出た!簡単!ノーコーディング!

 

ここまではググってわかった。そしてUnityちゃんとかの手を動かしたり、なでなでしたりできるらしい、すばらしい。

 

Hierachy見ると、右手がアクティブになっているのがわかりますね。手(指)にはRigidBodyとColliderがついているので、適当に箱とか置けば触れる。

こいつを利用して何かゲームを作りたい。

次回に続く。

 

 

 

 

 

GGJ2017inTUTに参加しました

f:id:Green_Game:20170123131546p:plain

 

クラゲって、いいですよね。

 

ということで、「クラゲが星を食べて見た目が変わる」ゲームを作りました!!!

 

今回のお題「WAVES」はクラゲの動きに出てます。

f:id:Green_Game:20170123131751p:plain

メインゲームは、中央のキングクラゲがいる星から子クラゲが飛んでいき、

f:id:Green_Game:20170123132318p:plain

その子クラゲで飛んでくる星を捕まえて、王様に食べさせるというものです。

文字に起こすと何言ってんだこいつですね!

 

下記のリンクからUnityプロジェクトをDLできますので是非やってみてください!

美食クラゲ | Global Game Jam®

 

初めてのGGJ参加&リーダーでしたが、約48時間笑いながらできたので良かったと思います。

TUTでは学生+社会人1~2人で、私たちは6人+1人のチームで制作しました。

社会人の方にかなり引っ張っていただいて、リーダーとしては力不足を感じました。

来年参加するときはぐいぐい引っ張っていけるようにしたいです…!

 

 

f:id:Green_Game:20170123133929p:plain

 

グラフィックの方にチームロゴを書いていただきましたありがとうございます!!

【Unity】Unityで困ったときに見るサイト・ブログ

Unityでゲームを作り始めるようになって、本以外にもインターネットで情報を血眼になって探すわけです。

ということで、頻繁に見るサイトやブログをまとめてみました。

 

サイト編

  • 公式マニュアル

docs.unity3d.com

Unityはマニュアルが充実していて、日本語訳もかなり進んでいるので、困ったらまず見ます。

docs.unity3d.com

マニュアルと同じ理由です。ここを見てわからなかったら改めてググります。

  • Qiita

qiita.com

プログラマのための情報共有サービス

ゲームに関わらず、技術系ならとりあえず登録して見ておきたい。

UnityでおすすめのAsset集(2016/08更新) - Qiita

たまにこういう記事を見て、Aseetをいじいじするだけで楽しい。

  • 素人が7日間クソゲーを作り続けてわかったこと

uinyan.com

名前の通りの記事です。作ったゲームの内容もそうですが、参考にしたサイトや書籍、「気が付いたこと」など見てみるといいと思います。

 

 

ブログ編

  • テラシュールブログ

tsubakit1.hateblo.jp

「Unity ブログ」でググると公式UnityBlogを差し置いて先頭に出てくるブログ。
とりあえずここはブックマークしておくべき。
技術的な記事が多く、とても丁寧でいつも大変お世話になっております。
 
特にこの記事は、触り始めてから半年たってから知り、もっと早く知っていればと後悔しました…
 
  • 凹みTips

tips.hecomi.com

こんなこともできるのか…という記事が多く、見てるだけでわくわくしてきます。
1つ1つの情報が細かく丁寧です。
 
  • 強火で進め

d.hatena.ne.jp

Unity以外にも、ツールやゲーム関係のイベントの情報が多いです。
 
  • コガネブログ

baba-s.hatenablog.com

Unity・C#の知っておくと得する・楽になる情報が多いです。
 
 
 
 紹介したものは私がよく見ている、というだけで、他にもいろいろなサイトを見ています。検索する力大事。

 

【Unity】Unityでゲームを作った時に読んだ本 2015~2016

Unityでゲーム制作をしようと思って最初にしたことが本漁りでした。

ということで、0から始めた私が1年半で読んだ(読んでいる)本を紹介します。

 ちなみにUnity5向けです。
 
「Unityで神になる本。」 初級
Unityで神になる本。

Unityで神になる本。

 

 

始めて触るならこの一冊 イラストでわかりやすく、面白く解説されているので、「分厚い本とか読みきれる気がしない…」と言う人でもOK。
0からでもそれっぽいものが簡単に作れます。
 
 
「ゲームの作り方 Unityで覚える遊びのアルゴリズム」 初級 中級
ゲームの作り方 改訂版 Unityで覚える遊びのアルゴリズム

ゲームの作り方 改訂版 Unityで覚える遊びのアルゴリズム

 

 

異なった種類のサンプルゲームが多数収録、ダウンロードできて、初心者には「こんなことできるのか!」中級者には「この仕組みはどこかで活かせそう」と思える本です。2Dアクションから音ゲーRPG、プロシージャル(自動的に)コース生成レースゲームまで、本当に幅広いです。
 
 
「ゲームアプリの数学 Unityで学ぶ基礎からシェーダーまで」 中級
ゲームアプリの数学 Unityで学ぶ基礎からシェーダーまで

ゲームアプリの数学 Unityで学ぶ基礎からシェーダーまで

 

 

Unityの本 と言うよりは、Unityを使ってゲームを作るのに必要な数学の知識をつける本。
シェーダーのことまでわかって、辞書的に使える本です。
数学苦手な人でも、無理にすべて理解しようとはせずに、必要な時に思い返せるようにしておくだけでも違うと思います。
 
ゲームプログラマになる前に覚えておきたい技術」 上級
ゲームプログラマになる前に覚えておきたい技術

ゲームプログラマになる前に覚えておきたい技術

 

 

セガの新人教育カリキュラムを元に書かれた本です。
この本はUnityとは関係ありませんが、ゲームプログラミングについてより理解を深めたいなら読むべき本です。
前提としてプログラムの知識が多少必要なので難易度が高いですが、プログラマゲームプログラマーになりたい人は入りやすいと思います。
 
 
 
他にも最初のころは本屋でたくさんの本を立ち読みしました。
紹介しといてなんですが、今の自分に合った本をパラパラとめくりながら見つけるのがいいと思います。