Unity動くオブジェクトをプログラミングで制御するの巻

こんにちわ。どこに向かっているかわからない私です。
これねぇ、、、いろいろやり方があるからあんまり説明したくないのよね、、、
(え?なぜかって?己の技術力のなさがばれちゃうからだじょ)

さて、タイトルの通りです。
前作成したオブジェクトに制御を加えていきましょう、
↓前作った奴↓

うーん、Unity初心者なので、まだよくわかってませんw
作成したオブジェクトをシーン上に張り付けて、プレイすると、
ひたすら指定した動きを続けるという状態になっていると思います。

ひたすら手を振り続ける見切れた棒人間(静止画)

これを、動かしたり、止めたりしたいよね?え?動きっぱなしでいい?
じゃぁ終了!(嘘ですごめんなさい)
動かしたり止めたりだけじゃなく、オブジェクトの移動なんかも一緒にできるといいね。

と、いうことで、

まずは、オブジェクトを選択します。

見慣れてきたかな?この画面

今回はこの棒人間オブジェクトの動きをこちらで操作できるようにします。
ヒエラルキー内で、棒人間オブジェクトを選びます。
次に、インスペクター内「コンポーネントを追加」ボタンを押しましょう。
(コンポーネントって何なんやろうな?って調べたら「部品」って意味らしいよ。)

一番下に「New script」がある

New scriptをクリックしましょう。

はわわわー

新しいピッカピカの処理を作成するぞってことですね。
(いや、準備された何かがあるのかもしれないんですが、私は知らんので、まぁ、これから作っていきます。)

名前を付ける(適当

さて、そこまで書いたら「作成して追加」を押しましょう。

Ugokasu(スクリプト)が作成されておるぞ

ちなみに、この作り方をすると、コードの保存場所はAssetsのすぐ下になるみたいです。

おまえ、、こんなところに!

ごちゃごちゃすると困るので、棒人間を格納しているugokuzo/firstに移動しておきますね。

移動終了

さて、、ここからなんですが、
これね、私すでにやってしまったの。
でね、その時にいろいろ環境構築してしまったので、ここでその説明ができませぬ。。。
言語としてはC#を使うので、あなたが使うIDEだか何だかにC#を実装できるように調整してあげる必要があります。
(それしないとどうなるかって?いろいろあるんですが、、まぁ、「これでいける」という確信を得にくいです。(超ザックリ))

続けますです。

薄字になっているこいつをダブルクリーック!

インスペクター内、スクリプトにセットした「ugokasu」をダブルクリーックすると、、、
こいつが起動します。

私の場合はこいつが出てくるぜ。

これ、なんですっけ?
えーっとVisualStudio?かな?
・・・ですね。(使えるならツールは何でも良い派)
私がやるとこいつが出てきます。

で、これなんですが、ちゃんとC#使える状態にしておかないとちゃんと動かなかったです。。多分(一週間前のことをすでに忘れるおバカわたし)

かろうじて覚えていることは、、、
Visual Studio Installerを開いて、、

思い出せ、、、わたし、、、!

変更ボタンをクリックした後で、、、

これだっけ?

「Unityによるゲーム開発」のチェックボックスにチェックを入れて、、
右下にある変更ボタンをクリックしたような、、、

ここを、、、押すのじゃ。。

で、VisualStudioを再起動すればよかったのですが、、
これだけだと、補完(先頭数文字入れると「これでしょ?」って候補を出してくれる便利機能)が動かなかったので、
えーそこは忘れてしまったので、
「Visual Studio Unity 補完」でググればまぁ、わかるでしょう。
(ありがとうGoogleさん、困ったときはいつも助けてくれる!)
それで、環境構築としては完了するはずであります。(確信が持ててない)

まずはコード説明から。

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

public class ugokasu : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        
    }

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

開いた直後のコードはこのようになっています。
ugokasuというクラスの中に
Start()という処理と、Update()という処理があります。
それぞれの中身は空っぽです。({}で囲まれている部分に処理が入ります。)

ちなみに、

Start()とは?

Start()はですね、このオブジェクトが作られた瞬間に一回だけ動く処理です。要は、初期化が必要な処理がここに入ると思ってください。

Update()とは?

Update()はですね、、、更新されたときじゃないよ!
これは一定時間たつごとに実行される処理になります。
うん、、まぁ、最初はその程度の認識でも全然大丈夫。
その一定時間、1分毎とかじゃないです。
チョー早い。です。(どれくらい感覚だったか忘れた。。ので、あとで調べましょ。)
だから、Updateが実行されるたび動きを止めたり動かしたりしても全然わかんないから注意してね!

(英語で書いてるって?うん。そうですね。)

じゃぁ、どうやって処理を書くのか?

まぁ、まずはUpdate()の中でいいです。
たくさん動いている処理の中で、「この処理のとき、ボタン押されてる?」みたいな感じで処理を書いてあげればよいです。
えーっとですね、、(先週書いたコードをよむわたし)

    void Update()
    {
        if (Input.GetKey(KeyCode.A))
        {

        }
    }

Update()の{}の中にこんな風に書いてみました。

~~プログラミング未経験者向け記述ここから↓~~

if (Input.GetKey(KeyCode.A))

if(もし)、Input(キーを押していたとき)、GetKey(そのキーが)、KeyCode.A(「A」)だったら?
みたいな意味です。
結果が正(true)の時にIfの{}の中身が実行されます。
要は、この処理を実行する時点で、キーボードのAというボタンが押されていればIFの{}の中身が実施されるのです。

~~プログラミング未経験者向け記述ここまで~~

さて、条件は今決めました。
「Aというボタンを押されたときに動きを止めたり動かしたりしたい。」
次は動きを止めたり、動かしたりする処理です。
いったん止めるか、、

    void Update()
    {
        if (Input.GetKey(KeyCode.A))
        {
            GetComponent<Animator>().speed = 0;
        }
    }

追加したのは

GetComponent<Animator>().speed = 0;

まず、
「GetComponent<Animator>()」
対象のオブジェクト(今回で言うと棒人間)に紐づいているコンポーネント(インスペクターに入っているもろもろ)を探す処理です。
「<>」の中に入れたコンポーネントを探してきてくれきます。
今回だとAnimatorを探してきます。
拾ってくるコンポーネントで処理が変わります。
(Transformだったら、回転や、サイズを変えたり、だとかですね)
えーっと、動画を止めるので、Animatorコンポーネント内に、動画の再生スピードを変える項目があります「speed」ですね。これを「0」にすると止まって、「1」にすると普通のスピードで再生されます。

※こういう処理は覚えるのはめちゃくちゃ大変です。量が、量がやばい。。
 なので、こういった処理はググるのです。
 「Unity 2D アニメーション 止める」
 とか書くと大体出てくるます。

さてさて、実行してみましょう。
※あ、VisualStudioのデータは保存してください。「Ctrl+C」でおけです。

「*」があると保存できてないからね!

保存すると、Unity側が「読み込み中・・・」みたいになるので少し待ってくださいね。
え?うまくいくよー

Unityでプレイボタンクリーック!
そして、キーボードのAを押す!

とまったあああ!(静止画w

が、しかし、これだと止まるだけです。
再動がかないません。。
さてやり方はいろいろありますが、
まぁ、speedの内容が1だと再生、0だとストップとわかったので、これを利用しますかね。

    void Update()
    {
        if (Input.GetKey(KeyCode.A))
        {
            float sp = GetComponent<Animator>().speed ;
            if (sp == 0)
            {
                GetComponent<Animator>().speed = 1;
            }
            else
            {
                GetComponent<Animator>().speed = 0;
            }
        }
    }

あ、、、(思い出して硬直)
あーーーーうん。
ま、いいや。いったん説明しましょう。

~~ここからプログラミング未経験者向け~~
float sp = GetComponent<Animator>().speed ;
これは何をやっているかというと、
Float型という形を持つ入れ物を作っています。
名前が「sp」です。
float型ってのは数値(小数点以下あり)です。
めちゃくちゃざっくりなので、詳しく知りたいときはググりましょう
なぜFloat型かって?
GetComponent<Animator>().speed がFloat型でデータを持っているからです。
型はそろえるのが基本です。どうやって知るか?
こうやってです。

今時全部便利!

「speed」のところにマウスカーソルを乗せてちょっと持つとこんな風に表示されえます。
「float Animator.speed」って書いてますね。
これで判断してます(私の場合)

で、ですね、その準備したspと名前を付けたfloat型専用エリアに、
GetComponent<Animator>().speedの中身を保管させているのです。
まぁ、直接IFの中に書いてもいいんですけどね、こう書いておきますよ。

で、次はどこかな、、
if (sp == 0)
これか。
今取得したAnimator.speed(spの中身)がどうなっているかを確認します。
0だと止まっていて、
1だと動いているんですね。
sp==0 の「==」は比較するための記号です。
「=」だと、
(例:sp=0だと、)
spというエリアに「0」を入れるという処理になってしまいます。
なので、比較したいときは「==(おなじ)」あるいは「!=(違う)」を使用します。
あと、もう一つか
「else」
これはifに指定した条件「じゃない」ときの処理になります。

if(A)
{
  Aが正(true)の時の処理
}
else
{
  Aが偽(false)の時の処理
}

こんな感じですね。
なので、

            if (sp == 0)
            {
                GetComponent<Animator>().speed = 1;
            }
            else
            {
                GetComponent<Animator>().speed = 0;
            }

spが0の時、
GetComponent<Animator>().speedに1をセット、
spが0じゃないとき、
GetComponent<Animator>().speedに0をセット。

「0=止まっているとき」なので、要は
「止まっているとき、動かす。動いているとき、止める。」
という感じになるのです。
(伝われ・・・!)

~~プログラミング未経験者向けここまで~~

さてさて、動かしてみましょう。
プレイボタンぽちっとな、

うむうむ。。。?(静止画)

ちょっとね、挙動がおかしくなります。
Aを押すと動いたり止まったりするような、しないような、、、という感じになるかと思います。
止まったと思えば次Aを押しても止まったまんまだったり、
逆に動いているのが止まらなかったり
あれあれ?おかしいとなります。

さて、最初のころに説明しました。
Update()の処理されるタイミング。
これですね、本当に短いスパンで動いています。
いま調べました。1秒に60回(!)
さあ、勘の良い人はわかるでしょう。
「あなたは、Aというキーを60分の1秒で押せるのか・・?」
そう、そうです。
「Aが押されていたら0を1に、1を0にする」
のです。
なので、
「Aが押されている間、0と1を切り替え続ける」
という状態になっているのです。
なので、Aを押している時間ずっと処理が動き続けているという状態ですね。

じゃあどうするか?
えーっとですね。
プログラムの世界だと常識レベル(か?私の中だけ?)
でありますが、大体キー関連の処理には
「キーを押した瞬間」
「キーを離した瞬間」
を検知する処理があります。
調べると、
Input.anyKeyDownが、
「キーが押された瞬間」だけ、true(正)になるようです、
なので、これを使いましょう。

    void Update()
    {
        if (Input.anyKeyDown && Input.GetKey(KeyCode.A))
        {
            float sp = GetComponent<Animator>().speed ;
            if (sp == 0)
            {
                GetComponent<Animator>().speed = 1;
            }
            else
            {
                GetComponent<Animator>().speed = 0;
            }
        }
    }

さぁ、どこが違うでしょうか?
答え、最初のifの条件。
条件が追加されていますね。
Input.anyKeyDown &&  Input.GetKey(KeyCode.A)
「キーが押された瞬間 かつ、押されたキーがA」
の時処理が動くようになりました。
ふぅ、( ´Д`)=3 フゥ
疲れた。。。
これで、一応動画を動かしたり止めたりという動きができるようになりました。
(動画ははれないので割愛)
今回はこれで終了です。

もう少し制御の話は使用かなぁとは思っています。
(Startも使ってないし、ほかの処理もやってみたいんでね)
ではではまたそのうち。


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