クレーンゲーム作る　後編

[【完走目指す】初心者が25日で強くなる Advent Calendar 2022](https://qiita.com/advent-calendar/2022/aruhitoganbaru)
１６日目の記事です。
### 初めに
下書き保存ボタンを押さなかったので途中中身がだいぶ消えました。
なので遅れました。
中身がおかしくなっているかもしれないです。
# 前編の様子　
![スクリーンショット_20221215_214141.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2961125/fde810c7-7544-fbb9-e2dc-2e64344e58b7.png)
![スクリーンショット_20221215_215621.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2961125/d7d4deae-9937-d8b5-21f7-182b8d151667.png)
見た目はほぼ完成系です。
では、中身を作ります。
前編の最後で動きをまとめたので一つ一つ作ります。
## 1.横移動ボタンを押すと、クレーンが横に動く
横に動きます
中身はこうなります。
```
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Button1 : MonoBehaviour
{ public Sys Sy;
    public bool buttonDownFlag = false;
    public GameObject Crane;
    // Start is called before the first frame update
    void Start()
    {
        
    }

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

        if (buttonDownFlag==true)
        {
            if (Sy.STen == 0)
            {
                if (Crane.transform.position.z <= 6.1)
                {
                    Crane.transform.Translate(0,0, Time.deltaTime);
                }
            }
        }
        
    }
    public void OnButtonDown()
    {
        buttonDownFlag = true;
    }
    public void OnButtonUP()
    {
 
        buttonDownFlag = false;
        if (Sy.STen == 0)
        {
            Sy.STen = 1;
        }
    }
}

```
# 結果
うごいた！
ちなみに、今回はButtonのOnClickを使っていません。
![スクリーンショット_20221215_235336.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2961125/98850b7b-6ee1-2822-13ae-b7efbff09951.png)
Event Triggerとかいうのを使います
![スクリーンショット_20221215_235423.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2961125/c964f827-6d70-c8c0-825c-73f907f041f4.png)
ちなみに、こっちでないとちゃんと動きません
# 2.縦移動ボタンを押すと、クレーンが縦に動く
は、省略します。
大体中身は1の工程と同じです。
動く向きとか変えてあげればできます。
# 3.クレーンのアームが45度動いて開く
ここで、アームが
![スクリーンショット_20221216_002518.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2961125/b47f9011-d1da-8eea-79dc-beae05824b99.png)
くにゃっと。曲がる。
### 原因
どうやら、blenderで作ったものをこんな感じに
![スクリーンショット_20221216_002615.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2961125/b1004276-03a8-b4e4-bd4e-e8a135681606.png)
オブジェクトを親子関係にして角度を変えると、おかしくなるっぽいです。
しかし親子関係を崩すと、クレーンの頭だけが独立して動いてしまいます。
### 対処
空のオブジェクトを用意します
![スクリーンショット_20221216_002944.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2961125/fc14471f-6893-3cf4-6a17-bf9007c30c45.png)
これに入れて、
![スクリーンショット_20221216_003103.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2961125/e6cf1ae6-48df-2662-98f2-8d389049c0c5.png)
親子関係をなかったことにすると、
![スクリーンショット_20221216_003200.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2961125/75ee20d5-f747-dc89-a5a7-6438a019781d.png)
ちゃんと動いた！
ヨシ！

では、アームを動かす部分を書いていきます。


中身はこうなりました。
```
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Crane : MonoBehaviour
{
    public GameObject Crn1;
    public GameObject Crn2;
    public Sys Sy;
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        Debug.Log(Crn1.transform.localEulerAngles.x);
       
        if (Sy.STen == 2)
        {
            if (Crn1.transform.localEulerAngles.x >= 315|| Crn1.transform.localEulerAngles.x == 0)
            {
                Crn1.transform.Rotate(-Time.deltaTime*15, 0, 0);
            }

            if (Crn2.transform.localEulerAngles.x >= 315|| Crn2.transform.localEulerAngles.x == 0)
            {
                Crn2.transform.Rotate(-Time.deltaTime*15, 0, 0);
            }
        }
        
        if (Crn1.transform.localEulerAngles.x <= 315 && Crn2.transform.localEulerAngles.x <= 315)
        {if(Crn1.transform.localEulerAngles.x >= 300 && Crn2.transform.localEulerAngles.x >= 300)
            {
                Sy.STen = 3;
            }
                
          
        }
        
    }
}
```
これで動きました。
ちなみに、クレーンは315度ぴったりの状態をすり抜けた時のために、300度まで取ってあります。

#　4.クレーンが下に下がる、5.止まる
下に下げます。
```
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CraneDown : MonoBehaviour
{
    public GameObject Crane;
    public Sys Sy;
    public bool Hit;
    // Start is called before the first frame update
    void Start()
    {
        Hit = false;
    }
        // Update is called once per frame
        void Update()
        {
            if (Sy.STen == 3)
            {
                if (Crane.transform.position.y >= 2 && Hit==false)
                {
                    Crane.transform.Translate(0,-Time.deltaTime,  0);
            }if (Crane.transform.position.y <= 2 || Hit == true)
            {
                Sy.STen = 4;
            }           
            }


        }
    void OnCollisionEnter(Collision collision)
    {
        Hit = true;
    }
}
```
> if (Crane.transform.position.y >= 2 && Hit==false)
                {
                    Crane.transform.Translate(0,-Time.deltaTime,  0);
            }

&&を使うことで、こちらも当てはまるときの条件にしています。
>if (Crane.transform.position.y <= 2 || Hit == true)
            {
                Sy.STen = 4;
            }       
どちらか片方が当てはまらなくなった時に、止まります。

# 6.クレーンのアームが閉じる
クレーンのアームを閉じます。
やってることは3の逆になります。しかし、中身は少し変わります。
「360度以下で動く」と書くと、360まで行ったときに0に戻ってしまい一生動きます。
なので、0度（今回は５度以下、0含む）になった時点で止めてます。
```
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ArmClose : MonoBehaviour
{
    public GameObject Crn1;
    public GameObject Crn2;
    public Sys Sy;
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        if (Sy.STen == 4)
        {
            if (Crn1.transform.localEulerAngles.x <= 360 )
            {
                Crn1.transform.Rotate(Time.deltaTime * 15, 0, 0);
            }

            if (Crn2.transform.localEulerAngles.x <=360 )
            {
                Crn2.transform.Rotate(Time.deltaTime * 15, 0, 0);
            }
        }

        if (Crn1.transform.localEulerAngles.x <= 2 && Crn2.transform.localEulerAngles.x <=2)
        {
            if (Sy.STen == 4)
            {
                Sy.STen = 5;
            }
               
            


        }

    }
}
```
これで動きます。
# 7.クレーンを上げる
クレーンを下げるものに、
```
  if (Sy.STen == 5)
        {
            if (Crane.transform.position.y <= 8)
            {
                Crane.transform.Translate(0, Time.deltaTime, 0);

            }
            if (Crane.transform.position.y >= 8 )
            {
                Sy.STen = 6;
            }
```
これを加えるだけ。簡単。
# 初期位置に戻す
```
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Res : MonoBehaviour
{
    public Sys Sy;
    
    public GameObject Crane;
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        if (Sy.STen == 6)
        {
            if (Crane.transform.position.z >= 0)
            {
                Crane.transform.Translate(0, 0, -Time.deltaTime);
            }
            if (Crane.transform.position.x <= 32)
            {
                Crane.transform.Translate(Time.deltaTime,0,0);
            }
            if (Crane.transform.position.x >= 32 && Crane.transform.position.z <= 0)
            {
                Sy.STen = 7;
            }
        }

    }
}

```
これでOK
# 9.アーム開閉
さっきのアーム開閉をコピペして、少し手を加える。
だけでは動かなかったので、書き直しました。
開くほう
```
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Arm : MonoBehaviour
{
    public GameObject Crn1;
    public GameObject Crn2;
    public Sys Sy;
    // Start is called before the first frame update
    void Start()
    {
        
    }

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


        if (Sy.STen == 2)
        {
            if (Crn1.transform.localEulerAngles.x >= 315 || Crn1.transform.localEulerAngles.x <= 1)
            {
                Crn1.transform.Rotate(-Time.deltaTime * 15, 0, 0);
            }

            if (Crn2.transform.localEulerAngles.x >= 315 || Crn2.transform.localEulerAngles.x <= 1)
            {
                Crn2.transform.Rotate(-Time.deltaTime * 15, 0, 0);
            }


            if (Crn1.transform.localEulerAngles.x <= 315 && Crn2.transform.localEulerAngles.x <= 315)
            {
                if (Crn1.transform.localEulerAngles.x >= 300 && Crn2.transform.localEulerAngles.x >= 300)
                {
                    Sy.STen = 3;
                }


            }
        }
        if (Sy.STen == 7)
        {
            if (Crn1.transform.localEulerAngles.x >= 315 || Crn1.transform.localEulerAngles.x <= 1)
            {
                Crn1.transform.Rotate(-Time.deltaTime * 15, 0, 0);
            }

            if (Crn2.transform.localEulerAngles.x >= 315 || Crn2.transform.localEulerAngles.x <= 1)
            {
                Crn2.transform.Rotate(-Time.deltaTime * 15, 0, 0);
            }


            if (Crn1.transform.localEulerAngles.x <= 315 && Crn2.transform.localEulerAngles.x <= 315)
            {
                if (Crn1.transform.localEulerAngles.x >= 300 && Crn2.transform.localEulerAngles.x >= 300)
                {
                    Sy.STen = 8;
                }


            }
        }

    }
}
```
閉じる方
```
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ArmClose : MonoBehaviour
{
    public GameObject Crn1;
    public GameObject Crn2;
    public Sys Sy;
    // Start is called before the first frame update
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {
        if (Sy.STen == 4)
        {
            if (Crn1.transform.localEulerAngles.x <= 360)
            {
                Crn1.transform.Rotate(Time.deltaTime * 15, 0, 0);
            }

            if (Crn2.transform.localEulerAngles.x <= 360)
            {
                Crn2.transform.Rotate(Time.deltaTime * 15, 0, 0);
            }


            if (Crn1.transform.localEulerAngles.x <= 2 && Crn2.transform.localEulerAngles.x <= 2)
            {
                if (Sy.STen == 4)
                {
                    Sy.STen = 5;
                }



            }
        }
        if (Sy.STen == 8)
        {
            if (Crn1.transform.localEulerAngles.x <= 360)
            {
                Crn1.transform.Rotate(Time.deltaTime * 15, 0, 0);
            }

            if (Crn2.transform.localEulerAngles.x <= 360)
            {
                Crn2.transform.Rotate(Time.deltaTime * 15, 0, 0);
            }


            if (Crn1.transform.localEulerAngles.x <= 2 && Crn2.transform.localEulerAngles.x <= 2)
            {
                if (Sy.STen == 8)
                {
                    Sy.STen = 0;
                }

            }
        }
    }
}
```
これで動く。

# 最終チェック
画像とかはないけど、
動いたのでOK！
めり込みが気になるなら、調節すれば大丈夫です。
# 景品を持つ
（衝突は前回やったので省略して、）衝突検知するようにしてみたが、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2961125/9c08fab8-631d-d702-86a4-c21e44dcfd4f.png)

すり抜けた。
後、画像はないけどアームだけ取れて落ちることがありました。

# 対処法
クレーンが景品に当たった→景品がクレーンに当たった　
ようにします。　
多分これだけだと何を言ってるのか理解できないと思うので、解説します。　
## 解説

### 古いほう
景品にタグ
![スクリーンショット_20221216_103442.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2961125/4cb470aa-c49c-2dfc-154c-82df97e846f3.png)
クレーンで衝突検知
![スクリーンショット_20221216_103428.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2961125/7d239b89-21a6-5c31-0fca-21f8206a1bc6.png)

### 新しいほう
クレーンにタグ
![スクリーンショット_20221216_105351.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2961125/5c054646-640d-1ce6-fa31-f49159df8cca.png)
景品で衝突を検知
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2961125/aefa9d92-43b4-8e5a-b122-85ed778061f2.png)

これでやってみます。
#### 結果
できた！！！
## 景品を取るために
土台とかを追加しました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2961125/d582fc7e-bfed-72da-c19b-a7043ebf8e5b.png)
あと
こんなのを作って、
![景品ゲット.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2961125/d5615250-bb46-e9b1-a3d1-76f9508f269a.png)
景品が取れた時に出るようにしました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2961125/79b3a847-32e8-c475-2fae-450966e98e5f.png)

# まとめ
動画
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">初心者の作るクレーンゲーム（記事用） <a href="https://t.co/hbEpaqihwj">pic.twitter.com/hbEpaqihwj</a></p>&mdash; ある暇な人 (@Aruhimanahito) <a href="https://twitter.com/Aruhimanahito/status/1603760352118067201?ref_src=twsrc%5Etfw">December 16, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

クレーンゲームは、初心者でも簡単に作れる

16日目　終わり