UE4のC++でWidgetを弄ってガバガバ電卓を作る

# はじめに
これは鈴鹿高専Advent Calendar2021の18日目の記事です。

https://qiita.com/advent-calendar/2021/snct

# 作成経緯
学校課題にてマクローリン展開を用いた近似計算をC++で実装し、sin,cos,tan等…の計算が可能な電卓を作ろうというものが出た。
そしてUnrealEngine4はC++で実装できるためどうせならそれで作ろうと思い至った。

# 概要

使用Version:4.26.2-15973114

UE4のBlueprintをなるべく使わず、WidgetをC++で実装して電卓を作成した
Githubにてこの電卓のソースコードを挙げておくので気になる人は見てください
可読性は低いです
https://github.com/nakimikan/UE4_calc

### 今回の記事作成に対して特に参考にさせてもらった記事
http://mklearning.blogspot.com/2014/12/umg.html
http://kagring.blog.fc2.com/blog-entry-122.html
https://kinnaji.com/2019/03/27/calculator/
https://dokuro.moe/ue4-cpp-translation-of-child-widget-without-blueprint/
https://qiita.com/unknown_ds/items/4189b6c31322f46afdb3
そしてUE4の各リファレンス

## 作り方
### Level作成
電卓を使う基本のlevelを作ります
といっても中身にはなにも置く必要がないので真っ暗なlevelでもなんでもいいので置きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2326126/3899e56f-3950-140a-0a86-65093c5696d2.png)
レベルブループリントを開き画像の通りにノードを伸ばしてコンパイルします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2326126/982a588e-52ec-bc5c-f44a-09b2da340231.png)
これの役割はlevelを開いたらwidgetを開くことと、マウスカーソルを表示するためです


### WidgetBluePrintの作成
次に基となるWidgetを作ります
右クリックで選択し、適当な名前を付けます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2326126/e110f5b5-0c91-6bfb-c43d-3c80aa3f1f51.png)
できたらこのWidgetを編集していきます
まずCanvasPanelがデフォルトで配置されているのでこれを消し、GridPanelを配置します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2326126/06334d81-43b0-04f0-3091-9e78d5cf9a68.png)
配置したらGridPanelをクリックし詳細ビューからフィルルールを変えていきます。
使うボタンの数やレイアウトのこだわりによってこれは変わってきます。
私の配置はこんな感じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2326126/95a4d453-486f-ad98-8e59-919d9ee6e913.png)
編集できたらボタンとテキストボックスを置いていきます。
ボタンをパレットから検索してそれをGridPanelにドラッグアンドドロップすると無事配置できるはずです
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2326126/179baa10-7778-575a-d922-fe263c51c9ac.png)
テキストブロックもButtonにドラッグアンドドロップをして配置していきます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2326126/d3bacba4-9284-2ea0-c64d-1ac238f29eeb.png)
これをひたすら繰り返し、いい感じのボタン配置を作ります
そして計算結果を表示するためのテキストボックスも配置します
見やすいよう文字の大きさなども詳細ビューから変えておきます
最終的にはこうなりました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2326126/19bf5ecd-550c-f298-a5e3-8629c5167216.png)
**後で、C++で活用するために名前は自分のわかりやすいものをつけておきましょう**
これで一旦、Widgetの編集は終わりです
### C++でのWidgetクラスの作成
次に、C++でWidgetのクラスを作成していきます
C++クラスのフォルダ内で右クリックして新規C++クラスを作成します。
UserWidgetを親クラスとして適当な名前をつけて作成します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2326126/4138d252-386e-d514-240c-71ebf19a5411.png)
作成したクラスをVisualStudioで編集していきます
全てを解説するのはしんどいので重要そうな部分を特筆していきます。

```C++
UPROPERTY(EditAnywhere, meta = (BindWidget))
		class UButton* button_plus = nullptr;
```

作成した名前のボタンやテキストボックスをC++で使用するためにこれをヘッダーファイルで定義します。
これでボタンやテキストボックスの関数等を呼び出せます。

```C++
virtual void NativeConstruct() override;
virtual void NativeTick(const FGeometry&, float) override;
```

NativeConstructは要はコンストラクタです。
NativeTickは毎フレーム呼び出される関数...だと思ってます。もしかしたら違うかもしれません...
あとは公式リファレンスとにらめっこの時間です。頑張りましょう

[UButtonの公式リファレンス](https://docs.unrealengine.com/4.26/en-US/API/Runtime/UMG/Components/UButton/)
[FTextの公式リファレンス](https://docs.unrealengine.com/4.27/ja/ProgrammingAndScripting/ProgrammingWithCPP/UnrealArchitecture/StringHandling/FText/)
[FStringの公式リファレンス](https://docs.unrealengine.com/4.27/ja/ProgrammingAndScripting/ProgrammingWithCPP/UnrealArchitecture/StringHandling/FString/)

コードが書けたらC++クラスをコンパイルします。
そしてwidgetにこれを親として継承させます。
実行してみましょう
これで満足いくものができていたら~~妥協~~完成です



## 使い方
基本は普通の電卓と同じ
~~ここからクソ仕様~~
同じ数字を連続で入力ができず、入力する場合は→のボタンを押す仕様になっています。
sin,cos,tanなどの入力の際は近似回数を入れる必要がある
使用してる様子

https://twitter.com/6nakimikan9/status/1442527812666101761


## やりたかったけどできなかったこと
誰か教えてください……

* C++の関数やクラスをBluePrintで使用する方法　　　    
　できたら圧倒的に便利          
　近似式の計算式の実装をBlueprintでやるのは正気じゃない   
* UButtonのOnClickedを使用する方法

 >同じ数字を連続で入力ができず、入力する場合は→のボタンを押す仕様になっています。

　この仕様が存在する理由。OnClickedでなくIsPressed()を使用しているから
　IsPressed()を使っててもちゃんと考えればこの仕様をなくすことはできるとは思ったけど頭が当時回らなかった

* 少数第8位以降の表示方法       
そもそもC++で桁数指定しての表示方法をiomanipしか知らない    
標準ライブラリのStringとかでそれができればいけるとは思う
 　　
* フルスクリーンでなくWindowモードで起動する方法
　iniファイルをいじる方法をためしたけどなぜかできなかった 
　BluePrintをいじる方法は試してない~~早くやれ~~

* 試行錯誤してたときにつくったc++クラスやActorを消す方法 
　どうして消せないのかわからない...
　これができないといつかファイル管理できなくて死にそうな未来が確定してる
　ただでさえファイルやらの命名センスがないのに...
* ~~プロジェクトの公開方法~~できた
　他の人はgoogledriveでやってた

## まとめ
自分の無知を晒した記事となりました
ボタンとかテキストとかを簡単に配置できて実行ファイルも簡単につくれるのはいいですね
今度は普通にゲームつくりたいです
もっとUE4のC++の記事増えてほしい……