UnityでRPGを作ってみる

UnityでRPGを作ってみる

AddressableAssets

AddressableAssetsのソースの書き方

using UnityEngine.AddressableAssets;
・・・
string pass = "Assets/_Prefabs/Stage/" + ts_data.GetStageFileName(int.Parse(data.name)) + ".prefab";
var op = Addressables.LoadAssetAsync<GameObject>(pass);
var prefab = op.WaitForCompletion();
Instantiate(op.Result).transform.SetParent(Stage.transform);
Addressables.Release(op);

文字列操作編

16進数文字列を10進数の整数型に変換する

変換したい文字をstrとすると、
int num= Convert.ToInt32(str, 16);

先頭からn文字目をm文字取得し、int型に変換する

例)
int ID = int.Parse(str.Substring(, ));

string[] floor_data = field_mng.dp.stage_mons[field_mng.stage_id].Split("/");
int enemy_index = int.Parse(floor_data[floor + 1].Substring(i, 1));

test

test

※執筆&調査中※Unityの重い処理の原因を特定したい

f:id:allmoreidea:20201107231117j:plain
60fpsは維持したい、けど何が原因で重いかわからない・・・・
なのでその原因を探します。

プロファイラを起動する

Window→Analyisis→Profiler
またはCtrl+F7


f:id:allmoreidea:20201107231409j:plain

超ド基本のAnimation

アニメーションの作成

  1. Projectビューにて右クリック→Create→Animationで「***.anim」を作成
  2. 作成した「***.anim」を該当のオブジェクトにAddする

f:id:allmoreidea:20200830120109j:plain


最初の状態(ステート)を変更する

Animator」ウィンドウにて、該当のステートを右クリック→Set as Layer Default State

Tips:
最初は静止させておいて、何かのきっかけでアニメーションするような場合は、アニメーションを全く設定していない状態を初期状態とすれば良い


スクリプトでステートを変更する

[SerializeField] Animator lid_anim;

    public void Open()
    {
        open = true;

        lid_anim.Play("open");
    }

アニメーションを最初から(指定時間から)再生する

第3引数に再生させたい時間を入力する。最初からの場合は0.0fですね。
※第2引数はレイヤーらしい(現時点では良く分からん)

this.GetComponent<Animator>().Play("WindowOpen", 0, 0.0f);

アニメーションした最後の状態をそのまま維持させたい

遷移先を無くせばOK
※ほかに方法があるかもしれないけど、これでうまくっているので取り敢えずこれで。
f:id:allmoreidea:20200831223326j:plain

ScriptableObjectを使う

アイテムのデータを登録していきます。
RPGツクールみたいですね。

1.ScriptableObject用のソースファイルを作成する

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

[CreateAssetMenu(menuName = "ScriptableObject/Create ItemData")]
public class ItemData : ScriptableObject
{
    public string Name;
    public Sprite icon;
    public string help;

}

※Sprite を使うために「using UnityEngine.UI;」してるのであって、使わないならこのusingは不要


2.データを作る

下のProject画面で右クリックして、Create→ScriptableObject→1.で作った名前

f:id:allmoreidea:20200823105616j:plain

長押しできるボタンを作る

やりたいこと

スマホRPGでよくある、スキルボタンを押したらそれで攻撃し、長押ししたらヘルプウィンドウを呼び出すとかああいうのを作ります。

やり方

ボタン化したいImageにEvent Triggerをアタッチメントし、Pointer Down、Pointer Upを作る
f:id:allmoreidea:20200510214458j:plain


押しっぱなし(Pointer Down)のときはフラグをONして、Update関数内でフラグがONした時間をカウント。
カウントが閾値を超えた時に処理を書けば、長押し処理の出来上がり。

// ボタン長押し用の変数定義
    const float POINTER_DOWN_TIME = 0.3f;
    bool pointer_down = false;
    float PointerDownTimer = 0;

void Update () {

       // ボタン長押し用処理
        if (pointer_down == true)
        {
            PointerDownTimer += Time.deltaTime;

            // 長押しされた時の処理
            if (PointerDownTimer > POINTER_DOWN_TIME)
            {

            }
        }
        else
        {
            // 長押しされなかった時の処理
            if ((0< PointerDownTimer) && (PointerDownTimer < POINTER_DOWN_TIME)){

            }
            PointerDownTimer = 0;
        }
}

public void PointerDown()
    {
        pointer_down = true;
    }

    public void PointerUp()
    {
        pointer_down = false;
    }

POINTER_DOWN_TIMEに適当な値を突っ込んでください。
自分は0.3秒(0.3f)にしました。この辺は各自調整するのがよろしいかと。

2D Object - Sprtiteにボタン機能を付ける

こういう3D空間に配置したSprtiteに対してButton機能を付けたいが、反応してくれない。

 

■方法

  1. Event Triggerコンポーネントを追加する
    1. Pointer Downを選び、ボタンを押したときにコールされる関数を指定する(この辺はボタンと一緒)
  2. Box Collider 2Dコンポーネントを追加する

    Unityは賢いので、勝手にSpriteの大きさに合わせたサイズにほせいしてくれる。ただし、動的にSpriteを切り替える場合はスクリプトで適当なサイズに変換してやる必要がある

    1. どうも、1px=0.01っぽいので、例えば64x64のSpriteならColliderのSizeを0.64x0.64にすればOK

 

 

Unityでスクロールできるウィンドウを作る

RPGのメニュー画面でモンスターを選択するような画面を作りたいです。

 

分かりづらいですが、下記のようにずらっとモンスターのアイコンが並んでて、それをスクロールできるようなエリアを作るのが目的です。

※絵が下手なのは勘弁してください

 

この画面の左の方をずずっと下にスワイプすると・・・

f:id:allmoreidea:20200510190433j:plain

 

こんな感じで移動するようにさせたい
f:id:allmoreidea:20200510190421j:plain

 

方法:UIのScroll Viewを使用する

f:id:allmoreidea:20200510190654j:plain

 

Scroll View

  •  好きな位置に持っていき、サイズを好きに変えます。これが実際に表示される領域となります。
  • 背景とかもここで設定します。デフォルトでは白っぽくなってるので色を変える場合もここです。
  • Movement type:端までスクロールした時の挙動を設定します。デフォルトでは端まで持ってくとびよんと伸びる感じになりますが、きっちり止まってほしいので「Clamped」としました。
  • Horizontal、Vertical:スクロールする方向を決める。横方向にスクロールする必要はないので、「Horizontal」のチェックは外します。
  • Interia - Deceleration Rate:マウスホイールのスピードっぽいです。他に何か使うのかも。

 

Viewport

しらん!

Content

  •  重要!ここに描画したいものを放り込みます。上の画像の場合、モンスターのサムネイルをこの中に入れるようにしています。
  • 名前は変更可です。Prefab化したものをこの中に放り込むことになると思うので、一意に決まる名前を入れておいた方がよいでしょう。

Scrollbar Horizontal

Scrollbar Vertical

「Scroll View」の

スクロールできる範囲は「Scroll View - Viewport - Content」で変えます。一般的に「Scroll View」より大きくすべきでしょう(じゃないと意味がない)

 

 

Particle SystemをCanvas(UI)の前面に表示する

 
 

最終的には没にしましたが、Canvasの前にParticle Systemを表示させたいと思いました。

 

普通はこうなる

 

これをこう表示させたい

 

やり方は簡単で、CanvasのRender ModeをScreen Space - Cameraに変更するだけ!

う~ん 簡単ですね

 

 

 

 

参考:

https://qiita.com/r-ngtm/items/24731da4b54e2932f6d0

 

 

トラブルシューティング(コンパイルエラー編)

NullReferenceException: Object reference not set to an instance of an object

  1. AクラスからBオブジェクトにアタッチされたCクラスの変数を呼ぼうとしてるのに、アタッチを忘れてる

123456

123456
123456
123456

初級講座



未分類

Prefabで生成したオブジェクトを他のオブジェクトの子にする

// 移動させたい親オブジェクトをUnity側のInspectorから予め設定しておく
[SerializeField] GameObject cnv; 
  (中略)
room[y, x] = Instantiate((GameObject)Resources.Load("Prefabs/Dungeon/Room")).GetComponent<CRoom>();
room[y, x].transform.SetParent(cnv.transform);

Rayを使ってオブジェクトを取得

 [SerializeField] Camera MainCamera;
  (中略)
Ray ray = MainCamera.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
 if (Physics.Raycast(ray, out hit, 100.0f))
 {
      Debug.Log(hit.collider.gameObject.name);
  }

ファイル操作

csvファイルを読み込む

前提:
csvファイルは ****\Assets\Resources\csv\ に置く。
csvフォルダに置くのは任意。分かりやすいのでこうしてる。Resourcesフォルダに置くのはMUST。

 // CSVの中身を入れるリスト
using System.IO; // StringReader を使用するための宣言
(中略)
List<string[]> FloorData = new List<string[]>();
(中略)
 TextAsset csvFile = Resources.Load("csv/map/" + "001") as TextAsset; /* Resouces/CSV下のCSV読み込み */
StringReader reader = new StringReader(csvFile.text);
 while (reader.Peek() > -1)
{
    string line = reader.ReadLine();
    FloorData.Add(line.Split(',')); // リストに入れる
 }

●Unity側でcsvが読めない(範囲外アクセス)と言われるときは
該当のcsvファイルをUnityの下画面をクリックすると、空っぽに見えてるはず
そんなときは、csv文字コードUTF-8にする