- 投稿日:2020-10-06T18:29:11+09:00
UnityAndroidでExportしたprojectをステップ実行
環境1
OS : win10 pro
Unity5.6
AndroidStudio2.3.2OS : win10 pro
Unity2019
AndroidStudio4手順
・Unity C#プラグインメソッドを呼び出す。pluginは消す。
・UnityでExportする。
・AndroidStudioでそれを開く。
・AndroidStudioで、C#で呼び出したプラグインメソッドと同じIFのメソッドを作成する。確認
Java層でブレークポイント停止するのを確認した。
AndroidJavaObjectの引数は JavaクラスへのFULLPATH / TestMainがクラス名
Unity/Assert/Plugins/Android以下は空にしてEXPORTする。c#
string PluginPackageClass = "com.ore.test.TestMain"; AndroidJavaObject mImageLoader = null; public void init_lib() { m_text.text = "init_lib"; try { mImageLoader = new AndroidJavaObject(PluginPackageClass); if (mImageLoader != null) { int t_no = mImageLoader.CallStatic<int>("getNo"); m_text.text = t_no.ToString(); } else { m_text.text = "null"; } } catch(Exception e) { Debug.Log(e.ToString()); m_text.text = "ex a"; } }ExportしたJava
Android4で開いて、PluginPackageClass を作成する。これに合わせたコードを書いていき、動作確認できたら、その部分をLibにして
Unity/Assert/Plugins/Androidにもっていく。package com.ore.test; public class TestMain { static int m_no = 0; public static int getNo(){ if ( m_no == 0) { return 44; }else{ return 22; } } public int getNo2(){ return 44; } }
- 投稿日:2020-10-06T17:29:21+09:00
unityのARFoundationでアプリ作ったのに、実機だとカメラが真っ黒になってしまう時の改善策
unityのARFoundationでARのアプリをエラーなく作ったのに、iosやAndroidで実機で立ち上げると、カメラが真っ黒で映らない!!時の改善方法をご紹介します。
改善策
- 「camera usage description」 を設定していない
Edit→project settings→Player→iosまたはAndroidを選択(実機の環境)
→camera usage descriptionの欄にCamera required for AR
というように記入してビルド
iosの場合はこれでXcodeの内のinfo.plistにPrivacy - Camera Usage Description が自動的にセットされます。
- XR Plug-in Management の Plug-in Providers を設定(私はこれで解決)
Edit→project settings→XR Plug-in Management→iosまたはAndroidを選択(実機の環境)→ARKitまたはARCoreにチェックを入れる。
XR Plug-in Managementはこちらに記載があります。
- バージョンを最新版にアップデート
Unity、ARFoundation,ios,Android,xcode,ARKit,ARCoreなどなどアップデート
ちなみXcodeのアップデートは容量と時間が必要なのでご注意を笑どこにもエラーがないのに、、
全て設定したのにカメラが動かないとなると、解決策はここら辺だと思います。
ARにおいてカメラはマストなので、しっかりと解決して実機で確認できらいいですね。
- 投稿日:2020-10-06T09:38:35+09:00
【Unity】ガチャを実装してみました【PHP】
概要
ソシャゲのガチャの一部を実装してみました。
以下のようなシンプルな仕様です。
・どのガチャも単発と10連。
・ピックアップガチャに対応。
・結果はテキストで表示。デモ画面
バックエンド側のphpのコードです。
Gacha.php<?php // 同一レアリティ内のアイテムの抽選 function get_item($item_rarity,$gacha_group_id){ // ガチャの重みの合計 $item_weight_sum = 0; // ガチャの重みの配列 $item_weight_array = array(); // ガチャのIDの配列 $item_id_array = array(); // PDOインスタンスを生成 $item_pdo = get_PDO(); // SELECT文を変数に格納 $item_select_sql = "SELECT item_weight,item_id FROM item_config WHERE item_rarity ='". $item_rarity. "' AND gacha_group_id ='". $gacha_group_id. "'"; // SQLステートメントを実行し、結果を変数に格納 $item_select_stmt = $item_pdo->query($item_select_sql); // foreach文で配列の中身を一行ずつ出力 // $rou['列名']で取り出せる foreach ($item_select_stmt as $item_row) { // データベースのフィールド名で出力 $item_weight_sum += (int)$item_row['item_weight']; $item_weight_array[] = (int)$item_row['item_weight']; $item_id_array[] = (int)$item_row['item_id']; } // 乱数生成 $random = rand(1,$item_weight_sum); $item_weight_total=0; // アイテムIDの抽選 foreach($item_weight_array as $item_key => $item_value ){ $item_weight_total += $item_value; if($random <= $item_weight_total){ $item_result = $item_id_array[$item_key]; break; } } // アイテムIDからレアリティとアイテム名を抽出 $item_sql = "SELECT item_rarity,item_name FROM item WHERE item_id ='". $item_result. "'"; $item_stmt = $item_pdo->query($item_sql); foreach($item_stmt as $item){ echo 'レアリティ : ' . $item['item_rarity'] . ' '; echo 'アイテム名 : ' . $item['item_name']; echo "\n"; } } // レアリティの抽選 function get_rarity($gacha_group_id){ try{ // ガチャの重みの合計 $gacha_weight_sum = 0; // ガチャの重みの配列 $gacha_weight_array = array(); // ガチャのレアリティの配列 $gacha_rarity_array = array(); // ガチャグループを条件に抽出 $dbh = get_PDO(); $sql = "SELECT gacha_weight,gacha_rarity FROM rarity_config WHERE gacha_group_id ='". $gacha_group_id. "'"; $stmt = $dbh->query($sql); // ガチャグループで条件を絞ってガチャの重みを合計する foreach ($stmt as $row) { // データベースのフィールド名で出力 $sum += (int)$row['gacha_weight']; $gacha_weight_array[] = (int)$row['gacha_weight']; $gacha_rarity_array[] = (int)$row['gacha_rarity']; } // 乱数生成 $random = rand(1,$sum); // ガチャの重みのトータル(順次加算) $gacha_weight_total=0; // 抽選ロジック(乱数を用いて、範囲内だった重みを探す) foreach($gacha_weight_array as $key => $value ){ $gacha_weight_total += $value; if($random <= $gacha_weight_total){ // 範囲内だった重み $rarity_result = $gacha_rarity_array[$key]; break; } } // アイテムの抽選 get_item($rarity_result,$gacha_group_id); // エラー(例外)が発生した時の処理を記述 }catch (PDOException $e) { // エラーメッセージを表示させる echo 'データベースにアクセスできません!' . $e->getMessage(); // 強制終了 exit; } } // PDOインスタンス生成 function get_PDO(){ return new PDO( 'mysql:host=mysql1.php.starfree.ne.jp;dbname=opnvtw_stdb;charset=utf8', 'opnvtw_lantitor', '1211stst', [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, ] ); } // 最初に呼ばれる関数 function get_gacha(){ // tryにPDOの処理を記述 try { $gacha_id = $_REQUEST['gacha_id']; $pdo = get_PDO(); $stmt = $pdo-> prepare("SELECT * FROM gacha WHERE gacha_id = ?"); $stmt->bindValue(1,$gacha_id,PDO::PARAM_STR); $stmt->execute(); // gachaテーブルのgacha_times分ガチャを回す。 foreach ($stmt as $row) { for($i = 1; $i <= (int)$row['gacha_times']; $i++){ // レアリティの抽選からして、その後にアイテムの抽選をする get_rarity($row['gacha_group_id']); } } // エラー(例外)が発生した時の処理を記述 } catch (PDOException $e) { // エラーメッセージを表示させる echo 'データベースにアクセスできません!' . $e->getMessage(); // 強制終了 exit; } } get_gacha(); ?>開発環境
MacOS Catalina 10.15.5
クライアントはC#+Unity 2019.2.12f1
バックエンドはPHP
レンタルサーバーStarSeverFreeのフリー PHP+MySQLプラン
今回はレンタルサーバーで実装してますが、ローカルで確認したいならXamppを使います。バックエンド
抽選ロジック
抽選ロジックは、重み付きランダムアルゴリズムを用いています。
例の図は☆5が5%、☆4が10%、☆3が85%の確率です。
探索範囲はそれぞれ、☆5が1~5、☆4が6~15、☆3が16~100になります。
1~100の間のランダムで値を出し、出た値が60なら16~100の間なので、抽選結果は☆3になります。探索には累積和を使っています。
このロジックを用いて、レア度の抽選→同一レアリティ内のアイテムの抽選を行っています。GachaLogic.php// ガチャの重みの配列 $gacha_weight_array = array(5,10,85); // ガチャのレア度の配列 $gacha_rarity_array = array(5,4,3); // 1~100の間で乱数を生成 $random = rand(1,100); // ガチャの重みのトータル(順次加算) $gacha_weight_total=0; // 乱数の範囲を探す foreach($gacha_weight_array as $key => $value ){ $gacha_weight_total += $value; // 範囲内の数値 if($random <= $gacha_weight_total){ // レア度の配列からレア度を取り出す $result = $gacha_rarity_array[$key]; break; } } echo $result;マスタデータ・DB
2種類のガチャ(普通のガチャの単発と10連、ピックアップガチャの単発と10連)のデータです。
今回は、ピックアップガチャの10連が押された場合を例に全体の流れを説明したいと思います。
ガチャテーブルは、ガチャの詳細が格納さているテーブルです。
ピックアップガチャが押された場合、gacha_idのpickup_sort_10がサーバ側(PHP)に渡されます。
gacha_idはガチャを特定するためのもので、一意です。
gacha_timesが10は、10回ガチャを回すことを表しているので、抽選は10回行われます。
gacha_group_idは、ガチャの種類を特定することができます。
単発と10連では、回数やコストは違いますが、種類は同じです。
そのため、pickup-sort_1とpickup-sort_10のgacha_group_idは両方ともBです。ガチャテーブル
gacha_id gacha_group_id gacha_name gacha_cost gacha_times normal_1 A test_1 10 1 normal_10 A test_10 100 10 pickup_sort_1 B test_pickup_sort_1 10 1 pickup_sort_10 B test_pickup_sort_1 100 10
レアリティ設定テーブルは、gacha_group_idごとの重みを設定しているテーブルです。
ピックアップガチャのgacha_group_idであるBのgacha_weightを用いて、抽選します。
87%の確率で☆3、10%の確率で☆4、3%の確率で☆5が出る設定になっています。
gacha_weightの合計が1000であれば0.1%きざみ、100であれば1%きざみにすることができます。
ここの抽選で出たgacha_rarityを用いて、次にアイテムの抽選を行います。レアリティ設定テーブル
gacha_group_id gacha_rarity gacha_weight A 3 870 A 4 100 A 5 30 B 3 870 B 4 100 B 5 30
アイテム設定テーブルは、gacha_group_idとitem_rarityごとの重みを設定しているテーブルです。
gacha_group_idのBと、先ほど抽選したレアリティ(gacha_rarity)を用いて、抽選を行います。
テーブルにデータを挿入するのに手間がかかりますが、一つ一つ設定できるようにすることで、コードの変更をせずにピックアップを実装することができます。
例えば、gacha_group_idがBで、item_idが4001や5001は、同一レアリティ内でも、抽選が当たりやすくしています。アイテム設定テーブル
gacha_group_id item_id item_rarity item_weight A 3001 3 100 A 3002 3 100 A 3003 3 100 A 3004 3 100 A 3005 3 100 A 3006 3 100 A 3007 3 100 A 3008 3 100 A 3009 3 100 A 3010 3 100 A 4001 4 500 A 4002 4 125 A 4003 4 125 A 4004 4 125 A 4005 4 125 A 5001 5 333 A 5002 5 333 A 5003 5 334 B 3001 3 100 B 3002 3 100 B 3003 3 100 B 3004 3 100 B 3005 3 100 B 3006 3 100 B 3007 3 100 B 3008 3 100 B 3009 3 100 B 3010 3 100 B 4001 4 500 B 4002 4 125 B 4003 4 125 B 4004 4 125 B 4005 4 125 B 5001 5 500 B 5002 5 250 B 5003 5 250
アイテムテーブルは、アイテムの詳細が格納されているテーブルです。
抽選で出たitem_idを用いて、名前(item_name)やアイテムの種類(item_type)を表示することができます。アイテムテーブル
item_id item_rarity item_name item_type 3001 3 バブルソート 1 3002 3 ヒープソート 1 3003 3 線形探索 2 3004 3 レイトレーシング 3 3005 3 ユークリッドの互除法 3 3006 3 バケットソート 1 3007 3 シェルソート 1 3008 3 挿入ソート 1 3009 3 選択ソート 1 3010 3 シェーカーソート 1 4001 4 マージソート 1 4002 4 二分探索 2 4003 4 ダイクストラ法 3 4004 4 ベルマンフォード法 3 4005 4 ワーシャルフロイド法 3 5001 5 クイックソート 1 5002 5 幅優先探索 2 5003 5 深さ優先探索 2 以上がバックエンド側の実装になっています。
クライアント
クライアント側はUnity,C#で書いてます。
UIアーキテクチャは簡易的なMV(R)Pで実装しています。
以前にMV(R)Pで実装した際のお話をQiitaに投稿しましたので、共有させて頂きます。
【Unity】アウトゲームでの設計でMV(R)Pパターンを採用しました【設計】
また、今回はバックエンドの実装や考えを中心に行ったので、クライアント側の実装について説明は、省かさせてもらいます。最後に
実際ガチャを実装するには、もっと細かいテーブル設定やロジックが必要になると思います。
他にもいくつかQiitaで記事を投稿しているのでよければ見てください。
- 投稿日:2020-10-06T00:01:26+09:00
ObjectをInstantiateするときに親Objectを指定する
ObjectをInstantiateするときに親Objectを指定することで、親オブジェクトにつけたアニメーションと同じ動きを、新たに生成した子Objectにもつけることができます。
第四引数に親オブジェクトを指定することで、新たに生成するオブジェクトを子オブジェクトとして生成できます。
Instantiate(生成したいオブジェクト, transform, rote,親オブジェクト);
<注意>
親オブジェクトを宣言するときは
public GameObject 親オブジェクト; ではなく
public Transform 親オブジェクト; になります。




