Unity3Dでゲームを開発した経験

私は自分が経験豊富なプログラマーであり、さらに真面目なゲーム開発者だとは考えていません。 私はプログラミングを楽しむ人であり、少しできることがあります。 この記事は、教育資料または指導と呼ばれることを主張していません。



注目を集めるスクリーンショット:

画像画像



問題の道徳的側面


ゲーム開発、モデリング、プログラミングに関する真剣な知識がなくても、これを行う価値はありますか? 私からの質問への答えは続きません、誰もが自分のものを持っています。 自信を持って私は確かに言うことができます-私はそれを後悔しませんでした。 熊手に地図を描くために、私が遭遇したボトルネックを簡潔かつ明確に特定して説明しようとします。



Unity3d


Unity3dは最近、無料でその可能性を最大限に活用できるようになりました。 私は長い間、いくつかのエンジンを駆使しましたが、c#が決定的な利点であることがわかりました。 さらに、Unity3dにはユーザーインターフェイスを構築する非常に便利な方法があります。 Luaを恐れていない人のために、ビジュアルプログラミングを軽視しない場合は、Project Anarchy、またはUnreal Engine 4にもアドバイスできます。 Unity3Dはモバイル開発に最適であるという印象を受けました。 残念ながら、Unity3Dはロシア語圏のコミュニティが弱く、しばしば公式の品質保証に登らなければなりません。



ゲームアーキテクチャ


私は既存のパターンを適用する試みをしましたが、最終的にはすべて「今のところ、ここに置いてください」になりました。 Unityには、どのタイプにも関連付けるのが難しい多くのコンポーネントがあります。 ほとんどの場合、この理由は私の経験不足ですが、結局のところ、 BotSpawnerなどのスクリプトは 、避難所なしでScriptsフォルダーのルートに留まりました。



Unityとデータベースへの保存


組み込みのPlayerPrefssqliteを使用しました。 Sqliteは、無料バージョンですぐに使用できるようになりました。 私にとって、sqlテーブルは取引中に商品のデータを保存するのに便利でした。 テーブルを管理するための最も便利なツールはsqlitebrowserで 、競合他社試したに停止しまし



PlayerPrefsでの書き込みと読み取りは、次のようなものに要約されます。

public class DB : MonoBehaviour { public int currentShipBodyState { get { return PlayerPrefs.GetInt("currentShipBodyState"); } set { PlayerPrefs.SetInt("currentShipBodyState", value); } } }
      
      





エレガントな読み書きが続きます:

 db.currentShipBodyState = 100; int shbs = db.currentShipBodyState;
      
      







Sqliteには素晴らしいジェスチャーが必要でした。 以下は、Unity3dバージョン5でSqliteを使用する例です。

エディターでSqliteを使用するには、 StreamingAssetsディレクトリを作成し、そこにデータベースファイルを配置するだけです。 Androidデバイスでデータベースを操作するには、データベースファイルをApplication.persistentDataPathに配置する必要があります 。 公式ドキュメントでは、プログラムの更新時に上書きされないパブリックディレクトリとして説明しています。 プラグインプラグイン\ Androidディレクトリも作成する必要があります。 最初にPlugins \ Androidの sqlite3.dllおよびSystem.Data.dllにlibsqlite3.soを配置します。



データベースに接続するためのユニバーサルカロコード:

 public IDbConnection connector() { //      if (Application.platform != RuntimePlatform.Android) { //database.Open(Application.dataPath + "/StreamingAssets/db.sqlite"); dbconn = (IDbConnection)new SqliteConnection("URI=file:" + Application.dataPath + "/StreamingAssets/db.sqlite"); dbconn.Open(); //Open connection to the database. } // android else { //    string filepath = Application.persistentDataPath + "/" + "db.sqlite"; //       ,    if (!File.Exists(filepath)) { WWW loadDB = new WWW("jar:file://" + Application.dataPath + "!/assets/" + "db.sqlite"); while (!loadDB.isDone) { } File.WriteAllBytes(filepath, loadDB.bytes); } dbconn = (IDbConnection)new SqliteConnection("URI=file:" + Application.persistentDataPath + "/db.sqlite"); dbconn.Open(); //Open connection to the database. } return dbconn; }
      
      







データベースクエリ。これらは通常のSQLクエリです。

 public List<string> getItemInfoFromIslandByItemName(string item) { dbconn = connector(); dbcmd = dbconn.CreateCommand(); string sqlQuery = "SELECT island_resources.amount, island_resources.weight, island_resources.title, island_resources.price, island_resources.sell_price,ship_resources.amount FROM island_resources INNER JOIN ship_resources ON island_resources.title=ship_resources.title WHERE island_resources.title='" + item + "' AND island_resources.island_id=" + zones_filter(current_zone_name) + " "; dbcmd.CommandText = sqlQuery; reader = dbcmd.ExecuteReader(); System.Object[] values = new System.Object[reader.FieldCount]; int fieldCount = reader.GetValues(values); List<string> list = new List<string>(); for (int i = 0; i < fieldCount; i++) { list.Add( values[i].ToString() ); } clean(); return list; }
      
      







モデリング、風景、水


ビデオレッスンによると、彼は外出先でモデリングを学びました。 船(2隻の船が利用可能)は私の労働の成果です。 テクスチャリングするのがより困難であることが判明し、モデルでは30分しかかかりませんでした。

予想外の問題であることが判明しました。 高いドローコール(dc)のためにモバイルデバイスに適さない組み込みの地形作成システム。 私のゲームでは、大きな地図と多くの島々。 私は質の高い景観を得るために多くの努力をしなければなりませんでした。 レリーフを作成するために、 GeoControlにアドバイスして、 そこからUnityに高さマップをインポートし、特別なプラグインを使用してメッシュに転送することができます。 結果のメッシュは3Dエディターで最適化する必要があり、Mayaを使用します。 その結果、DCの量は100を超えません。私は膨大な数の水資産を試しましたが、標準的なwater4水を選択しました。



AI


ボットを制御するために検索パスを使用しませんでした。 私は、船舶のナビゲーションシステムからの障害物と反応の検出に関する「インテリジェンス」を構築することにしました。 ボットの船を3方向の光線で射撃します。障害物が光線の1つで検出されると、コマンド「ステアリングホイール」が送信されます。 主人公の船が検出されると(最小距離に近づくと)、ボットは追跡目標を受け取り、ショットに都合の良い位置に立ちます。 主人公が検出されると、側線は発射に関与するスクリプトにコマンドを送信します。 近くに障害物がない場合、ボットは自分たちの生活を送り、島から島への「海のルート」に沿って移動します。



Unity3dのゲーム内購入


選択はOpenIABにかかった 。 難しいタスクに対する信じられないほどシンプルなソリューション。

1. Google Play販売コンテンツセクションで、アイテムを作成します。

2.いくつかの簡単な操作を実行するスクリプトを作成します。

コード
  private void Awake() { //     OpenIABEventManager.billingSupportedEvent += OnBillingSupported; OpenIABEventManager.billingNotSupportedEvent += OnBillingNotSupported; OpenIABEventManager.queryInventorySucceededEvent += OnQueryInventorySucceeded; OpenIABEventManager.queryInventoryFailedEvent += OnQueryInventoryFailed; OpenIABEventManager.purchaseSucceededEvent += OnPurchaseSucceded; OpenIABEventManager.purchaseFailedEvent += OnPurchaseFailed; OpenIABEventManager.consumePurchaseSucceededEvent += OnConsumePurchaseSucceeded; OpenIABEventManager.consumePurchaseFailedEvent += OnConsumePurchaseFailed; OpenIABEventManager.transactionRestoredEvent += OnTransactionRestored; OpenIABEventManager.restoreSucceededEvent += OnRestoreSucceeded; OpenIABEventManager.restoreFailedEvent += OnRestoreFailed; } //    void Start () { OpenIAB.mapSku(SKU_COINS_2000, OpenIAB_Android.STORE_GOOGLE, "id   "); OpenIAB.mapSku(SKU_COINS_5000, OpenIAB_Android.STORE_GOOGLE, "id   "); var public_key = "      api"; var options = new OnePF.Options(); options.storeKeys.Add(OpenIAB_Android.STORE_GOOGLE, public_key); options.verifyMode = OptionsVerifyMode.VERIFY_ONLY_KNOWN; OpenIAB.init(options); }
      
      







3. 便利なOpenIAB.purchaseProduct(作成した製品のID)を呼び出します



購入が成功すると、 OnPurchaseSuccededメソッドが呼び出され、これにより購入操作が正常に完了したことを確認しました。 購入が成功した場合、商品を消費する必要があります。そうでなければ、繰り返し購入することはできません。

 private void OnPurchaseSucceded(Purchase purchase) { OpenIAB.consumeProduct(purchase); }
      
      





使用が成功すると、 OnConsumePurchaseSucceededここで呼び出されます 。ここでは、プレーヤーに商品を割り当てるための記録を作成できます。



1つのオブジェクトで複数のサウンドを同時に再生する問題を解決するサウンド管理


このスクリプトを掛ける空のオブジェクトを作成します。

 public class AudioManager : MonoBehaviour { public Transform target; //      "" //  public AudioClip cannon_fire_sound_AC; //   private AudioSource cannon_fire_sound_AS; //   public static bool is_cannon_fire; void Update () { this.transform.position = target.transform.position; if (is_cannon_fire) { cannon_fire_sound_AS = AddAudio(cannon_fire_sound_AC, false, false, 0.5f); cannon_fire_sound_AS.Play(); is_cannon_fire = false; } } AudioSource AddAudio(AudioClip clip, bool loop, bool playAwake, float vol) { var newAudio = gameObject.AddComponent<AudioSource>(); newAudio.clip = clip; newAudio.loop = loop; newAudio.playOnAwake = playAwake; newAudio.volume = vol; newAudio.minDistance = 10; return newAudio; } }
      
      





次に、正しい場所からAudioManager.is_cannon_fire = true; //変数の最適な名前ではありませんを呼び出します



アドモブ


Admobの複雑さを理解しようとしています。 テストのためにアカウントに500rを補充し、1日100rの制限を設定してプロモーションを開始しました。 数時間後、私はこれを賞賛します:



正直なところ、私はそのような金額がどこから来たのかわかりませんでした。ほとんどの場合、詳細に注意を払っていません。 それでも、これがAdmobから請求された請求書ではないことを願っています。



ゲームはパイレーツとトレーダーと呼ばれ、Google Playが利用可能です。 当然、改善と開発が必要です。 希望する人は触ることができ、執筆時点での検索では29位です。










All Articles