質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.62%

  • C#

    6843questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

  • Unity

    3800questions

    Unityは、ユニティテクノロジーが開発したゲームエンジンです。 主にモバイルやブラウザ向けのゲーム製作に利用されていましたが、3Dの重力付きゲームが簡単に作成できることから需要が増え、現在はマルチプラットフォームに対応しています。 言語はC言語/C++で書かれていますが、C#、JavaScript、Booで書かれたコードにも対応しています。

【Unity】アバターの中心点を軸に回転させたい

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,803

sanset

score 159

Unityちゃんのアバターを使用してプログラミングをしております。

移動で、Unityちゃんを進行方向に向かって横(Z軸)に回転させるという動作を設けたいです。

if(360 > RotateValue){
RotateValue += 30;
}else{
RotateValue = 0;
}

transform.rotation = Quaternion.Euler(transform.localEulerAngles.x, transform.localEulerAngles.y, dashjumpRotate);transform.rotation = Quaternion.Euler(transform.localEulerAngles.x, transform.localEulerAngles.y, RotateValue);

上記のコードは、Unityちゃんを一回転させるものです。

このようにコードを設定すると回転できるのですが、回転軸がUnityちゃんの足元(?)にあって、Unityちゃんが画面から一瞬フェードアウトします。

説明が下手で申し訳ないですが、こちらのGIFを見ていただくと分かると思います。

GIF動画

リンク元:てんちょーの技術日誌様

Unityちゃんのアバターの中心を軸としたいのですが、GIFのような足を中心とした一回転となってしまいます。

このようなケースの対処法がわからず、こちらで相談した次第です。

お詳しい方、ご教示願えますでしょうか。

【追記】

親要素に空のゲームオブジェクトを設定した時の設定画面です。

スクショ1

スクショ2

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

よくあるやり方としては、新しく「GameObject」→「Create Empty」で空のオブジェクトを作り、ユニティちゃんをそのオブジェクトの中に入れ(ヒエラルキー上でユニティちゃんを新しいオブジェクトの子にする)、移動・回転させるときはその新しいオブジェクトの方を操作するという手があるかと思います。

参考: UnityでObjectのPivotを変更する - 脳汁portal

[追記]

下図のような、「プレイヤー操作用原点」→「Z軸周り回転用原点」→「ユニティちゃん」の三重構造にするのはどうでしょう。プレイヤー操作用原点は本来のユニティちゃんと同じく足下に位置するようにして、Z軸周り回転用原点をおヘソの位置に配置する感じです。

ヒエラルキー

本来のユニティちゃんの原点とプレイヤー操作用原点が一致するようにしておいて、CaracterControllerやプレイヤー制御用スクリプトはプレイヤー操作用原点にアタッチし、Z軸周り回転アクションだけはZ軸周り回転用原点を操作、それ以外はプレイヤー操作用原点を操作するようにすれば、今までの足下原点前提のコードを残したまま回転アクションを加えられるかと思います。

実行時の様子
アクション

ちなみにご参考までに、上図のプレイヤー操作用原点のスクリプトは下記のようになっています。ご質問者さんの設計とは異なる部分が多々あるかと思いますので、あまりお役に立てないかもしれませんが...

using System.Collections;
using System.Linq;
using UnityEngine;

[RequireComponent(typeof(CharacterController))]
public class PlayerController : MonoBehaviour
{
    public float MaxSpeed = 5.0f;
    public Animator PlayerAnimator; // ユニティちゃんのAnimator
    public Transform RotationPivot; // Z軸周り回転用原点
    private Transform cameraTransform; // 移動制御のためのカメラのTransform(今回の話題とは直接関係ありません)
    private CharacterController characterController; // プレイヤー操作用原点にアタッチされているCharacterController
    private Coroutine rollingCoroutine;

    // Z軸周り回転アクション
    private IEnumerator Roll()
    {
        var angle = 0.0f;
        while (angle < 360.0f)
        {
            this.RotationPivot.localEulerAngles = new Vector3(0.0f, 0.0f, angle); // Z軸周り回転はRotationPivotに関して行う
            angle += 30.0f;
            yield return null;
        }

        this.RotationPivot.localEulerAngles = Vector3.zero;
        this.rollingCoroutine = null;
    }

    private void Start()
    {
        this.characterController = this.GetComponent<CharacterController>();
        this.cameraTransform = Camera.main.transform;
        if (this.PlayerAnimator == null)
        {
            this.PlayerAnimator = this.GetComponentInChildren<Animator>();
        }
        if (this.RotationPivot == null)
        {
            this.RotationPivot = this.GetComponentsInChildren<Transform>()
                .Where(t => t.name == "RotationPivot")
                .First();
        }
    }

    private void Update()
    {
        // プレイヤーの移動
        var input = new Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"));
        var inputMagnitude = Mathf.Clamp01(input.magnitude);
        var right = this.cameraTransform.right;
        var forward = this.cameraTransform.forward;
        forward.y = 0.0f;
        forward.Normalize();
        var motion = ((input.x * right) + (input.y * forward)) * this.MaxSpeed;
        var speed = motion.magnitude;
        if (speed > 0.25f)
        {
            this.transform.rotation = Quaternion.LookRotation(motion); // 入力に対する向き合わせのための回転はプレイヤー操作用原点のTransformを操作する
        }
        this.characterController.SimpleMove(motion); // 移動はプレイヤー操作用原点のCharacterControllerを操作する
        this.PlayerAnimator.SetFloat("Speed", inputMagnitude); // アニメーションはユニティちゃんのAnimatorを操作する

        // スペースキー押下でZ軸周り回転アクション
        if ((this.rollingCoroutine == null) && Input.GetKeyDown(KeyCode.Space))
        {
            this.rollingCoroutine = this.StartCoroutine(this.Roll());
        }
    }
}

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/01/09 04:09

    ありがとうございます!
    こちらの方法も試して見たのですが、同じような回転になってしまいました。
    こ要素のユニティちゃんのpositionをずらすと、回転自体はうまくいっているように見えるのですが、ユニティちゃんが基本地面に埋まってしまいます・・・。
    何か根本的に間違っているのでしょうか?

    キャンセル

  • 2018/01/09 06:47

    うーん...具体的に言うと次のような感じでしょうか?

    - 空のGameObjectを作り、位置をユニティちゃんのおヘソあたりに移動する。
    - ユニティちゃんを空オブジェクトの子にする。
    - 回転させるスクリプトをユニティちゃん自体から空オブジェクトに付け替える(または、スクリプト中のtransform操作対象をユニティちゃん自身からその親オブジェクトに書き換える)。
    - プレイモードにしてみると、本来のユニティちゃんの原点(足下)に新しい親オブジェクトの原点が移動したようになり、結果的にユニティちゃんの下半身が地面に埋まる。

    回転自体がうまくいっているなら、あとは位置の制御をどうするかですね。スクリプト中で位置の移動に関わっている部分(transform.positionの書き換えなど)がありましたら、そちらもご提示いただけるとヒントになるかもしれません。
    思うに、この位置制御部分が、原点が足下にあることを前提としたコードになっているような気がします(移動時にY座標を強制的に地面の位置にする処理がある、など...原点が足下ならこれで正しくユニティちゃんが地面に立つが、おヘソを原点とすると、その位置が地面の位置に移動して埋まってしまう)。

    キャンセル

  • 2018/01/09 14:58

    Bongoさん、親身にご協力くださりありがとうございます...!
    仰る通り、位置制御部分は足元になっていると思います。
    確認はシーンビューのrotationのZを変更して確認していました。
    ただいま出先なので、戻り次第詳しい情報を追記させて頂きます。

    キャンセル

  • 2018/01/10 23:42

    遅れて申し訳ありません、詳しい情報を追記させていただきます。
    ・空のゲームオブジェクトにunityちゃんを子要素として移動
    ・元々unityちゃんでカメラ追従スクリプトや移動スクリプト(CharacterControllerコンポーネントを使用)を使用していたので、それらのスクリプトファイルを親要素に移行
    移動スクリプトには重力処理があるので、縦の位置調整(回転の中心)は子要素であるunityちゃんでしかできませんでした。
    なので、Bongoさんの仰った「移動時にY座標を強制的に地面の位置にする処理がある」がされております。
    ・unityちゃんの位置を-0.5あたりにすると原点から回転しているように見えますが、地面に埋まってしまいます。
    移動スクリプトはよくあるキャラクターコントローラーコンポーネントにmove関数を使う処理で、ジャンプなどを行うので重力計算も行なっています。
    いろいろモーションの処理が多くここで記述するとややこしくなるのですが、移動自体はこの動画のようなシンプルなものです。
    https://www.youtube.com/watch?v=miMCu5796KM
    設定の画像などを追記いたしますので、もしよろしければご確認いただけると幸いです。

    キャンセル

  • 2018/01/11 07:52

    Z軸周り回転だけを担当するオブジェクトを介在させた三重構造はどうでしょうか?回答に追記しました。

    キャンセル

  • 2018/01/12 02:57

    GIF動画から参考コードまで提供頂き、本当に感謝です...!
    アドバイスいただいた三重構造で、間に回転用のオブジェクトを挟み、移動スクリプトでそちらのratationを変更することで、理想の動作が実現できました!
    自分一人ではここまでたどり着けたかは定かではないので、teratailに相談して、Bongoさんという素晴らしい方に出会えたのは幸運です。
    感謝の形がベストアンサーくらいでしか示せないのがとても心苦しいですが、ここまで親身にアドバイスをして頂き本当にありがとうございます!

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.62%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • C#

    6843questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

  • Unity

    3800questions

    Unityは、ユニティテクノロジーが開発したゲームエンジンです。 主にモバイルやブラウザ向けのゲーム製作に利用されていましたが、3Dの重力付きゲームが簡単に作成できることから需要が増え、現在はマルチプラットフォームに対応しています。 言語はC言語/C++で書かれていますが、C#、JavaScript、Booで書かれたコードにも対応しています。