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

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

新規登録して質問してみよう
ただいま回答率
85.50%
C#

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

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

Q&A

解決済

2回答

3586閲覧

マリ〇ギャラクシーのように下方向ではなくある物体に対して重力が働いている状況下でキャラを歩かせたい

zenobread

総合スコア44

C#

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

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

0グッド

9クリップ

投稿2019/07/10 13:57

編集2019/07/16 13:34

ざっくりまとめるとタイトルに含まれているゲームのように、通常ゲームでは下に向かって重力が働いていますが
今回は惑星に対して重力を働かせてその重力に従いキャラを歩かせようと考えています。

重力の向きを変更することには成功しましたが、キャラの足が常に地面に向かうようにベクトルを操作することが出来ません。

やったこと
1キャラクターをLookAtで惑星に常に向かせる
→キャラの3Dモデルの向きがy軸方向に設定されており、つまりは体全体が惑星に向かって向いていてよこだおしになっている状態
2LookAtを消しキャラクターの向きベクトルを取得、そののち向きベクトルとキャラクターにかかる重力ベクトルの内積を0にさせる
→キャラを立たせることが出来たが実際に動かした時惑星ではなく、Unityの通常の重力に従って動きなおかつキャラの足先が惑星の方へ向かなくなったため失敗

結論 やりたいこと
キャラクターが惑星の重力に従ってスムーズに動いているように見せたい

下記はキャラクターについているスクリプトです。

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class BearAnimConScp : MonoBehaviour 6{ 7 private static float G= 6.67259f; 8 Rigidbody br_body, sp_body;//キャラと惑星のRigidBoody 9 public GameObject Sphere;//惑星 10 Vector3 dir, heading,go_dir; 11 float speed = 5.0f; 12 float angleDir,x_dir; 13 // Start is called before the first frame update 14 void Start() 15 { 16 sp_body = GetComponent<Rigidbody>(); 17 br_body= GetComponent<Rigidbody>(); 18 19 x_dir = go_dir.x * heading.x+go_dir.y*heading.y+go_dir.z*heading.z;//内積0を求めている 20 } 21 22 // Update is called once per frame 23 void Update() 24 { 25 angleDir = transform.eulerAngles.z * (Mathf.PI / 180.0f); 26 go_dir = new Vector3(Mathf.Cos(angleDir), Mathf.Sin(angleDir), 0.0f);//キャラクターの向きベクトル 27 28 heading = (Sphere.transform.position - this.transform.position) / 1; 29 dir = G * heading.normalized * (sp_body.mass * br_body.mass) / (heading.sqrMagnitude);//重力計算 30 31 br_body.AddForce(dir);//重力実行 32 33 if (Input.GetKey("up")) 34 { 35 transform.position += transform.up * speed * Time.deltaTime; 36 } 37 if (Input.GetKey("down")) 38 { 39 transform.position -= transform.up * speed * Time.deltaTime; 40 } 41 if (Input.GetKey("right")) 42 { 43 transform.position += transform.right * speed * Time.deltaTime; 44 } 45 if (Input.GetKey("left")) 46 { 47 transform.position -= transform.right * speed * Time.deltaTime; 48 } 49 } 50} 51

どうかよろしくお願いいたします。

編集
惑星の上をキャラクターが歩くことまではできました。
ただ右左の矢印キーを押すとカメラが一瞬おかしくなってしまうことが悩みです。

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class BearAnimConScp : MonoBehaviour 6{ 7 private static float G= 6.67259f; 8 Rigidbody br_body, sp_body; 9 public GameObject Sphere; 10 Vector3 dir, heading,go_dir; 11 float speed = 15.0f; 12 float angleDir,x_dir; 13 private Vector3 move; 14 private Vector3 mir_move; 15 // Start is called before the first frame update 16 void Start() 17 { 18 sp_body = GetComponent<Rigidbody>(); 19 br_body= GetComponent<Rigidbody>(); 20 move = new Vector3(0,0,0); 21 mir_move = -move; 22 } 23 24 // Update is called once per frame 25 void Update() 26 { 27 if (Input.GetKey("up")) 28 { 29 transform.position += transform.forward * speed * Time.deltaTime; 30 move+= transform.forward * speed * Time.deltaTime; 31 transform.rotation = Quaternion.LookRotation(-dir, -move) * Quaternion.FromToRotation(Vector3.up, Vector3.forward); 32 } 33 if (Input.GetKey("down")) 34 { 35 transform.position -= transform.forward * speed * Time.deltaTime; 36 move-= transform.forward * speed * Time.deltaTime; 37 transform.rotation = Quaternion.LookRotation(-dir, -this.transform.forward) * Quaternion.FromToRotation(Vector3.up, Vector3.forward); 38 } 39 if (Input.GetKey("right")) 40 { 41 transform.position += transform.right * speed * Time.deltaTime; 42 move+= transform.right * speed * Time.deltaTime; 43 transform.rotation = Quaternion.LookRotation(this.transformm.forward, -dir) * Quaternion.FromToRotation(Vector3.up, Vector3.right); 44 } 45 if (Input.GetKey("left")) 46 { 47 transform.position -= transform.right * speed * Time.deltaTime; 48 move-= transform.right * speed * Time.deltaTime; 49 transform.rotation = Quaternion.LookRotation(this.transform.forward,-dir) * Quaternion.FromToRotation(Vector3.up, Vector3.left); 50 } 51 52 if (!Input.anyKeyDown) 53 { 54 move = new Vector3(0, 0, 0); 55 transform.rotation = Quaternion.LookRotation(-dir, -this.transform.forward) * Quaternion.FromToRotation(Vector3.up, Vector3.forward); 56 } 57 58 heading = (Sphere.transform.position - this.transform.position) / 1; 59 dir = G * heading.normalized * (sp_body.mass * br_body.mass) / (heading.sqrMagnitude); 60 br_body.AddForce(dir*20); 61 } 62} 63

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

どっかで記事を見かけたのですが、忘れてしまったので参考になりそうなサイトをご紹介しておきます

惑星から万有引力を受ける物体をUnity上で実装
https://qiita.com/kugipanti/items/ad538a937118822c773c

Unity:重力に逆らい、球面にそって垂直に歩かせてみる
https://indie-du.com/entry/2017/01/24/200000

Unity 星の上を歩く~完成編~
http://manakel.hatenablog.com/entry/2015/10/30/220716

その16 オブジェクトを任意の平面に立たせる姿勢制御
http://marupeke296.com/DXG_No16_AttitudeControl.html

投稿2019/07/11 04:39

hogefugapiyo

総合スコア3302

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

zenobread

2019/07/11 10:18

ありがとうございます。 個人的に考えてたよりもよっぽど複雑なのでしっかりと読ませていただきます。もし成功したらまた変身させていただきます。
guest

0

・キャラの姿勢
キャラが立っているなら、必ず頭が上にないといけません
常に重力の反対が上になるように、キャラを回転させてください
前は、前回の移動方向をもとにいい感じの場所でいいでしょう

そこで、LookRotationを使うのが便利です
これは前方向を固定、上方向は指定ベクトルを元にいい感じ、というものです
欲しいのは上が絶対、前がいい感じなので、
LookRotationに上、後ろの順で指定して、上が前になるよう回転させます

Quartanion.LookRotation(-gravity, -move) * Quartanion.FromToRotation(Vector3.up, Vector3.forward);

・移動方向
上キーを押したら移動するのは画面の上に位置する方向だと思うので、
カメラの上を基準に重力と垂直方向になる方向を求める必要があります。
キャラの姿勢に書いた方法を応用して求めてください。

・物理挙動
Unityは平面を元にした物理挙動を想定しているので、球面世界とは相性がどうなのかわかりません
それに、マリオギャラクシーはゲームにするために物理挙動に嘘を紛れ込ませています
場合によってはこのあたりを自作する必要があるかもしれません

投稿2019/07/11 03:15

編集2019/07/11 10:22
izmktr

総合スコア2856

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

zenobread

2019/07/11 10:18

ご回答ありがとうございます。 早速Quartanionに関してスクリプトリファレンスを見たのですがLookAtやRotateを変数にとっていないようです。もしくは何か特別なことが必要であればお教えください。 物理挙動に嘘が隠れているというお話は友達からも少し聞きました。 ちょっとUnityでこのゲームを開発するのを考えてみようかと思います。
izmktr

2019/07/11 10:22

すいません、関数名間違っていたみたいです 解答の方修正しました
zenobread

2019/07/11 11:28

実践してみたところ、キャラクターが小刻みに右左に体を振ってしまう特殊な軌道をしてしまっています。その後Unity自体がフリーズしてしまったので作業を再開次第お話しさせていただきます。
izmktr

2019/07/11 11:42

moveには0ベクトルを入れず、止まっているときは最後の移動方向を入れてください
zenobread

2019/07/11 23:41

移動方向のベクトルをどう表現すればいいのか分からず、現在GetKeyで transform.position+=transform.forward*5*Time.deltaTime; というふうに移動しているのでmoveにはtransform.positionを代入しているのですがあっていますか?
izmktr

2019/07/12 01:07

駄目です 移動方向とは今の座標=前の座標+移動方向 で使った移動方向です ただ、止まっているときは0ベクトルなのでその場合は更新しないとします
zenobread

2019/07/16 05:08

ありがとうございます。かなり自分の望んだものに近づいたのですが、キャラクターが最初の地点から球面のちょうど反対側に来た時キャラクターがその場でぐるぐる回ってしまう挙動を取ってしまいます。これについて今現在考えております。
izmktr

2019/07/16 05:21

キャラは前向きにのみ移動するので、移動方向とはキャラの向きの事です キャラの向きは重力に対して垂直でないといけません ところが、キャラの向きが重力と平行(同一直線)に近くなると、向きが決められずそのような挙動を示します 問題が起こるのなら、移動方向ではなく向かせたいキャラの向きとして、重力とキャラの向きが正しく設定されているか確認してください
zenobread

2019/07/16 13:33

おかげさまでほぼ完成まで近づきました。そこまでのコードを質問板に貼りますのでどうかご確認ください。 ただ左右の矢印キーを押すとカメラが一瞬おかしな方向を向いてしまうことが最後の悩みです。 長々と申し訳ありませんがあともう少しだけお付き合いくださいませ。
izmktr

2019/07/17 01:10

カメラがおかしくなるのなら、カメラの位置か向きがおかしいので、そのコードを調べましょう
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問