FC2ブログ
    04 «1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.25.26.27.28.29.30.31.» 06

    ハルシオンシステムの気ままBlog

    株式会社ハルシオンシステムのメンバーが送る、UnityやらJavaやらの技術的話題から、自社開発のアプリの宣伝とかとかのブログです。ほんと気ままにいきたいと思います。更新日は毎週 月 木でっす!

     

    【ハルシオンブログ】Unity Updateの中でGetComponentをしてはいけませんよ?っていう基本の話 

    5月も終わりですね。
    5月もあっという間に終わった感じがします。
    さて横浜ゲームダンジョンに出ようかどうしようか・・・・・・坂内っす。


    ポケットガール~受け継がれし希望~よろしくお願いします。
    URL(Android):https://play.google.com/store/apps/details?id=com.halcyon.pocketgirl3
    URL(iOS):https://itunes.apple.com/jp/app/id1539553611

    PV:



    Unityでの基本的な話なんだけど、Update内でGameObject.Findをしないという話。
    よく聞きますよね。
    実際にどれくらい重くなるのか試してみました。

    [Blog20230529.cs]

    using UnityEngine;
    using UnityEngine.UI;

    public class Blog20230529 : MonoBehaviour
    {
    [SerializeField] GameObject obj;
    [SerializeField] Image imgPlate;

    int rdmCnt = 0;
    System.Diagnostics.Stopwatch stopwatch;
    bool isMeasuring;

    private void Start() {
    // 準備
    for (int i = 0; i < 1000; i++) {
    Instantiate(obj, new Vector3(Random.Range(-3f, 3f), Random.Range(-4f, 6f), 0), Quaternion.identity);
    }
    stopwatch = new System.Diagnostics.Stopwatch();
    stopwatch.Start();
    isMeasuring = true;
    }

    private void Update() {
    if (isMeasuring) {
    rdmCnt++;
    GameObject.Find("imgPlate").GetComponent<Image>().color = new Color(Random.value, Random.value, Random.value, 1f);
    //imgPlate.color = new Color(Random.value, Random.value, Random.value, 1f);
    if (rdmCnt >= 2000) {
    isMeasuring = false;
    stopwatch.Stop();
    Debug.Log((float)stopwatch.Elapsed.TotalSeconds);
    }
    }
    }
    }






    Startでは画面の負荷をあげるために、Sphereを1000個画面に適当に置いてます。

    2000回Imageの色を変えて時間を測ります。

    Updateの中の
    GameObject.Find("imgPlate").GetComponent<Image>().color = new Color(Random.value, Random.value, Random.value, 1f);

    imgPlate.color = new Color(Random.value, Random.value, Random.value, 1f);

    を切り替えて実行してみました。

    【GameObject.Find("imgPlate").GetComponent<Image>().color = new Color(Random.value, Random.value, Random.value, 1f);の場合】
    11.10498秒

    【imgPlate.color = new Color(Random.value, Random.value, Random.value, 1f);の場合】
    11.27025秒


    か・・・変わらねえ・・・・というか、GetComponentしてない方が遅い!?

    あれ??

    まぁただ、Updateで毎フレームFindで取得しにいくのはちょっと気持ち悪いのは気持ち悪いですよね…

    ちなみに処理負荷上げるために玉を10000個置いても、処理時間に差がありませんでした‥

    うちのPCだとちょっと時間の差はありませんでしたが、やめた方がいいですね!キリッ

    ということで、UpdateでGetComponentをしない方がいいよという話。全然検証になってませんが。

    では、あでゅ~!ノシ

    Category: 開発日記(Unity)

    tb 0 : cm 0   

    【ハルシオンブログ】ifでキャスト判定した時にそのままキャストした変数として使う 

    こんにちは。
    大坂です。

    ポケットガール~受け継がれし希望~よろしくお願いします。
    URL(Android):https://play.google.com/store/apps/details?id=com.halcyon.pocketgirl3
    URL(iOS):https://itunes.apple.com/jp/app/id1539553611

    PV:


    ifでis演算子を使用してキャスト判定した時って、そのままキャストした変数として使えるんですね。
    こんな感じでやってた。

    object obj = "test";
    if(obj is string) {
    Debug.Log(((string)obj).Length);
    }


    こうできます。

    object obj = "test";
    if(obj is string s) {
    Debug.Log(s.Length);
    }


    ちょっとだけ手間が省けますね。
    C#7からの機能らしいです。

    では今週も短いですがこれにてノシ

    Category: 開発日記(Unity)

    tb 0 : cm 0   

    【ハルシオンブログ】配列ってあとからでもサイズ変えれるんですね。Resizeで配列のサイズを変えよう! 

    こんにちは。坂内っす。
    5月ももう終わりそうですね。
    時が過ぎるのがとても速いです・・・


    ポケットガール~受け継がれし希望~ でてます!

    URL(Android):https://play.google.com/store/apps/details?id=com.halcyon.pocketgirl3
    URL(iOS):https://itunes.apple.com/jp/app/id1539553611

    PV:



    Unityで配列使うことって多々ありますよね。

    でも配列って大きさ決めたら増やすこととかできないから使いずらいってことあると思います。
    その分Listのほうが自由にできていいですもんね。

    でも実は配列って宣言した後でもサイズ変えれるんですよ。


    Array.Resize(ref 配列, 変更後の要素数)

    [Blog20220522.cs]

    using System;
    using UnityEngine;

    public class Blog20230522 : MonoBehaviour
    {
    void Start() {
    int[] intAry = {0, 1, 2, 4, 6, 10 };
    Debug.Log("初期設定" + intAry.Length);

    Array.Resize(ref intAry, 10);

    Debug.Log("リサイズ後" + intAry.Length);
    }
    }





    こんな感じで、初め6個のintを入れたintAryですが、Resize後にはちゃんと10個の配列になっています。

    ということで、配列のサイズを初期設定後に変える方法でした。

    あでゅ~ノシ

    Category: 開発日記(Unity)

    tb 0 : cm 0   

    【ハルシオンブログ】C#9で型名がわかっているときはnew 演算子で型名を省略できる 

    こんにちは。
    大坂です。

    ポケットガール~受け継がれし希望~よろしくお願いします。
    URL(Android):https://play.google.com/store/apps/details?id=com.halcyon.pocketgirl3
    URL(iOS):https://itunes.apple.com/jp/app/id1539553611

    PV:


    C#9で型名がわかっているときはnew 演算子で型名を省略できるんですね。
    ターゲット型の new 式というらしいです。


    // 今までの書き方
    List test_1 = new List();

    // new で型を省略できる
    List test_2 = new();

    // エラー
    var test_3 = new();

    // メソッドの戻り値も省略できる
    List TestMethod()
    {
    return new() {1, 2, 3};
    }

    「var」のところはエラーになるので、型名を明示しているときだけできますね。

    大した話ではないですが、C#9でこんな機能があるよという紹介でした。
    ではまたノシ

    Category: 開発日記(Unity)

    tb 0 : cm 0   

    【ハルシオンブログ】Unityでボタンいっぱいの画面を作ってみた。 

    こんにちは。坂内っす。

    まずはポケガ3の宣伝から。

    ポケットガール~受け継がれし希望~よろしくお願いします。
    URL(Android):https://play.google.com/store/apps/details?id=com.halcyon.pocketgirl3
    URL(iOS):https://itunes.apple.com/jp/app/id1539553611

    PV:



    Unityでこんな画面作ってみる。


    ボタンがいっぱいで作るのめんどいよね!

    ボタン1個1個にOnClick設定とか・・・・やってられませんよね。

    こんな感じで簡単に作れます。

    まずボタンのプレハブを用意。



    60x60の白Imageと、その子供にTextを用意しました。
    もちろんTMPでもなんでもOK
    Textは数字入れたときにちゃんと見えるようにサイズと位置を調整済。

    次に、ボタンを並べるところを準備します。

    GridLayoutで60x60が並ぶようにしておきました。




    あとは、こんなコードを書きます。

    [Blog20230515.cs]

    using UnityEngine;
    using UnityEngine.UI;

    public class Blog20230515 : MonoBehaviour
    {
    [SerializeField] Text lblSelectNo;
    [SerializeField] Transform trnButton;
    [SerializeField] GameObject objItem;

    const int countOfButton = 150;

    void Start()
    {
    for (int i = 0; i < countOfButton; i++) {
    GameObject obj = Instantiate(objItem, trnButton, false);
    obj.name = "btn" + i;
    Text text = obj.GetComponentInChildren<Text>();
    text.text = i.ToString();
    int no = i;
    obj.GetComponent<Button>().onClick.AddListener(() => OnClickNo(no));
    }
    }

    void OnClickNo(int i) {
    lblSelectNo.text = i.ToString();
    }
    }



    これだけ。

    1個1個ボタンを設定する必要なんてないんです!
    AddListnerで設定してあげればいいですね。

    これで作られるオブジェクトはこんな感じ。




    ちゃんとボタン押すと押されたNoが画面上部にでますね。


    ということで、ボタンいっぱいの画面の作り方でした。

    あでゅ~ノシ

    Category: 開発日記(Unity)

    tb 0 : cm 0   

    【ハルシオンブログ】Dictionaryをforeachで更新する 

    こんにちは。
    大坂です。

    ポケットガール~受け継がれし希望~よろしくお願いします。
    URL(Android):https://play.google.com/store/apps/details?id=com.halcyon.pocketgirl3
    URL(iOS):https://itunes.apple.com/jp/app/id1539553611

    PV:


    Dictionaryをforeachで更新するときのお話。
    こんな感じでやると怒られます。

    Dictionary dic = new Dictionary { { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 4 }, { 4, 5 } };
    foreach(int key in dic.Keys)
    {
    dic[key] = 0;
    }



    解決策としては、Keyでリストを作ってそれを使うとうまくいきます。

    Dictionary dic = new Dictionary { { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 4 }, { 4, 5 } };
    // dic.Keysをリストにする
    List keyList = new List(dic.Keys);
    // 作ったリストを使ってforeachを回す
    foreach (int key in keyList)
    {
    dic[key] = 0;
    }

    これで問題なく更新できます。
    そういえばこんなこともあったなぁと思ったのでメモ的なお話です。

    ではではノシ

    Category: 開発日記(Unity)

    tb 0 : cm 0   

    【ハルシオンブログ】C#でArrayListって使わなくなったなぁと思ったので、処理時間とか調べてみた 

    こんにちは!GWが終わってしまいました。皆様GWはどうお過ごしでしたでしょうか?
    ずっと家に引きこもっていました。坂内っす。

    ポケットガール~受け継がれし希望~よろしくお願いします。
    URL(Android):https://play.google.com/store/apps/details?id=com.halcyon.pocketgirl3
    URL(iOS):https://itunes.apple.com/jp/app/id1539553611

    PV:


    最近Unity(C#)でリストを扱う際には、Listをよく使っています。
    以前(15年くらい前とか?)Javaをやっていた時は、よくArrayListを使っていた。
    C#にもArrayListはあるらしいが、使うことはなくなったなぁと思ったので調べてみた。

    【ListとArrayListの違い】
     ArrayListはObjectしか格納できない。
     ListはTを格納できる。
     
     Objectをそのまま使うことはないため、ArrayListから取り出す際には必ずキャストをしないといけなくなる。
     キャストをするともちろん処理が重くなる。

    こんなコードを書いて、ArrayListとListの処理時間を確認してみた。

    [Blog20230508.cs]

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

    public class Blog20230508 : MonoBehaviour{

    public class TestA {
    public int num;
    public TestA(int i) {
    num = i;
    }
    }

    ArrayList array;
    List list;

    void Start()
    {
    var sw = new System.Diagnostics.Stopwatch();

    sw.Start();
    // ArrayList
    int intAry = 0;
    array = new ArrayList();
    for (int i = 0; i < 100000; i++) {
    array.Add(MakeTestA(i));
    }
    for (int i = 0; i < array.Count; i++) {
    TestA testA = array[i] as TestA;
    intAry += testA.num;
    }
    sw.Stop();
    Debug.Log("int : " + intAry);
    Debug.Log("ArrayList : " + sw.Elapsed.ToString());

    sw.Restart();
    // List
    int intList = 0;
    list = new List<TestA>();
    for (int i = 0; i < 100000; i++) {
    list.Add(MakeTestA(i));
    }
    for (int i = 0; i < list.Count; i++) {
    intList += list[i].num;
    }
    sw.Stop();
    Debug.Log("int : " + intList);
    Debug.Log("List : " + sw.Elapsed.ToString());

    }

    TestA MakeTestA(int i) {
    TestA testA = new TestA(i);
    return testA;
    }
    }



    それぞれTestAというクラスを10000個作りArrayListとListに突っ込む。
    それぞれ取り出して、TestAの中のNumを足しこんでいき時間を計測する。

    結果はこちら。

    int : 704982704
    ArrayList : 00:00:00.0148516
    int : 704982704
    List : 00:00:00.0184415

    あれ??
    ArrayListのほうが早くない・・・・???

    これくらいの処理だとキャストしても特に速度変わらないのかな・・・??

    TestAクラスが軽すぎるからなのか??

    TestAクラスをこんな感じにしてみたら、差が出てきました。


    public class TestA {
    public int num;
    public int num1;
    public int num2;
    public int num3;
    public int num4;
    public int num5;
    public int num6;
    public int num7;
    public string aa;
    public string ab;
    public string ac;
    public string ad;
    public string ae;
    public string af;
    public string ag;
    public string ah;
    public TestA(int i) {
    num = i;
    }
    }


    int : 704982704
    ArrayList : 00:00:00.0261743
    int : 704982704
    List : 00:00:00.0188563

    あからさまにキャストしたArrayListのほうが処理時間が増えてきました。

    Listの方は全然処理時間変わらないですね。

    結果

    軽いクラスをArrayListに突っ込むなら、特にListとの処理時間に差はないけど、クラスの中身が増えてくるとキャストに時間がかかっていくということですね。
    なので、ArrayListよりはListをそのまま使った方がいいと。

    ちょっと気になったので、ArrayListの話を掘ってみました。

    以上、あでゅ~ノシ

    Category: 開発日記(Unity)

    tb 0 : cm 0   

    【ハルシオンブログ】Unityで画像データがおおきい場合、こういう設定にすればデータ圧縮ができますよ。 

    こんにちは。坂内っす。
    もう5月になってしまいました。
    あと1か月で今年も半分!頑張っていきましょう!

    ポケットガール~受け継がれし希望~よろしくお願いします。
    URL(Android):https://play.google.com/store/apps/details?id=com.halcyon.pocketgirl3
    URL(iOS):https://itunes.apple.com/jp/app/id1539553611

    PV:


    Unityの画像データ圧縮について。

    Unityでゲームを作っていると画像データで容量が大きくなっていきますよね。

    昔から言われている、4の倍数のサイズにするとデータ圧縮が効き、容量を大きく減らすことができます。

    どういうことかというと、こんな画像データがあるとします。



    ポケガ3のタイトルなんですが、このサイズが882x1560の場合、Unityではこんな注意が出てます。



    これよく見るんじゃないですかね。



    こんなメッセージが出てて、サイズは5.2Mもあります。

    サイズが882x1560なので、4で割り切れません。

    では、4で割り切れる880x1560にしてみます。
    且つ、Generate MipMapsのチェックを外します。



    なんとサイズが0.7Mまで下がりました。

    ついでに、スマホのゲームの場合、AndroidとiOSの設定を次のようにするといいらしいです。

    Android


    画像に透過がない場合は「RGB Compressed ETC2 4bits」
    透過がある場合は「RGBA Compressed ETC2 8bits」


    iOS


    にすればいいらしいです。

    これでAndroid、iOS共に少しでも画像を軽くできるみたい。

    特に大きめの画像が多い場合は劇的に容量が減るのでやってみてください。

    ということで、画像の容量削減の方法でした。

    あでゅ~ノシ

    Category: 開発日記(Unity)

    tb 0 : cm 0