0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Unityで回転させたかっただけなのに結構大変だったお話

Posted at

(´・ω・)「矢印キーで回転する3Dオブジェクトを作りたいんだけどどうすれば良い?」

と聞かれたので、実際にサンプルを作ってみることにした。

矢印キーで回転する3Dオブジェクトを作る

オブジェクトをつくろう!

まずはヒエラルキータブの上で右クリック→「3D Object」→「Cube」で箱を作る。
blog1.PNG

回転しているのがわかりやすいようにインスペクタタブでScaleを適当に調整する。
blog2.PNG

以下のようなオブジェクトができるはず。
blog3.PNG

スクリプトをつくろう!

Assetsの中にScriptというフォルダを作って、「Create」→「C# Script」でスクリプトファイルを作成する。
blog5.PNG

矢印キーを押下したら90度ずつ回転するようにするようにUpdateメソッド内に実装する。

CubeKaiten.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

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

    // Update is called once per frame
    void Update()
    {
        // ↑キー押下時
		if (Input.GetKeyDown(KeyCode.UpArrow)) {
			transform.Rotate(new Vector3(0f, 0f, 90f));
        }
        // ↓キー押下時
		if (Input.GetKeyDown(KeyCode.DownArrow)) {
			transform.Rotate(new Vector3(0f, 0f, -90f));
        }
        // →キー押下時
		if (Input.GetKeyDown(KeyCode.RightArrow)) {
			transform.Rotate(new Vector3(90f, 0f, 0f));
        }
        // ←キー押下時
		if (Input.GetKeyDown(KeyCode.LeftArrow)) {
			transform.Rotate(new Vector3(-90f, 0f, 0f));
        }
    }
}

アタッチして動かそう!

先ほど作ったスクリプトを作ったオブジェクトにアタッチして動かしてみる。
image1.gif

これでどうだ!

(´・ω・)「カクカク回転じゃなくて滑らかに回転して欲しいなぁ」

と言われたのでもう一度考え直す・・・・。

3Dオブジェクトを滑らかに回転させる

スクリプトを修正する

先ほどのスクリプトでは一気に90度回ってしまうため2度ずつ45回にかけて回るようにスクリプトを修正する。

CubeKaiten.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

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

    // Update is called once per frame
    void Update()
    {
        // ↑キー押下時
		if (Input.GetKeyDown(KeyCode.UpArrow)) {
			Animation(new Vector3(0f, 0f, 2f));
        }
        // ↓キー押下時
		if (Input.GetKeyDown(KeyCode.DownArrow)) {
			Animation(new Vector3(0f, 0f, -2f));
        }
        // →キー押下時
		if (Input.GetKeyDown(KeyCode.RightArrow)) {
			Animation(new Vector3(2f, 0f, 0f));
        }
        // ←キー押下時
		if (Input.GetKeyDown(KeyCode.LeftArrow)) {
			Animation(new Vector3(-2f, 0f, 0f));
        }
    }
    
    // 2度ずつ回転を45回行う
    private void Animation(Vector3 angle) {
    	for(int i=0; i<45; i++){
    		transform.Rotate(angle);
    	}
    }
    
}

保存し再度動かしてみる。

image2.gif

(´・ω・)「さっきと変わってないやん!!」

なんでこれだとダメなのか?

Update()メソッドは毎フレームごとに呼ばれる。
つまり45回for文で回したとしても、一瞬で終わってしまう。
というわけで、再度考え直し・・・。

CubeKaiten.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CubeKaiten : MonoBehaviour
{

	// アニメーション中かどうか
    bool isAnimate;
    // 回転の角度
    Vector3 angle;
    // 回転回数
    int count;

    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
    	// アニメーションを行うかの判定
    	if (isAnimate) {
			Animation();
		}
    
        // ↑キー押下時
		if (Input.GetKeyDown(KeyCode.UpArrow)) {
			isAnimate = true;
			angle = new Vector3(0f, 0f, 2f);
			count = 0;
        }
        // ↓キー押下時
		if (Input.GetKeyDown(KeyCode.DownArrow)) {
			isAnimate = true;
			angle = new Vector3(0f, 0f, -2f);
			count = 0;
        }
        // →キー押下時
		if (Input.GetKeyDown(KeyCode.RightArrow)) {
			isAnimate = true;
			angle = new Vector3(2f, 0f, 0f);
			count = 0;
        }
        // ←キー押下時
		if (Input.GetKeyDown(KeyCode.LeftArrow)) {
			isAnimate = true;
			angle = new Vector3(-2f, 0f, 0f);
			count = 0;
        }
    }
    
    // 2度ずつ回転を45回行う
    private void Animation() {
    	
    	transform.Rotate(angle);
    	count++;
    	
		// 45回回ったら終了
		if(count == 45) {
    		isAnimate = false;
    	}
    }    
}

矢印キー押下でAnimationを呼び出し、45回回ったらAnimationを終了させるという風に書いてみた。

これでどうだ!

image3.gif

(´・ω・)「滑らかになったー!けど回る方向が途中でおかしくなるぞ!」
(↑だと分かりにくいですが、実際に動かすと時々逆回転します)

ワールド座標とローカル座標

色々調べていると、ワールド座標とローカル座標というのにたどり着いた。
ワールド座標は原点から見た座標になり、ローカル座標は親オブジェクトからの座標になる。

ということは、回すときにワールド座標を基準とすればうまくいくのではないかと思い、修正。

CubeKaiten.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CubeKaiten : MonoBehaviour
{

	// アニメーション中かどうか
    bool isAnimate;
    // 回転の角度
    Vector3 angle;
    // 回転回数
    int count;

    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
    	// アニメーションを行うかの判定
    	if (isAnimate) {
			Animation();
		}
    
        // ↑キー押下時
		if (Input.GetKeyDown(KeyCode.UpArrow)) {
			isAnimate = true;
			angle = new Vector3(0f, 0f, 2f);
			count = 0;
        }
        // ↓キー押下時
		if (Input.GetKeyDown(KeyCode.DownArrow)) {
			isAnimate = true;
			angle = new Vector3(0f, 0f, -2f);
			count = 0;
        }
        // →キー押下時
		if (Input.GetKeyDown(KeyCode.RightArrow)) {
			isAnimate = true;
			angle = new Vector3(2f, 0f, 0f);
			count = 0;
        }
        // ←キー押下時
		if (Input.GetKeyDown(KeyCode.LeftArrow)) {
			isAnimate = true;
			angle = new Vector3(-2f, 0f, 0f);
			count = 0;
        }
    }
    
    // 2度ずつ回転を45回行う
    private void Animation() {
    	
    	transform.Rotate(angle,Space.World);
    	count++;
    	
		// 45回回ったら終了
		if(count == 45) {
    		isAnimate = false;
    	}
    }    
}

Animation()内のtransform.Rotateにangle,Space.Worldを引数で渡すように修正。

image4.gif

やったー!ちゃんと回したい方向に回るぞー!

でもこの3Dオブジェクトって親がいない気が・・・?ここが未だに解決できてないけど一旦やりたいことは出来た。回転させるのって結構大変・・。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?