ぐーるらいふ

底辺。

【Unity】タッチした位置にuGUI(RectTransform)を表示する

お疲れ様です。ぐーるです。
最近はなんかサーバだけではなく、採用だ評価だと色んな所まで見てたりして、
ちょっとアップアップしています。色んな人と会話するのって難しいです。

unityroom以外でもなんかゲーム作ってて、ふと
「指定位置にuGUIでテキストと画像を出したいなー」
と思ったので、実装したのですが、なんか思ったように上手く行かずにちょっと困ったので
メモ代わりにまとめておきます。

タッチした位置にuGUI(RectTransform)を表示する

普通のGameObjectだったらScreenToWorldPoint()とか使いますよね。
こんな感じ。

f:id:ghoul_life:20181113000239g:plain

public GameObject cubePrefab;
	
// Update is called once per frame
void Update () {
        if (Input.GetMouseButtonDown(0))
        {
            var mousePosition = Input.mousePosition;
            mousePosition.z = 10;
            var pos = Camera.main.ScreenToWorldPoint(mousePosition);
            var cube = Instantiate(cubePrefab);
            cube.transform.position = pos;
            cube.transform.SetParent(this.transform);
        }
}

が、RectTransformではどうするんだろうと言うとこうします。
タッチした位置にInstantiateしてDoTweenでアニメーション付与して終わったら消す。

f:id:ghoul_life:20181112235926g:plain

// uGUIのprefab
public GameObject itemPrefab;

// Update is called once per frame
void Update () {
        if (Input.GetMouseButtonDown(0))
        {
            var canvas = this.GetComponent<Canvas>();
            var canvasRect = canvas.GetComponent<RectTransform>();

            Vector2 localpoint;
            RectTransformUtility.ScreenPointToLocalPointInRectangle(canvasRect, Input.mousePosition, canvas.worldCamera, out localpoint);
            var item = Instantiate(itemPrefab);
            item.transform.SetParent(this.transform);
            item.GetComponent<RectTransform>().anchoredPosition = localpoint;
            DoTweenUtil.UpToRectTransform(item);
        }
}

補足でDoTweenのコードも

    public static void UpToRectTransform(GameObject gameObject)
    {
        var rectTran = gameObject.GetComponent<RectTransform>();
        if(rectTran != null)
        {
            rectTran.DOMove(new Vector2(0 , 50) , 1.0f)
            .SetRelative(true)
            .OnComplete(() => {
                UnityEngine.Object.Destroy(gameObject);
            })
            .SetEase(Ease.OutCubic)
            .Play();
        }
    }

こんだけだけど

なるほど、RectTransformUtilityなんて便利なものがあるのね。
また一つ勉強になりました。

もうすぐunity1weekが始まりますね。お題は「クリスマス」ではないかと思っているのですが、
そんなことないか。
新型iPad ProとApple Pencilを衝動買いしてしまったのでお絵かき練習だけは継続しています。

【Unity】いい感じにデータクラスをList表示したい【Inspector】

なんか連投です。
きっとこの後間が空きます!
時間とやる気があるときにやっとけ!って事ですね。

リスト表示したい

なんか簡単なマスタデータ的なデータ持ちたくて
でもcsvにするほどでも無くて、でも折角Unity使ってるんだからオシャレにリスト表示したい。

f:id:ghoul_life:20181029235212p:plain

こんな感じにInspectorを活用したい。
調べればすぐ出てくるかもしれないけど、自分でもメモっておく。

PropertyDrawerとReordableList

ソースから。Dataクラスをリスト表示する最小限な構成を紹介

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

[System.Serializable] // <- これが大事。忘れずに
public class Data {
    public int _id;
    public string _name;
    public DataList.DataActionType _actionType;
}
using UnityEngine;

// GameObjectに付けるのはこれ。
public class DataList : MonoBehaviour
{
    public enum DataActionType
    {
        NONE,
        TYPE1,
        TYPE2,
        TYPE3
    }
    [SerializeField] Data[] _dataList;
}

以下はEditor拡張だ。

// Project/Editorの下に配置でもOK
#if UNITY_EDITOR

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

[CustomPropertyDrawer(typeof(Data))] // DataクラスのInspector表示をカスタム
public class DataPropertyDrawer : PropertyDrawer {
    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    {
        // 表示幅
        float[] widthes = { position.width * 0.2f, position.width * 0.5f, position.width * 0.3f };

        if (property != null)
        {
            position.width = widthes[0];
            EditorGUI.PropertyField(position, property.FindPropertyRelative("_id"), GUIContent.none); // フィールド名を指定

            position.x += position.width;
            position.width = widthes[1];
            EditorGUI.PropertyField(position, property.FindPropertyRelative("_name"), GUIContent.none);

            position.x += position.width;
            position.width = widthes[2];
            EditorGUI.PropertyField(position, property.FindPropertyRelative("_actionType"), GUIContent.none);
        }
    }
}
#endif
// Project/Editorの下に配置でもOK
#if UNITY_EDITOR

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using UnityEditorInternal;

[CustomEditor(typeof(DataList))]
public class DataListEditor : Editor
{
    private ReorderableList _reorderableList; // ReorderableListを利用して、並び替えや+-ボタンを使えるようにする

    void OnEnable()
    {
        _reorderableList = new ReorderableList(serializedObject, serializedObject.FindProperty("_dataList"));
        _reorderableList.drawElementCallback += (Rect rect, int index, bool selected, bool focused) =>
        {
            SerializedProperty property = _reorderableList.serializedProperty.GetArrayElementAtIndex(index);
            // PropertyFieldを使ってよしなにプロパティの描画を行う(PropertyDrawerを使っているのでそちらに移譲されます)
            EditorGUI.PropertyField(rect, property, GUIContent.none);
        };
        _reorderableList.drawHeaderCallback += rect =>
        {
            EditorGUI.LabelField(rect, "id | name | action type");
        };
    }


    public override void OnInspectorGUI()
    {
        _reorderableList.DoLayoutList();
        serializedObject.ApplyModifiedProperties();
    }
}
#endif

これだけでOK

上記のコードだけで画像のようなリスト表示が出来るようになる。便利~。

【Unity】【Android Plugin】android連携で画像を読み込みたかっただけなのにちょっとハマった話

お疲れ様です。ぐーるです。
最近もお絵描きの練習と新しいゲームの開発をコツコツやってます。
もうすぐ1weekまた始まるんでしたっけ。
ヤバい。Inventoryシステムの完成を急ぎたい。

Androidプラグイン

UnityからAndroidネイティブの機能を使いたい場合はプラグインを作成する必要があります。
作り方についてはちょっと調べると沢山出てくるのでここでは割愛。
プロジェクト作って、
新しくモジュール追加でLibrary選んで、
適当にコード書いてビルドして、
aarからjar取り出すかbundlesの下から取ってきて、
Plugins/Androidの下に配置すればOKってな具合です。

まぁ大概はビルド&配置task作って楽しますかね。

画像が出ない?

画像を読み出す時はこんな感じのコードを書きます。

// res/drawable/hogehoge.pngを読み出す
Context unityContext = UnityPlayer.currentActivity.getApplicationContext();
int resourceId = unityContext.getResources().getIdentifier("hogehoge", "drawable", unityContext.getPackageName());

ふむふむ、なるほど。ではこのまま書こう。
と書いてみるとhogehoge.pngが読めない。
えー何故だ!?Plugins/Android/res/drawableの下にちゃんと置いてるよ?と。
今回はこのお話。

結論

ハッキリ言ってしまえば配置ミスです。
こう配置する必要がありました。

// Plugins/Android/の下
res/drawable-hdpi-v4/
res/drawable-ldpi-v4/
res/drawable-mdpi-v4/
res/drawable-xhdpi-v4/
res/drawable-xxhdpi-v4/
res/drawable-xxxhdpi-v4/

正解は全部作って全部にちゃんとhogehoge.png入れとけ!です。これだけ。

出来上がったjarかAndroid exportしたAndroidプロジェクトを見てみればすぐわかりますが、
res/drawableの下に置いたビルド後に画像が無くなってるんですよね。
恐らくUnity側でそこは自動でアイコンを配置したりなどで使ってて
何か入れておいても無視されてる様子。

Androidやってる人からしたら常識なのかもしれないですが、
dpiによってリソース分けられてるんですよね。すっかり忘れてました。

余談

アイコン読み出したいときはこう書きます

Context unityContext = UnityPlayer.currentActivity.getApplicationContext();
// iconを読み出す
PackageManager packageManager = unityContext .getPackageManager();
ApplicationInfo applicationInfo = null;
try
{
    applicationInfo = packageManager.getApplicationInfo(unityContext .getPackageName(), PackageManager.GET_META_DATA);
}
catch (PackageManager.NameNotFoundException e)
{
    e.printStackTrace();
    return;
}
appIconResId = applicationInfo.icon; // iconのリソースIDを取り出す

【Unity1week】一週間ゲームジャム「あつい」に参加【Unity】

お疲れ様です。お久しぶりです、ぐーるです。
仕事の方ではゲームとは関係ないまま、すっかり中堅、それ以上となり
打合せ、社外MTGなど座席に余り居ないような毎日を送っています。
Unityの新規開発プロジェクトとかやりたいです。

前回からまた長い間が空いてやってきました、unity1week。
自分からするとつい先日宴ゲームジャムがあったので、
そこまで間が無かったようなそんな印象なんですが、やっぱりこっちも参加したいと。

ghoul-life.hatenablog.com


そうでもしないとunityを触る機会とか無いんだものー

お題について

これまた難しい。どうしようかウンウン唸ってみるが全然アイデアは降りてこない。
・おでん?
・太陽?
・お湯?
こういう時にマインドマップとかやるといいのだろうけど、
流れに身を任せて日々を過ごす。

とりあえず漠然と考えていたのは
「自分でキャラなにか描きたいなぁ」
だった。

相変わらず下手だが、下手の横好き、別に見られても減るもんじゃないし!
(でもリアル知り合いには言わないし、見せないw)
という気持ちで、
自分でも描けそうで、
作りやすそうで、
カジュアルで、
工数は2日ぐらいないい感じの無いかなーと案を巡らせていると
よくある正弦波とかを利用した波乗りとかどうだろうとふと思いついた。

なみのり

昔メッシュを利用したマップを作ってその上を滑らせたりしてたんで
これならすぐ出来るなーと思った。ひっくり返ったらゲームオーバーにしようと。
とりあえず枠組みはすぐ出来るし、キャラも波乗りしている女の子でいいじゃんと。

サーフィンやボディボードとかも思ったけどわかりやすく浮き輪にしました。
浮き輪なら遅くても平気だし!
と描き始める。

f:id:ghoul_life:20180917142613j:plain

ざっとこんな感じで座ってて〜髪は長めで〜
とか試行錯誤をやってるうちにどんどん深みにハマっていく。(ここがめっちゃ楽しいんだけど)
「他のバリエーションとか浮き輪も乗るタイプのものとかアニメーションとか付けたいなー」
と思っているうちに期限は刻一刻と迫っていた。

ゲームについて

もうこっちは特に言うこと無いですね。
uvスクロールで水面を動かしつつとplaneを利用してスクリプトからmesh変形させてるだけ。

    private void Wave()
    {
        _mesh = this.GetComponent<MeshFilter>().mesh; // planeのメッシュ
        _meshCollider = this.GetComponent<MeshCollider>();
        _verticies = _mesh.vertices;

        int counter = 0;
        int yLevel = 0;

        for (var i = 0; i < iLen; i++) 
        {
            for (var j = 0; j < jLen; j++)
            {
                Calc(counter, yLevel);
                counter++;
            }
            yLevel++;
        }

        _mesh.vertices = _verticies;
        _mesh.RecalculateBounds();
        _mesh.RecalculateNormals();
        

        _meshCollider.sharedMesh = _mesh;

    }

    private void Calc(int i , int j)
    {
            var x = (_verticies[i].x + this.transform.position.x) / _detailScale;
            var y = (_verticies[i].y + this.transform.position.y) / _detailScale;
            _verticies[i].z = Mathf.PerlinNoise(x, y) * _heightScale;
            _verticies[i].z -= j;
    }

これプレイが進むと自動でパラメータが切り替わっていくんだけど
この切り替わりがちょっと唐突なのが微妙だった。
今後の課題だなと。lerpで向かっていくといいのかな。

(実はこんなトリッキーな波にすることとかも出来るのです)

f:id:ghoul_life:20180917164252p:plain

絵について

結局描けたのは
・通常
・ジャンプ時
・落ちた時
の3つだけ。
あとUIパーツとかそういったものも手描きで作ってたりしてます。

次回について

次ももちろん参加します。

それとは別で次のゲームの構想は決まっていて
作り出していきたいのですが仕事が忙しい…。
平日は10-23が標準で日付跨ぐ、朝までコースもしばしば。
これで家族がいる人とかどうやって暮らしてんだろう?
とか全然わかりませんね。

あ、宴ゲームジャム、賞ほんとにありがとうございました。
ADVの話のアイデアも練っておこう!
「Unity & 宴ノベルゲーム開発入門」出版記念オンラインゲームジャム | 無料ゲーム投稿サイト unityroom - Unityのゲームをアップロードして公開しよう

【Unity】「Unity & 宴ノベルゲーム開発入門」出版記念オンラインゲームジャム に参加しました

https://unityroom.com/games/shirakisou

先日、ゲームジャムへの提出が完了した。
今回は初のADVということで、思ったこととか大変だったことでも書いてみようかなと。
あんまり技術的な事はありません。基本は全て宴任せ。

ADVについての想い

昔(SFC時代)はかまいたちの夜とかそういったサウンドノベルっていうジャンルが流行った事がありました。

時代は流れ、逆転裁判ダンガンロンパといったカジュアルなものがヒットしたり、
シュタインズゲートが大ヒットしてアニメ化映画化までして、長期ヒットを続けていたり
四十八(仮)がある意味有名になったりと、緩やかな進化を続けているものの、
大きくは変わらず、基本は文章力で勝負しているジャンルになるのかなと思います。

www.famitsu.com
こんなインタビューとかもありました。

それに挑戦しようと言うのは無謀な感じがしましたが、
やるだけやってみようと言うわけでまずは適当なメモ書きから始めました。

メモ書き

・殺人事件を題材にする

容疑者は三人
- 友人のおじさん
- 恋人の女性
- 仕えていたメイド

死因は背中から刺殺
ナイフは死体に刺さったまま
部屋は施錠されていた

キッチンにいた
居間にいた
部屋に居た
でアリバイはなし

誰に話しかけよう
・三人
・もう充分(犯人当てに)

3つの質問
・殺された人
・その他1
・その他2

おじさん
・十年来の友人だった
お金を借りていた事もあったが、今はもう無い

・最近付き合いだしたと聞いた
今回が初対面

・三年ほど前からいるメイドだ
ほとんど会話したことがない

当初はこんな感じでした。
思いついた設定や状況などをとりあえずメモる。
そして繋いでいこうとしてました。

エンディングを先に作る

誰かが言っていた。ゲームはエンディングから作れと。
そうしないといつまで経っても終わらないと。

なので、犯人をざっくり決めて、エンディングの結びの言葉まで
先に決めてました。
これが無かったら絶対間に合ってなかった…。
ありがとうセンパイ。

どんどん間延びする文章

OP -> 到着 -> 環境 -> 人物紹介 -> 事件 -> 調査 -> 解決 -> ED

当初はこんな流れにしようと決めていました。
「二日目とか無いと短すぎるかなー」
とか余裕ぶっこいてたらとんでもなかった。

とりあえず書く
->
読み直す
->
違和感を直す
->

のループで精度を上げていて
「ここ唐突だな」
と思ったところを直し続けていると、
あっという間に10行、20行と増える。

気がついたら三万文字を超えていた。

「あ、こりゃダメだ」
と思い切って組み直しをすることに。

思い切って

要点だけに絞っていく作業。
だが、最小限の人物紹介は必要だなとその辺りも組み直し。
最初にミステリーですよ!ということを伝えるために殺人現場からのスタートにした。

事件発覚 -> 人物紹介 -> 事件 -> 解決 -> ED

とシンプルな座組に。

もう少しゲームらしくするには、マップを移動することが出来たり、
質問する内容を自分で選択出来たりといった部分を作れば良かったのですが、
どうしてもプレイ時間が間延びしてしまってそれは断念しました。

個別に会話をして人となりを知るシーンなどもあったのですが、泣く泣く外しました。

宴について

技術的な事は無いとか言っちゃったけど、ちょっとだけ。
とにかく言えることは

「困ったらSample.xlsを見ろ」

これに尽きる。これに全てが乗っていた。
ですが、とりあえず自分が使えるようになるために要点に絞って調べたことを。

xlsのシート「Start」から始まる
分岐:Selection
ラベルに飛ぶ:Jump
ローカルラベル:**~~~
シート名:*~~~
キャラの表示:Character , CharacterOff
頻出しそうなコマンドをメモ
- FadeIn , FadeOut : フェードイン、フェードアウト。 Arg6で秒数を指定出来る
- Wait : 待機。Arg6で秒数指定
- bg : Arg1で指定した背景に差し替え
- Sprite : 背景の上に出す画像を指定
- SpriteOff : 差し込み画像を削除
- Bgm , Se のサウンド

と使いたい機能だけに絞って少しずつ把握していった。
特にLayerは非常に強力なので、これは使いこなしたいし、
自分でも作れるようになりたい。

感想

製作期間は1week challengeと同じ一週間です。
最初は本当にボリューミーでした。

文章を書く、ということが国語の授業とか以外では本当に初めてだったのですが
思ったよりも書くの楽しかったなーと。また書きたい。
ですが、文章を書くだけなら簡単なんですが、まとめるのは本当に難しかったです。

そして最後に、EDはちょっと切なげなEDになってます。
良ければちょっとプレイしてもらえると、そしてハートを押して下さいー!

推理ADV 白木荘の殺人 | 無料ゲーム投稿サイト unityroom - Unityのゲームをアップロードして公開しよう

【Unity1week】一週間ゲームジャム「ぎりぎり」に参加 前編?【Unity】

前置き

Unity unity1week「ぎりぎり」に参加しました。
今回作ったのはこちら。脱出ゲーム。

f:id:ghoul_life:20180612201305p:plain
https://unityroom.com/games/giriescape


なんでこんなめんどくさいのを選んだんだ…と。

パッと見でわかる。

  • アイテムマスタ
  • メッセージマスタ

が必要だということが。


最初にお題の「ぎりぎり」と聞いて、最初に思いついたのがコレで、
一度挑戦してみたかったなーと思ってたので、「まぁいいか、やってみよう」と挑戦することにしました。

設計について

基本的には

  • キャラが移動
  • オブジェクトをターゲット
  • アクションボタン押下でメッセージが出る
  • ギミックがあればギミックを処理
  • 結果メッセージYES
  • 結果メッセージNO

というような流れになるだろうと想定。

この時メッセージは所持しているアイテムによって違う、
またはアイテムを使用するとメッセージが変わる

といった具合だ。

すでにめんどくさい雰囲気が漂っている。

ざっとフローをまとめるとこんな感じだ。

f:id:ghoul_life:20180612173846p:plain
f:id:ghoul_life:20180612173856p:plain


力尽きたので、プログラム編は後日

【Unity】 【有料Assets】 Simple Bones Animationを使って適当に取ってきたキャラにオリジナルアニメーションを作る

お疲れ様です。ぐーるです。
お久しぶりになってしまった。
サラリーマンや学生も期の変わりは忙しいんですよね。

ProBuilderはどうした

やってるんですが、まだ記事的にまとまってなくて…
もうすぐUnityの勉強会もあるんで、そちらの情報と合わせて記事にしたいな

ProBuilderで学ぶレベルデザイン

Simple Bones Animation

Unity Asset Storeでいい感じのキャラを見つけた!
早速使ってゲーム作るぞ!
走りはこれで、攻撃はこれで…
あれ、ゲームクリア時になんかポーズしたいのにいい感じなの無いじゃん!

なんてことがあった時、3Dモデルが作れない自分を呪い諦めていたんですが、
どうやらこんな便利なツールがあると汗人柱さんが記事にしてたのを見つけました。

www.asset-sale.net

(ちょっと古い記事ですが。ほんと神)

おお、これイイじゃん、早速使ってみよう!と思いたち、買いました。
(有料です。4.95ドル…!)

assetstore.unity.com

事前準備

キャラクターはこいつを使います。

assetstore.unity.com


可愛い宇宙服シューターです。ライトなSFシューティングのプレイヤーにぴったり。
だが

  • Idle
  • Run
  • Run Back
  • Left
  • Right

しかアニメーションが無く、実際に撃つようなモーションはありませんでした。
(2018/04/13。updateで追加されたりするかもしれません。)
これに撃つアニメーションを作りたいと思います。

新規プロジェクトを立ち上げ、Simple Bones AnimationとSpace ManをImportしておきます。

1.space manのRigをHumanoidからLegacyに変える

これを行わないとSimple Bones Animationが上手く動かない

f:id:ghoul_life:20180413215704p:plain
f:id:ghoul_life:20180413215729p:plain

2.space_map_modelのPrefabを配置する

配置したらAnimatorを削除し、Animationに付随しているAnimation Clipを一旦全て外す。
これで新たなAnimation Clipを作ることができるようになります。
space manのRootを選択して、Add ScriptからSimple Bonesスクリプトを追加する
Root Nodeが空の状態になるので、Space Manの Pelvisをセットする。

f:id:ghoul_life:20180413215745p:plain

ここまでやるともうボーンがSceneビューに見えるはず。

3.Shot.animを作成

Animationが空っぽの状態でAnimationビューを開くと 新たなAnimation ClipがCreate出来る。
Createを押下して、Shot.animとしてanimファイルを作成

すると、Simple BoneのAnimationにShotが選択されている状態になる。
これで準備完了です。

f:id:ghoul_life:20180413215803p:plain

4.アニメーションを作る

SimpleBonesのAnimationから「Create Animation Keys」にあるPosition , Rotation , Scaleのいずれかを押下すると
ボーン周りのTransformがAnimationビューに紐付けることが出来る。
が、今回は使いません!

初期ポーズはIdleからコピーして持ってきます。

f:id:ghoul_life:20180413215818p:plain

そして動かしたいパーツを選択しつつ…動かして…Add Key!!
間違えたら…一度消して、直して再度Add Key!!

f:id:ghoul_life:20180414014342p:plain

5.Shotアニメーションが作れました

こんな感じでShotアニメーションが出来ました。

f:id:ghoul_life:20180414014419g:plain

簡単でしょう?と言いたいですが、自然なボーンアニメーション作るのは難しいですね…。
でもツールはほんと凄い。有料は優良なんですね!