UnityでRPGを作ってみる

UnityでRPGを作ってみる

Unityで入力補完が利かなくなった時の対処法

Visual Studio使いです
再起動すれば勝手に治るだろうと思ったら治らなかったので、調べました。メモ。

エクスプローラーからVisual Studioの「ソリューションエクスプローラー」を開き、ドラッグ&ドロップ。
どうやら、Unity上で格納場所を変更してしまったときに参照が切れたようです。

f:id:allmoreidea:20181223103312p:plain

UnityRemoteとApplication.isEditorの罠

罠、というか自分が勝手に嵌っただけですが・・・

スマホのタッチと、UnityでのEditorからの双方からデバッグできるようにするためにこうするといいよ、というサイト様を参考にこう作ったのですが、スマホから全く動かない。

 if (Application.isEditor)
        {
            if (Input.GetMouseButtonDown(0) || Input.GetMouseButton(0))
            {
                tap_pos = Input.mousePosition;
                ret = TapDataChk(tap_pos, 0, 1);
            }
            
        }
        else
        {
            // 実機で実行中
            for (int i = 0; i < Input.touchCount; i++)
            {
                // タッチ情報の取得
                Touch touch = Input.GetTouch(i);
                Debug.Log("i:" + i+ "   pos:" + touch.position);

                ret = TapDataChk(touch.position, 0, 1);

                if(ret != -1)
                {
                    i = 99999;
                }
            }
        }

で、Debug.Logでよくよく見てみると、エディタ用の処理が動いてることが判明。
まさか、エディタから起動しているからエディタ用の処理が動くのか?
スマホ用の処理をデバッグしたければエディタを落としてインストールしないといけないのか?
そんな馬鹿なことがあるのか?

と思っていたら、やはり自分がバカなだけでした。

Application.isEditor はエディタが起動しているか否かを判定しているので、それを消してやり、エディタ(マウス)用とスマホ用の処理を並列させてやればいいだけでした。

//エディタ用の判定
        if (Input.GetMouseButtonDown(0) || Input.GetMouseButton(0))
        {
            tap_pos = Input.mousePosition;
            ret = TapDataChk(tap_pos, 0, 1);
        }

        // 実機用の判定(エディタ用の判定結果が-1のときのみ判定する)
        if (ret == -1)
        {
            for (int i = 0; i < Input.touchCount; i++)
            {
                // タッチ情報の取得
                Touch touch = Input.GetTouch(i);
                Debug.Log("i:" + i + "   pos:" + touch.position);

                ret = TapDataChk(touch.position, 0, 1);

                if (ret != -1)
                {
                    i = 99999;
                }
            }
        }

解決。
処理負荷的には実機用の判定を上に書いたほうが良いのかな?
そもそもリリース時にはデバッグ処理は消した方がいいのかな?

#リリースすることはないだろうからあんま関係なさそう

Prefubで作ったオブジェクトを別の親オブジェクトの子にする

こういうことをやりたい
が、UIで作った画像を20個も手で作成するのはめんどくさいので、何とかならないか調べました。

f:id:allmoreidea:20180728115042j:plain

■概要

  1. Resources.Loadでprefubを読み込む
  2. Instantiateでprefubを生成する
  3. 後で操作したいので、それぞれGameObjectにする ※GetComponentで最初から作成したclassにしてしまった方がいい気もする
  4. SetParentで親を指定する
GameObject[] actorCircle = new GameObject[20];

        for (int i = 0; i < actorCircle.Length; i++) {
            actorCircle[i] = Instantiate((GameObject)Resources.Load("Prefabs/ActorCircle"), new Vector3(835 - i * 45, 450, 0), Quaternion.identity); // effectの読み込み&作成
            actorCircle[i].transform.SetParent(cnv.transform); // UIはCanvusの子でないといけないので、予めGameobjectを取得しておいたcnvを親に設定する
            actorCircle[i].GetComponent<RectTransform>().localScale = new Vector3(0.9f, 0.9f, 0.9f); // SetParentしたことでScaleが変わってしまうので、再設定する
        }

■不明点
UI全般そうだけど、設定したpositionがどうなってるのか全然わからない
最初canvusに対する相対位置かと思ったけど、そうでもないみたい
Rect transformのpositionをいじれば表示位置が変わるのはわかったけれど、Inspectorで見ても値は据え置きで何がどう変わってるのかさっぱり。
new Vector3(835 - i * 45, 450, 0),  は値を少しずつ変えて力業で導き出しました。

【Unity】フォントを変える

Assetストアにこれってものがないって思ってたら、TrueType(.ttf) OpenType(.otf)が使えるそうなので、適当にこれをインポートしてあげればいい。

docs.unity3d.com


規約的にOKか知らないけど、マイコンピュータ以下”.ttf”で検索かけると大量に引っかかるのでそれをUnityに読み込ませれば、PCに入ってる奴なら何でも使えそう。

f:id:allmoreidea:20180725005711j:plain

規約的にはダメな気がするけど、まぁ、どうせ公開しないだろうしそれならあんま気にしなくていいでしょ。

【Unity】スクリプトから画像を分割して読み込む

アイコンとかは1つの画像にして分割するといいと思います

下準備

  1. 読み込みたい画像をResources以下に置く(自分はさらにImgフォルダを作ってその下に格納)
  2. Texture TypeをSprtiteに変更
  3. 画像を分割したい場合は、Sprite modeをMultipleに変更f:id:allmoreidea:20180715140418j:plain
  4. ちょい下にある「Sprite Editor」を押下
  5. 下図のように任意のサイズ(今回は32x32)でスライスする

f:id:allmoreidea:20180715140710j:plain

C#

Sprite[] icon_skill; // 分割した画像を格納する配列を定義

icon_skill = Resources.LoadAll<Sprite>("Img/skill_icon"); // LoadAllで分割された画像を一斉に読み込む
SkillButton[0].GetComponent<Image>().sprite = icon_skill[1]; // 任意のGameObjectに張り付ける====



注意

何度やってもうまく読み込めなくてうーんと唸ったところ。
当初、

a = Resources.LoadAll("Img/skill_icon") as Sprite[];

とas~を後ろにつけていたが何度読み込んでも真っ白。デバッグで見たけどNullってるぽかった。

a = Resources.LoadAll<Sprite>("Img/skill_icon");

と、を前に持ってくることで無事解決出来た。
理由はわからないし、as~としてるソースもあったのでこれで良いのかと思ってたけれど、Unityのバージョンとか関係あるのかな。
とりあえずVer.5.6.3p2ではこれでうまくできたので備忘録として。

別オブジェクトの関数にアクセスする方法

例)

「BattleManager」オブジェクトの「BattleManager」クラスにある「SetSelectCommand」に自身のpublic変数「id」を渡す方法

public class ButtonSkill : MonoBehaviour {

    GameObject obj;
    BattleManager mng;
    public int id;

    // Use this for initialization
    void Start () {

        obj = GameObject.Find("BattleManager");  // 作ったGameObjectを探す
        mng = obj.GetComponent<BattleManager>(); // 作ったclassを格納する

    }
 
 // Update is called once per frame
 void Update () {
  
 }

    public void OnClick()
    {
        mng.SetSelectCommand(id);
    }
}

 ※UIのボタンを押したらモードが切り替わるようなものを想定。別にOnClickの中にある必要はない

 

個別記事にするまでもないトラブルシューティング

・unityの編集に画面が入力できなくなった
 ⇒どこでもいいのでコンテキストメニューを出せばOK
 参考:http://sat-box.hatenablog.jp/entry/2018/03/19/183458

・なんかCanvasのTextがぼやけるんだけど・・・
 f:id:allmoreidea:20180630142049j:plain
 ⇒文字サイズの調整をScaleでやってるのがダメ。TextのScaleを全部1.0にして、文字の大きさは「Font Size」で調整すること。
#考えてみれば、当たり前っちゃ当たり前ね・・・・

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

エラー内容

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

書いたコード

 

    public class BattleCharacter
    {

        BattleCharacter()
        {
            obj = null;
            lev = 0;
        }
    }

    BattleCharacter chara = new BattleCharacter[16];

    // Use this for initialization
    void Start () {

        chara[0].lev = 15;

  (以下略)

 ポイント

 

  • 原因は初期化してないclass配列に対してアクセスしようとしてるから(chara[0].lev = 15; のところ)
  • class配列はコンストラクタでの初期化は明示的に書いてやらないといけない(らしい)
  • そもそも構文が間違ってる

解決策

    public class BattleCharacter
    {
        public GameObject obj;
        public int lev, hp, atk, def, spd, acc, rdg, mag;
        public int exp;

        public BattleCharacter()
        {
            obj = null;
            lev = 0;
        }
    }

    BattleCharacter chara = new BattleCharacter[16];

    // Use this for initialization
    void Start () {

        chara[0] = new BattleCharacter();

        chara[0].lev = 15;

 参考:

https://qiita.com/scnsh/items/8eb80000267ac99d2bf4

 

 

”~はアクセスできない保護レベルになっています”と表示された場合の解決法

 (unityはあんま関係ないけど)C#の記法

”~はアクセスできない保護レベルになっています”と表示された場合の解決法

f:id:allmoreidea:20180630112003j:plain

int expにpublicをつければよい

結局hatenaが一番使いやすい

sskblog.amebaownd.com

Ameba owndでせこせこ使ってたけれど、根本的に使いにくい・醜い見にくい・ デザインがいまいち。SEO弱いと将来性を感じないので古巣のhatenaに戻すことにした。

人に見せるようというよりは自分のmemo的な要素が強いので、とにかく素早く手軽にかけることが第一。文章以外で時間かけたくないので。