三角関数を使って円運動の軌道を変え続ける


三角関数を使って Unity で円運動の軌道を変え続ける

今回使用した環境は

windows 11
Unity 2020.3.16f1
Visual Studio Community 2022 v17.1.2

です。

初めに

今回、三角関数を少し勉強したので、それを記事にしたいと思います。

やりたい事は、昔、Windows Media Player であった円運動の軌道を変え続けるエフェクトの作成です。

Mathf でサインを取得する

ご存じかも知れませんが、Unity の Mathf 関数ではサインとコサインを取得できます。

以下に UI.Image をアタッチさせたオブジェクトを揺らすコードを書きます。

RectTransform rt;
void Start()
{
    rt = GetComponent<RectTransform>();
}

void Update()
{
    float sin = Mathf.Sin(Time.time);
    rt.localPosition(0, sin, 0);
}

コサインを取得して円運動させる

ご存じの通り、ここにコサインを加えると、円運動が出来ます。

void Update()
{
    float sin = Mathf.Sin(Time.time);
    float cos = Mathf.Con(Time.time);
    rt.localPosition(cos, sin, 0);
}

円運動の速さと大きさを変える

この sin やら cos に倍率を掛けるとスピードや運動の大きさを変える事が出来ます。


public float moveSpeed;
public float moveVolume;

void Update()
{
    float sin = Mathf.Sin(Time.time * moveSpeed) * moveVolume;
    float cos = Mathf.Con(Time.time * moveSpeed) * moveVolume);
    rt.localPosition(cos, sin, 0);
}

円運動の軌道を変える

更に、時間をずらす事で円運動の軌道を変えられます。

public float essence;

void Update()
{
    float sin = Mathf.Sin(Time.time * moveSpeed) * moveVolume;
    float cos = Mathf.Con((Time.time - essence) * moveSpeed) * moveVolume);
    rt.localPosition(cos, sin, 0);
}

軌道を変化させ続ける

これを、軌道を変え続けるために、essence を変化させ続けます。
essenceShift の量は 0.01 が丁度良いかと思います。
moveSpeed は 15位が分かりやすく、
moveVolume は Canvas の大きさによって違いますが、初期設定
(Canvas - Screen Space -Overlay,
MainCamera - Projection : Orthographic, Size : 5)だと 50 位が丁度良いと思います。

CircularMotionShifter
private float essence;
public float essenceShift;
bool canShift = true;
void Update()
{
    float sin = Mathf.Sin(Time.time * moveSpeed) * moveVolume;
    float cos = Mathf.Con((Time.time - essence) * moveSpeed) * moveVolume);

    if((sin % moveVolume > (moveVolume * 0.9) && canShift){
        essence += essenceShift;
        canShift = false;
    {
    else if(sin < 0)
    {
        canShift = true;
    }


    rt.localPosition(cos, sin, 0);
}

完成したコード

完成したソースコードは以下になります。

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

public class RotationTest : MonoBehaviour
{
    RectTransform rt;
    public int speed;
    public int moveSpeed;
    public int moveVolume;
    private float essense = 0;
    public float essenseShift;
    bool canShift = true;

    // Start is called before the first frame update
    void Start()
    {
        rt = GetComponent<RectTransform>();
    }

    // Update is called once per frame
    void Update()
    {
        float sin = Mathf.Sin(Time.time * moveSpeed) * moveVolume;
        float cos = Mathf.Cos((Time.time - essense) * moveSpeed) * moveVolume;

        Debug.Log(sin);
        if(sin % sinPower > (sinPower * 0.9) && canShift)
        {
            essense += essenseShift;
            canShift = false;
        }
        else if(sin < 0){
            canShift = true;
        }

        rt.localPosition = new Vector3(cos, sin, 0);
    }
}

スイッチの仕方が糞仕様ですが、とりあえずこれにてメモとします。

sin 関数の使い方に関しては以下のページにお世話になりました。
Sin関数の使い方

また、三角関数については「数学ガールの秘密ノート-丸い三角関数(結城浩著)」
にお世話になりました。