Unityでソシャゲを作りたい#7 POPUPなどを実装したのでホーム画面の基盤ができたが地獄の問題に直面した

今までの残課題だったPOPUPが完成しました。

Templateとして枠が準備してあって、その中に入れるGameObjectを外部で作成しぶち込むとサイズ感とか計算して表示してくれる仕様のつもりです。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System.Threading.Tasks;
using DG.Tweening;

public delegate void Callback();
public class PopUp_script : MonoBehaviour{

   void Start(){
       
   }
   GameObject Mine;
   GameObject window;
   GameObject title;
   GameObject contentsarea;
   GameObject btarea;

   
   //それだけで完全に機能するGOを事前に作ってハメたらPOPUP化して表示
   public void Set_POP(GameObject contents,GameObject BTset = null){
       Mine=this.gameObject;
       if(contents==null){
           Debug.Log("コンテンツがnullだわさ");
           OnDefaultBT();
           return;
       }
       float w = Screen.width;
       float h = Screen.height;

       float windowW = w*0.8f;

       float titleH = windowW*(1f/6f);
       float BTH    = windowW*(1f/6f);
       if(BTset==null){ BTH = 0f;}
       

       float contentsMaxH = (h*0.8f)-titleH-BTH;
       float contentH = contents.GetComponent<RectTransform>().sizeDelta.y;
       if(contentH>contentsMaxH){contentH=contentsMaxH;}

       float windowH = titleH+BTH+contentH;

       GetComponent<Image>().DOFade(0.6f, 0.5f);
       window = this.gameObject.transform.GetChild(0).gameObject;
       title  = window.transform.GetChild(0).gameObject;
       contentsarea  = window.transform.GetChild(1).gameObject;
       btarea = window.transform.GetChild(2).gameObject;

       window.GetComponent<RectTransform>().DOScale(new Vector3(0,0,0), 0f);
       title.GetComponent<RectTransform>().DOScale(new Vector3(0,0,0), 0f);
       btarea.GetComponent<RectTransform>().DOScale(new Vector3(0,0,0), 0f);
       contentsarea.GetComponent<RectTransform>().DOScale(new Vector3(0,0,0), 0f);

       window.GetComponent<RectTransform>().sizeDelta = new Vector2(windowW,windowH);
       window.GetComponent<RectTransform>().localPosition = new Vector2(0f,0f);
       
       title.GetComponent<RectTransform>().sizeDelta = new Vector2(windowW,titleH);
       title.GetComponent<RectTransform>().localPosition = new Vector2(0f,windowH/2f-titleH/2f);

       btarea.GetComponent<RectTransform>().sizeDelta = new Vector2(windowW,BTH);
       btarea.GetComponent<RectTransform>().localPosition = new Vector2(0f,-windowH/2f+BTH/2f);

       contentsarea.GetComponent<RectTransform>().sizeDelta = new Vector2(windowW,contentH);
       contentsarea.GetComponent<RectTransform>().localPosition = new Vector2(0f,BTH/2f-titleH/2f);

       contents.GetComponent<RectTransform>().sizeDelta = new Vector2(windowW,contentH);
       contents.transform.SetParent(contentsarea.transform, false);
       //buttonはパネルにまとめてから入れること子要素の数で判断します。
       if(BTset.transform.childCount>0 && BTset!=null){
           BTset.GetComponent<RectTransform>().sizeDelta = new Vector2(windowW,BTH);
           BTset.transform.SetParent(btarea.transform, false);
       }else if(BTset.transform.childCount <= 0 && BTset!=null){
           //nullではないけど子要素はない
           //defaultボタンをセット
           GameObject DfBT_prefab = (GameObject)Resources.Load(ConfigDatas.prefabTempPath+"PopUp/P_DefaultBTpanel");
           GameObject DfBT =Instantiate(DfBT_prefab) as GameObject;
           DfBT.transform.GetChild(0).GetComponent<Button>().onClick.AddListener(() => OnDefaultBT());
           DfBT.transform.SetParent(btarea.transform, false);
       }

       window.GetComponent<RectTransform>().DOScale(new Vector3(1,1,0), 0.5f);
       title.GetComponent<RectTransform>().DOScale(new Vector3(1,1,0), 0.5f);
       btarea.GetComponent<RectTransform>().DOScale(new Vector3(1,1,0), 0.5f);
       contentsarea.GetComponent<RectTransform>().DOScale(new Vector3(1,1,0), 0.5f);
   }
  
   public async void OnDefaultBT(){
       if(window==null){Destroy(Mine); return;}
       window.GetComponent<RectTransform>().DOScale(new Vector3(0,0,0), 0.4f);
       title.GetComponent<RectTransform>().DOScale(new Vector3(0,0,0), 0.4f);
       btarea.GetComponent<RectTransform>().DOScale(new Vector3(0,0,0), 0.4f);
       contentsarea.GetComponent<RectTransform>().DOScale(new Vector3(0,0,0), 0.4f);
       await Task.Delay(40);
       Destroy(Mine);
   }

   void Update(){
       
   }
}

こんな感じですね。

まぁ大概な力業なんで、recttransform.sizeDelta = new Vector2(w,h);が理解できれば全部それですね。

動作としてはこんな感じです。

画像1

gifの長さの関係上大急ぎで操作してます。ごめんなさい。

あと画像がテスト用に好きなUIスクショしたやつを使ってるので著作権とか劇恐いです。悪気はマジでないのでまずい場合はすぐ消します。

動作は伝わったでしょうか。最後のボタン三つ並んでるPOPUPはキャラ一覧です。DBに三体分しか登録しなかったのでああなりました。

ちなみに画像やクエストデータはすべてテスト用の自作ローカルサーバから取得してるんですよ。いいでしょ。

これでホーム画面の動作は基本全部出来ます。

大問題

大体できたら実機テストするわけで、私の今の愛機galaxy s10 5gでテストしたらそれなりに動きました。

しかしながら、前の愛機AQUOS Rで動かしたらカックカク…

しかも文字がバグる…

なぜなんだ。

と、少し考えて気づいてしまいました。

BestFitだ。

ちらっと見かけましたが、Textコンポーネントの文字サイズを枠に合わせてくれる機能のBestFitはやったら重いらしいですね。

今回tweenで大きさも可変してるのでことさら重いのでしょう。

そうです。致命的です。他にも問題はございまして。

POPUP表示中頑張って隙間から後ろタップすれば画面移動しやがります。

これは対策可能ですが、このままボタン押されたらPOPUPが被ったりもします。

全部直すとなると…地獄ですね。

潜在的な問題はほかにも

今のところ問題になってはいないですが、後々問題になりそうな部分で、

エディタ画面で再生中にプログラムを変更してリロードが走った場合、Updateで常時監視している部分がNullReferenceを吐きやがります。

それから、サーバと通信する際アニメーションが停止します。

Unitywebreqest がメインスレッドでしか動かせない制約が敵です。

これは改善自体は後ででいいですが、ロードタイミングが雑なのでそこは管理しないといけません。

以上を全部管理するため、全体管理の体制にメスを入れます。

詳しくは次回以降にしますね。

ではまた。

この記事が気に入ったらサポートをしてみませんか?