(この記事の使用環境: Unity2017.1.0b8 Personal, C#, Visual Studio Community 2017, Windows10


今回はCubeを転がしてみました。
unityroom様が開催している「Unity 1週間ゲームジャム」、先月のお題が「転がる」だったので、転がしていた方がいらっしゃいましたね。

自分でも試してみたのですが、思ったよりも苦戦しました。結局、下記の参考文献を強く参考にさせてもらって完成させました。

■ 参考文献
Cubeを接地した状態で回転させる方法について - Qiita
http://qiita.com/mao_/items/3ff84277f036afaec183



自分で作ってみたものはこんな感じ。



スクリプトはこんな感じ。
positionとrotationのズレが累積されていくのを防ぐために位置調整処理を入れています。
(追記: rotationの微調整がうまく機能していなかったので、強制的にリセットする処理に変更しました。残念)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;


///<summary>
///Cube(立方体)を回転させるスクリプト
///</summary>
public class CubeController : MonoBehaviour
{
    // === 外部パラメーター(インスペクター表示)=============================

    public int rotatingSpeed;


    // === 内部パラメーター ==================================================

    int rotatingAngleMax = 90;
    int rotatingAngle = 0;

    Vector3 side;           // 回転の中心座標(Cubeの辺のいずれか)
    Vector3 axis;           // 回転方向を定める軸

    Vector3 halfScale;      // Cubeの半分のスケール

    bool rotating = false;  // 回転中か否か


    // === コード(MonoBehaviour基本機能の実装)==============================

    private void Awake ()
    {
        halfScale = transform.localScale / 2;
    }


    private void Update ()
    {
        if ( rotating )
        {
            Rotate ();
        }
        else
        {
            // 右に転がる
            if ( Input.GetAxis ( "Horizontal" ) > 0.5f )
            {
                side = transform.position + new Vector3 ( halfScale.x, -halfScale.y, 0 );
                axis = Vector3.back;
                rotating = true;
            }
            // 左に転がる
            else if ( Input.GetAxis ( "Horizontal" ) < -0.5f )
            {
                side = transform.position + new Vector3 ( -halfScale.x, -halfScale.y, 0 );
                axis = Vector3.forward;
                rotating = true;
            }
            // 前に転がる
            else if ( Input.GetAxis ( "Vertical" ) > 0.5f )
            {
                side = transform.position + new Vector3 ( 0, -halfScale.y, halfScale.z );
                axis = Vector3.right;
                rotating = true;
            }
            // 後ろに転がる
            else if ( Input.GetAxis ( "Vertical" ) < -0.5f )
            {
                side = transform.position + new Vector3 ( 0, -halfScale.y, -halfScale.z );
                axis = Vector3.left;
                rotating = true;
            }
        }
    }


    ///<summary>回転する</summary>
    void Rotate ()
    {
        rotatingAngle += rotatingSpeed;

        if ( rotatingAngle >= rotatingAngleMax )
        {
            rotatingAngle = 0;
            AdjustPosition ();
            rotating = false;
            return;
        }

        transform.RotateAround ( side, axis, rotatingSpeed );
    }


    ///<summary>回転終了時に position と rotation を微調整する</summary>
    void AdjustPosition ()
    {
        transform.position = new Vector3 (
            Mathf.Round ( transform.position.x * 10 ) / 10,
            Mathf.Round ( transform.position.y * 10 ) / 10,
            Mathf.Round ( transform.position.z * 10 ) / 10 );

        transform.rotation = Quaternion.Euler ( 0, 0, 0 );  // 修正版:強制的に回転をリセットする

        /*
        transform.rotation = Quaternion.Euler(
            Mathf.Round ( transform.rotation.eulerAngles.x / 10 ) * 10,
            Mathf.Round ( transform.rotation.eulerAngles.y / 10 ) * 10,
            Mathf.Round ( transform.rotation.eulerAngles.z / 10 ) * 10 );
        */
    }
}


今回は以上です。
(管理情報: MyUnityData\MyProjects\3D_Test\Unity2017_1_0_b8_Test