pypy.com/

Python、Unity、FX自動化などを勉強しています。あと、コーラと車も好きです。そこらへんについて、たまに記事を書きます。

unityでpid制御(車編)_下準備

こんにちは。
今回は、久しぶりにunityでの記事を書きたいと思います。
テーマは、pid制御です。
pid制御といえば、フィードバック制御のひとつで有名ですね。
目標値と現在値の差分をProportional(比例)-Integral(積分)-Differential(微分)して制御する方法です。
今回は、下準備ということで、準備だけなのですが、近日中に制御までする記事を上げたいと思っています。
それでは書いていきます!

サーキットを作る

今回pid制御する対象が車ということで、それ用のサーキットを作りたいと思います。
本当は、テレインを置くだけでも良かったのですが、なんかサーキットがあったほうがよくない?って思ったので作りました。
fusion360というソフトで作ったものが以下のものになります。
f:id:SaidaTaisei:20191109101116p:plain
まあ、よくある感じのやつですね。
本当は、もっと凝ったものを作ろうかとも思ったのですが、面倒だったので止めました。
これを、unityで取り込むと、以下の写真のようになります。
そのままドラッグ&ドロップしただけです。
あ、ついでに、色を変えたような気もします。
f:id:SaidaTaisei:20191109102435p:plain

車を読み込む

車はunityのstandardassetsのものを使います。
このレベルのものが無料であるのはうれしいですね。
stanndardassets?ってなる方は、unityエディタでassetstoreを開いて、検索すると下の写真のものがあると思うので、それをimportすれば大丈夫です。
f:id:SaidaTaisei:20191109103244p:plain

いい感じに配置する

先ほどまでの作業で、サーキットと車は準備されたはずなので、それをいい感じの大きさにして、いい感じに配置します。
適当にやれば大丈夫です。
そしたら、サーキットのほうのオブジェクトにmeshcolliderをaddcompornentします。
これをしとかないと、車がすり抜けてしまうので、必ずつけましょう。
それで、あとは、スタートをおしたら、以下のようになりました。
f:id:SaidaTaisei:20191109111436p:plain
こうなれば、もうキーボード操作で車を走らせることができるはずです。
試しにやってみると動きました。

コースの線を引く

上の作業までで車をキーボードでは動かせるのですが、今回のテーマはpid制御ということで、目標となるコースに線を引きます。
まあ、線は書いても書かなくてもいいのですが、書いたほうが見やすいので、書いておきます。
適当に、コースとなりそうな場所に空のゲームオブジェクトを手動で配置し、それを一つのオブジェクトの子オブジェクトにしておきます。
あとは、以下のスクリプトをアタッチして、line_objectにその親となったオブジェクトを入れます。

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

public class create_line : MonoBehaviour
{
    public GameObject line_object;
    private List<Vector3> line_list;
    // Start is called before the first frame update
    void Start()
    {
        line_list = child_get_position(line_object);
        line(line_list);
    }

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

    //単純にリストの座標値にラインを引きます
    private void line(List<Vector3> target)
    {
        // オブジェクトの作成
        GameObject newObj = new GameObject();
        newObj.transform.parent = transform;
        // ラインの作成
        LineRenderer newLine = new LineRenderer();
        newLine = newObj.AddComponent<LineRenderer>();
        newLine.SetWidth(0.3f, 0.3f);
        newLine.SetVertexCount(target.Count+1);
        for (int i = 0; i < target.Count; i++)
        {
            newLine.SetPosition(i, target[i]);
            if (i == target.Count - 1)
            {
                Debug.Log(i);
                newLine.SetPosition(i+1, target[0]);
            }
        }
    }
    //ゲームオブジェクトを入れるとその子オブジェクトのポジションをリストにして返します。
    private List<Vector3> child_get_position(GameObject gobject)
    {
        List<Vector3> list = new List<Vector3> { };

        foreach (Transform n in gobject.transform)
        {
            list.Add(n.transform.position);
        }

        return list;
    }
}

これで、実行すると、下の画像のように線が描けるはずです。
f:id:SaidaTaisei:20191113175258p:plain
今日は、ここで終わります。
続編はできるだけ早く上げたいと思います。