カレンダー最後まで作る

[【完走目指す】初心者が25日で強くなる Advent Calendar 2022](https://qiita.com/advent-calendar/2022/aruhitoganbaru)４日目です。
２日目の続きです。カレンダーを今日で終わらせます。
## ２日目でやったこと
![スクリーンショット_20221201_105536.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2961125/bf7cf8ea-f90e-374d-426f-75adaa483a76.png)
これの、背景がなく、ボタンに数字が入ってないところまで作りました。

### 仕組み
1.今の日時と日数を取得
2.月初めの曜日を取得
3.1の情報をもとに先月の日数を取得
4.ボタンに対応した数字を入れる


## ボタンに数字を入れる

```
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System;
using TMPro;
public class Calendar : MonoBehaviour
{    public TextMeshProUGUI[] Day;
    private int year;
    private int month;
    private int i;
    private int days=1;
    private int Mday;//今月の日数
    private int Fday;//前月
    private int Ndays=1;
    DayOfWeek firstDate;
    // Start is called before the first frame update
    void Start()
　{
year = DateTime.Now.Year;
        month = DateTime.Now.Month;
        DateTime firstDay = new DateTime(year, month, 1);
        firstDate = firstDay.DayOfWeek;
         Mday = DateTime.DaysInMonth(year, month);
        if (month == 1)
        {
            Fday = DateTime.DaysInMonth(year - 1, 12);
            
        }
        else
        {
            Fday = DateTime.DaysInMonth(year, month - 1);
        }
        Debug.Log(Fday);
        switch (firstDate)
        {
            case DayOfWeek.Sunday:

                for (i = 0; i <= Mday-1; i++)
                {
                    Day[i].text = days.ToString();
                    days = days + 1;
                }
                Debug.Log("Sunday");
                    break;
            case DayOfWeek.Monday:
                for (i = 1; i<Mday; i++)
                {
                    Day[i].text = days.ToString();
                    days = days + 1;
                }
                Debug.Log("Monday");
                break;
            case DayOfWeek.Tuesday:
                
               
                for (i = 1; i >=0; i--)
                {
                    Debug.Log(i);
                    Day[i].text = Fday.ToString();
                    Fday = Fday - 1;
                }
                for (i = 2; i <= Mday+1; i++)
                {
                    Day[i].text= days.ToString();
                    days = days + 1;
                }
               for(i=Mday+2; i < 42;i++)
               {
                    Day[i].text = Ndays.ToString();
                    Ndays = Ndays + 1;

                }
                
                break;
            case DayOfWeek.Wednesday:
                for (i = 3; i <= Mday+2; i++)
                {
                    Day[i].text = days.ToString();
                    days = days + 1;
                }
                Debug.Log("Sunday");
                break;
            case DayOfWeek.Thursday:
                for (i = 4; i <= Mday+3; i++)
                {
                    Day[i].text = days.ToString();
                    days = days + 1;
                }
                Debug.Log("Monday");
                break;
            case DayOfWeek.Friday:
                
                for ( int i=5; i <= Mday+4; i++)
                {
                    Day[i].text = days.ToString();
                    days = days + 1;
                }
                for (int i = Mday+1; i <=42; i++)
                {
                    Day[i].text = days.ToString();
                    days = days + 1;
                }

                Debug.Log("Tuesday");
                break;
            case DayOfWeek.Saturday:
                for (i = 6; i <= Mday+5; i++)
                {
                    Day[i].text = days.ToString();
                    days = days + 1;
                }
                Debug.Log("Saturday");
                break;


        }

    }

    // Update is called once per frame
    void Update()
    {
       
    }
}
```
##### 説明
>using TMPro;

![スクリーンショット_20221201_111213.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2961125/7d99254b-8f42-0b50-33bd-99d97e7263dd.png)
Textの横に(TMP)とついていたら必要です。


>public TextMeshProUGUI[] Day;

さっきusing TMProを追加したので、TextMeshProUGUIが使えるようになりました。
[]を使うと、たくさんのオブジェクトをまとめて管理できます。これを「配列」といいます。
例えばここに、リンゴ、ミカン、ブドウがあったとします。
![4-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2961125/2ac818c5-0fa0-d39d-4c93-5e30d1c747ef.png)

これを、果物用のかごに入れてあげるイメージです
![フルーツバスケット.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2961125/ad0b8641-cde9-a69a-023c-7d9be7aff33a.png)

こんな感じで、全てのフルーツをかご1つで管理できます。　
かごを持てば、すべてのフルーツを一度に持てます。
もちろん、中身はそのまま使えます。　


>DayOfWeek firstDate;

DayOfWeekは、曜日を表すことができるモノになります。ここではfirstDateと名付けます。後で使います。

書き忘れてましたが、intやobjectの前についているpublicとかprivateについて紹介します。　
![4-4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2961125/d6f0ff12-a4d4-bab3-3ea7-51fa5e2cebfd.png)

上のイラストのようにpublicをつかうと他のC#スクリプトで、元のC#のpublicで指定した値を使うことができます。　
逆に、privateだと、これはできません。詳しくは９日目に書きます。
>DateTime firstDay = new DateTime(year, month, 1)
firstDate=firstDay.DayOfWeek;

Datetimeは、日付を表します。
ここでは、Datetimeをfirstdayと名付け、そのfirstdayにその月が何年の何月か（日は１日目で固定）を反映させます。
firstDateには、今反映させたfirstdayの曜日が入ります。
> Mday = DateTime.DaysInMonth(year, month);

Mdayに今月の日数が入ります


>if (month == 1)
        {
            Fday = DateTime.DaysInMonth(year - 1, 12);
            
        }
        else
        {
            Fday = DateTime.DaysInMonth(year, month - 1);
        }

ここで、Fdayが登場します。Fdayには先月の日数を入れます。Fdayは、もし今月が1月だったら去年の12月の日数が入ります。

> switch (firstDate)
        {
            case DayOfWeek.Sunday:
            for (i = 0; i <= Mday-1; i++)
        {
            Day[i].text = days.ToString();
            days = days + 1;
                                           }
            Debug.Log("Sunday");
            break;

今回は日曜日のパターンを例にとります。
 switchというものを使います。簡単に言えば、if文の上位互換です。
caseで場合分けしています。
forを使います。for文を終わらせるには、breakを使います。
これで1つ目の説明が終わりました。

### ボタンを押したときに日付が変わるようにする。
これが理解に苦しみました。
結構時間を取られました。
なんか![スクリーンショット_20221201_211718.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2961125/23f0acc3-b3ac-f8cd-a62f-d7cb994ffe3e.png)
こんなのとか
![スクリーンショット_20221201_220941.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2961125/239b6684-36b5-a108-d0e3-63e0bcbab40a.png)
こんなのが出てきて全然できませんでした。
終いには![スクリーンショット_20221201_222618.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2961125/4598ee9a-6346-507a-b511-d4ec9546e36d.png)
まったく意味不明なエラーが出てきたりしました。
再起動したら治りました。

#### 現在の状態
ボタンが「親オブジェクト」、テキストが「子オブジェクト」になっています。
親子関係です。
親は子供のものを勝手に使うことはできないし、子供も親のものを勝手に使えない状態です。
使うときには、「使います」と宣言しなければなりません。
↓失敗例です
```
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using UnityEngine.UI;
using TMPro;

public class CalClick : MonoBehaviour
{
   
   public  NowDate ND;
   
    

  
   
    public void OnClick()
    {
       
       
        ND.Day = GetComponentInChildren<Text>();

    }
}
```
![スクリーンショット_20221201_224310.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2961125/550bc95e-82c9-67b1-c2a0-520042f3462f.png)
GetComponentInChildren＜Text＞();がnullとして帰ってくるようです。

↓以下は成功例です
```
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using UnityEngine.UI;
using TMPro;

public class CalClick : MonoBehaviour
{
   
   public NowDate ND;

   TextMeshProUGUI A;

    // Start is called before the first frame update
   
    public void OnClick()
    {
        A = GetComponentInChildren<TextMeshProUGUI>();




        ND.Day = A.text;
      

    }
}
```
やっとできました。
これを作るのに一週間くらいかかったと思います。わからないと難しいです。
>public NowDate ND;

NDを使います。


   >TextMeshProUGUI A;

TextMeshProUGUIをAとします。
>A = GetComponentInChildren<TextMeshProUGUI>();

Aの中身に子オブジェクトのTextMeshProUGUIを入れました。

>ND.Day = A.text;

あとはNDのDayを子オブジェクトTextMeshProUGUIのtextにします。

### 仕上げ
すべてのボタンが反応するようにします。
頑張ってください。
背景なんかもつけて、いい感じにします。
自分は白い背景を付けました。
ついでに、押されたボタンの色を変えます。
Inspector>Button>Pressed Colorを変えます。
あと、数字の入らないボタンは消します。
ここも頑張って作ってください。
![スクリーンショット_20221202_005601.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2961125/bf2d0922-ed94-55c9-6bdf-8df7eafffd3b.png)

完成しました。
![スクリーンショット_20221202_005707.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2961125/1a2d031d-bc15-ec71-e002-a3a93c4357d0.png)
押すと光ります

## まとめ
### もっといいやり方があるはずです。
初心者なので、こんな方法しか思い浮かびませんでした。でも、少しは役に立つ情報があると思うので、参考までにどうぞ