gologiusの巣

プログラミング、モデリングなどのメモです。誰かの役に立てるとうれしいです。

Unityでオブジェクトを割る

Unityでこんな感じで画像を割ります。

f:id:gologius:20170819124203g:plain

ちなみに予め破片モデルを用意する方法です。なので、毎回割れ方は同じです。 有料Assetならもっといいのがあるのですが。

ソース

さっさとデータ欲しい、見たい人はこちら github.com

説明

先に述べたように、予めモデルを作っておいて破壊時に散らかす方法です。 DebrisにRididbodyとColoderを設定した上で非表示(SetActive(false))にしておいて、スペースキーを押すと Coliderのおかげで勝手に弾けて散らかる、という感じです。

GameObjectのDebrisの子要素に、破片用オブジェクトがないと、動かないので注意してください。

モデルはMetasequoiaで作成しました。

f:id:gologius:20170819124901p:plain

using UnityEngine;
using System.Collections;
using System.IO;


/// <summary>
/// 条件
/// * このGameObject以下に破片用の子GameObject(以下破片オブジェクト)がある
/// * 破片オブジェクトにRigidbodyとColiderが設定されている
/// </summary>
public class ImagePanel : MonoBehaviour {

    [Tooltip("表示させる画像")]
    public Texture texure = null;

    [Tooltip("破壊前に見える板")]
    public GameObject panel;

    [Tooltip("破壊後の破片を纏めているオブジェクト")]
    public GameObject debris;

    private bool isFinish = false; //debug

    void Start()
    {
        //エラー処理
        if (texure == null)
        {
            Debug.LogError("Texture is null");
            isFinish = true;
            return;
        }

        debris.SetActive(false); //飛び散らないように非アクティブにしておく

        //Texture設定
        panel.GetComponent<Renderer>().material.mainTexture = texure;
        foreach (Transform child in debris.transform)
        {
            child.gameObject.GetComponent<Renderer>().material.mainTexture = texure; //破片すべてにTexture設定
        } 
    }

    void Update () {
        //debug スペースキーを押すと爆散する
        if (Input.GetKeyDown(KeyCode.Space) && !isFinish)
        {
            crash();
            isFinish = true;
        }
    }


    public void crash()
    {
        debris.SetActive(true); //破片を表示
        debris.transform.parent = null; //Destroy(this.gameObject)に巻き込まれないように
        Destroy(debris, 10.0f);


        Destroy(this.gameObject);
    }
 }

最初は破壊前の板、このサンプルではPanelは使用していませんでした。 ただ、

  • ヒビが見える(透明なマテリアルを適用したときには特に)
  • 処理速度が遅い(Coliderの衝突判定が常に走るから)

の理由で、破壊前の板を用意しています。

Android MainActivityでClassNotFoundExceptionが出る。

Android Studioで実機テストしたときに、こんなエラーが出たときの自分の対処法。

とりあえずこうしたら動いた、的な記事なのであまり技術的なことに期待しないでください

08-14 16:32:02.973 22144-22144/com.gologius.infoclip E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.gologius.infoclip, PID: 22144
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.gologius.infoclip/com.gologius.infoclip.MainActivity}: java.lang.ClassNotFoundException: Didn't find class "com.gologius.infoclip.MainActivity" on path: DexPathList[[zip file "/data/app/com.gologius.infoclip-2/base.apk"],nativeLibraryDirectories=[/data/app/com.gologius.infoclip-2/lib/arm64, /vendor/lib64, /system/lib64]]
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2420)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2569)
at android.app.ActivityThread.access$900(ActivityThread.java:150)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1399)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:168)
at android.app.ActivityThread.main(ActivityThread.java:5885)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:797)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:687)

Caused by: java.lang.ClassNotFoundException: Didn't find class "com.gologius.infoclip.MainActivity" on path: DexPathList[[zip file "/data/app/com.gologius.infoclip-2/base.apk"],nativeLibraryDirectories=[/data/app/com.gologius.infoclip-2/lib/arm64, /vendor/lib64, /system/lib64]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
at android.app.Instrumentation.newActivity(Instrumentation.java:1085)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2410)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2569) 
at android.app.ActivityThread.access$900(ActivityThread.java:150) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1399) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:168) 
at android.app.ActivityThread.main(ActivityThread.java:5885) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:797) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:687) 

Suppressed: java.lang.ClassNotFoundException: com.gologius.infoclip.MainActivity
at java.lang.Class.classForName(Native Method)
at java.lang.BootClassLoader.findClass(ClassLoader.java:781)
at java.lang.BootClassLoader.loadClass(ClassLoader.java:841)
at java.lang.ClassLoader.loadClass(ClassLoader.java:504)
... 12 more
Caused by: java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack trace available

経緯

別のノートPCで開発したプロジェクトファイルを、別のPCに移した際に発生

原因を調べる

原因としては、

  • AndroidManifest.xmlのアクティビティ名が間違っている
  • Andorid Private Libraryがエクスポートされていない

が考えられるそうです。ただ、Eclipseで開発している情報が多くて、そのまま適用、ということはできませんでした。 いろいろやってみましたが、どうもこれが原因ではなさそうです。

次に、adb install -r xxxx.apkでインストールすればとりあえず動く、という記事を見ました(ソース忘れました…たぶんStackOverflowです) やってみると、見事動きました。しかしAndroidStudioでは動かないので根本的解決にはなってない・・・

最終的な解決策

AndroidStudioでBuild->Clean Projectすれば治りました。 しかし原因は不明のまま・・・

Unity一週間ゲームジャム テーマ「夏」に参加しました

先月参加したゲームジャムに、もう一度参加しました。二回目です。 今回は

  • 前回の反省を生かす
  • 前回と違う技術を使う(追加する)

ということを目標にゲーム制作しました。

何を作るか決める

僕はまず何を使うかを決める派なので、テーマ「夏」から連想するものを出します。

・・・ビーチとカニとスイカが思い浮かびました。カニはモーション作るのだるそうなので却下。 ここからさらに、前作ったガンダムバルバトスから「潰す」を連想しました。

そしてスイカを潰すゲームを作ろうと決めました。 後から調べたらネタかぶり多かったけどね。

プレイヤーは日焼けした兄さんがよいなと思ったので、MakeHumanというソフトで作成しました。 なんかポリ数が多そうだったので、Mesh Compressionで圧縮してます。 f:id:gologius:20170730150335p:plain https://docs.unity3d.com/ja/540/Manual/FBXImporter-Model.html

ガリガリ作る

前回の反省として

  • UIがアニメーションしない
  • ゲームのルールが分かりづらい

がありました。なので、今回はMecanimを勉強して組み込みました。 また、ゲームのルールも単純にしました。

二日目の進捗

完成

で、ロゴとか作ってこんな感じになりました。

www.youtube.com

ここから遊べるのでどうぞ https://unityroom.com/games/suika_crash

工夫点

Animatorでいろいろ動かした

タイトル画面、UI、ハンマーの動きなどです。Animatorについては後々記事を書こうかと思います。 ちょっと動かすだけでそれっぽくなるのでおススメです。

ただ、AnimatorControllerがどんどん増えていくのがなんか嫌だった。 AnimationClipを一つしか使用してないのに、Stateとかいちいち設定しないといけないのもなんか微妙。 アニメーションの順番指定(タイトルが動いて、そのあとボタンが・・・みたいな)も結局スクリプト書きました。

ここらへんの不満点はUnity 2017のPlayableやTimeLineを使えば改善されるっぽいので、今度使ってみたいです

爽快感

ハンマーの衝撃範囲を大きくしたり、潰した時の汁飛ばしとか残り汁とか。ParticleSystem万歳

感想と反省

前回よりはマシなものができた気がします。ただ、ハンマーを出現させると視界が悪くなるのでそこは残念。

反省としては、ゲームの雰囲気をおしゃれにできない?というのを思いました。 うまく説明できないんですけど、ライディングとか、全体の色?とかUIの配置、デザインはもっと改善の余地あるかなぁと思いました。

全然関係ないけど、今回の参加者が少ない気がした。学生の定期試験やスプラ2、ドラクエとかとかぶってたからかな?

Akeytsu IKの使用方法メモ

Akeytsuの使用方法メモです.日本語の情報が少ないので参考になれば幸いです. 使い始めてからまだ日が浅いので間違っていたらコメントお願いします.

IKの設定

Ctrlキーを押しながら,ボーンを二つ選択.選択すると,下の画像の赤枠内が黄色に光る. f:id:gologius:20170722110151p:plain

光っているボタンを押すと,IKボーンが追加される. f:id:gologius:20170722110300p:plain

モーションを作る

左下のボタンのボタンでモード切り替えができる. f:id:gologius:20170722110349p:plain

ここからがポイントなのですが,IKは元あったモーションには適用することができず,新しく作ったモーションから適用することができるみたいです. 下の画像で説明します. Runというモーションを新しく作ったとします.設定したIKはこのモーションでは使用することができます. しかし,元あったStandなどのモーションでは使用することができませんf:id:gologius:20170722110519p:plain

IK自体が使用できないのではなく,モーションを作成した時点で設定されているIKボーンしか使用できない,ということです. MMD使ったことないのでわかりませんが常識なのかな...?

Androidアプリ開発でToolbar(一番上のバー)の設定

f:id:gologius:20170708075209p:plain

一番上のバー(Toolbar)を編集しようと思って,どこをいじればいいのかわからなかったのでメモ.

開発環境(何を書けば...)

  • min sdk version 21
  • Compile sdk version : API26 : Android8.0
  • build tools version : 26.0
  • ActivityはMainActivity一つ

前提

  • ActivityはMainActivity一つ
  • アプリのテーマをxxxxx.NoActionbarにしている
  • デザイナなりxml直打ちなりでToolbarを挿入している
  • MainActivityのonCreate内に以下のような記述がある
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); //R.id.toolbarは各自で設定したidを入れる
setSupportActionBar(toolbar);

本題

MainActivity内に以下の関数を追加.これによりToolbar内によくみるアイコン付きボタンが表示される準備ができる.

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

次に,xmlファイルを作成する. 先ほどのmenu_mainxmlファイルの名前と(おそらく)同じ

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context="com.gologius.infoclip.MainActivity">
    <item
        android:id="@+id/action_settings"
        android:orderInCategory="100"
        android:title="@string/action_settings"
        android:visible="true"
        app:showAsAction="never"
        tools:title="設定" />
    <item
        android:id="@+id/action_about"
        android:title="このアプリについて"
        android:orderInCategory="200"
        app:showAsAction="never" />

    <item
        android:id="@+id/action_search"
        android:icon="@drawable/ic_search_black_24dp"
        android:title="search"
        app:showAsAction="always" />

    <item
        android:id="@+id/action_add"
        android:icon="@android:drawable/ic_menu_add"
        android:title="add"
        app:showAsAction="always" />
</menu>

・・・(縦)のアイコンには,app:showAsAction="never"にしたものが入る. なので,app:showAsAction="never"が一つもなければ・・・(縦)アイコンは表示されない.

たぶんこの解釈であっているはず.

Unity一週間ゲームジャム テーマ「積む」に参加しました

概要

ゲームジャムに参加しました。期間とテーマが決められて、指定の場所にアップロードするだけのお手軽ゲームジャムです。 特に順位付けもありません。

Unity 1週間ゲームジャム | ゲーム投稿サイト unityroom - Unityのゲームをアップロードして公開しよう

参加理由

就職したところで、思いのほか情報系の技術に触れない、情報系の同期もいなくて・・・みたいな理由(説明難しい)。 単純に研修の時期なので仕方ない面はありますが・・・(けどPCすら触れないのはどうなの

とりあえずメインで使うものを決める

テーマ「積む」から連想するものを探します。

・・・土のうが思い浮かびました。 最初の印象を大事にしたいのでこれでいくことに。

土のうの3Dモデルなんかないし作るか~とか思いつつ一応探したらあった。 で、とりあえず位置決めと設置を実装したのが以下の動画

ゲームとして成り立たせる

土のうといえば水などの浸水を防ぐものです。 「防く」ものです。 水を防ぐ、のはビジュアル的にどうやるのがいいか思い浮かばなかったので、弾を防ぐことにしました。

これブロックくずしじゃ( ^ω^)・・・

防ぐだけでは微妙な気がしたので、敵と弾を増やして、エフェクトもつけて綺麗な感じになるようにしました。

で、あとはTopとかゲームクリア画面とか作って完成。

www.youtube.com

技術的な話

正直特に難しいことはしてません。ソースも公開したいと思ってる(思ってるだけでGithubにUPし忘れる) ので、見たら大したことしてないなーとしか思わないかと。 ただ、WebGL用にビルドするのも初めてだったので、日本語が表示されない問題で躓きました。

qiita.com

弾の反射はスクリプト書くよりも、Physical Material割り当てる方が楽だし確実っぽい。

あと、シーン切り替え時に画面が暗くなる問題が発生した。 古いバーションの解決策はあったけど、新しいバージョンはあんまりなかった。 結果的に以下の赤枠のAuto Generationのチェックを外してGenerate Lightingボタンを押して事前にデータを作っておくことで対応した。 .sceneと同じ場所にフォルダが出力されるけど、消したらダメ

f:id:gologius:20170625091236p:plain

反省と今後に向けて

  • 毎回同じ機能実装、作業をしている気がするので、テンプレートを作っときたい
    • 次回にも生かせる
  • クリア画面でスコアを出力していない
    • ごめんなさい。そのうち直すか
  • AIがバカ
    • 自分の陣地内に留まってない。
  • ゲームとして面白いかが微妙
    • 運ゲー化してる。敵を倒す爽快感みたいなのはない
  • ロゴ、サムネがダサい
    • デザイン力の問題
  • 素材の問題
    • 拾ってくるとどうしてもかぶってしまう(オリジナリティの低下)
    • 実際BGMがかぶっていた
    • 凄そうに見せるにはビジュアルけっこう大事。自分で絵かける人とか強い
  • UI
    • 動かしたりとかしたい。ゲームジャムでそこに力をいれるのは時間的にきついかもしれないが
    • 要勉強

感想

Twitter上だけですが、みんながいろいろ作ってて、一体感みたいなのが楽しかったです。 発想力がすごい人がいっぱいいました。すごい

Unityでオブジェクトのマテリアルを変更する話

Unityで動的にマテリアルを変更したい、的なことがしたい場合

GameObject obj = xxxxxx; //適当な読み込み
Material mtl = yyyy; //適当な読み込み

obj.GetComponent<Renderer>().material = mtl;

のようにするのですが、僕は勝手に

obj.GetComponent<Renderer>().material = mtl;

obj.GetComponent<Renderer>().materials[0] = mtl;

が同じ振る舞いをするものだと思っていました。

どうも違うみたいで、前者だと意図したふるまいになるのですが、後者の場合、以下の画像のようにDefault Materialが割り当てられてしまうみたいです。

f:id:gologius:20170527183941p:plain (MeshRendererの部分です)

どう違うのかはまた調査します