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

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

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

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

Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

Unity

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

Q&A

解決済

1回答

551閲覧

3Dゲームでバイオハザードと同じ様な操作を(自機に)したい。

nissei

総合スコア35

C#

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

Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

Unity

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

0グッド

1クリップ

投稿2017/07/05 15:52

編集2017/07/05 15:54

・カメラの位置は自機の頭部の少し後ろ上に固定。
・カメラのポジションはxとy軸のみ変更可能。
・W,S,A,Dのそれぞれのキーで前進、後退、左移動、右移動。

上記の三点を行いたいのですが上手くいきません。
地面の凹凸に接触すると自機がまるで球体の様に転がってしまします。

スクリプトは二枚に分けてます。
ちなみにメインカメラは空のオブジェクトに子オブジェクトとして親子関係にし、自機にくっつけています。

自分なりに書いたコードを添付します。どこが致命的に間違っていて、改善及び変更すればいいのか教えていただきたいです!

< ↓ コード ↓ >
スクリプトその1
//自機の移動
public class Player : MonoBehaviour {

public float speed; // Use this for initialization void Start () { } // Update is called once per frame void Update () { var vec = Vector3.zero; if (Input.GetKey(KeyCode.W)) vec.z += 1.0f; if (Input.GetKey(KeyCode.S)) vec.z -= 1.0f; if (Input.GetKey(KeyCode.A)) vec.x -= 1.0f; if (Input.GetKey(KeyCode.D)) vec.x += 1.0f; vec = vec.normalized; transform.position += vec * Time.deltaTime * speed; if(vec.magnitude > 0.0f) { transform.rotation = Quaternion.LookRotation(vec); } }

}

< ↓ コード ↓ >
スクリプトその2
public class Player : MonoBehaviour {
// Use this for initialization
void Start () {

}

// Update is called once per frame
void Update () {
//視点の変更
if (Input.GetKey(KeyCode.UpArrow)) transform.Rotate(1.0f, 0, 0);
if (Input.GetKey(KeyCode.DownArrow)) transform.Rotate(-1.0f, 0, 0);
if (Input.GetKey(KeyCode.LeftArrow)) transform.Rotate(0, -1.0f, 0);
if (Input.GetKey(KeyCode.RightArrow)) transform.Rotate(0, 1.0f, 0);
}

以上です。宜しくお願い致します。

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

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

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

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

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

guest

回答1

0

ベストアンサー

凹凸に触れると転がる...という点を考慮しますと、Rigidbodyの設定がどうなっているか気になります。
もし、「Freeze Rotation」に何もチェックがないようでしたら、「X」と「Z」にチェックを入れてY軸周り以外の回転を禁止してみるとどうでしょうか。

[コメントを受けて追記]
どちらも自機にアタッチ...ですか?まだ全体の構造を把握しきれておりませんが、ちょっと私なりの方法で実験してみましたので追記します。おそらく質問者さんのオブジェクトの階層構造と違っている点があるかと思いますが、ここをこうしたいなどありましたらご指摘ください。

以下のようにオブジェクトを用意しました。

  • シーンの直下に空のオブジェクトを置く。名前は「PlayerAndCamera」とする。
  • PlayerAndCameraの下に「Player」を置く。原点はPlayerAndCameraと合わせる(ローカル座標がゼロ)。
  • PlayerAndCameraの下に「Camera」を置く。Playerの背中を映す位置にする(ローカル座標Zは-3)。
  • PlayerにSphere Colliderをアタッチする。オブジェクトの見た目と合うよう位置・サイズを調整する(Colliderは適宜質問者さんのプレイヤーオブジェクトに合わせて選定してください)。
  • PlayerAndCameraにRigidbodyをアタッチする。Freeze RotationはX・Y・Zすべてチェックする(物理シミュレーションによる回転の影響が及ぶといまいちな気がしたので、Yも回転禁止しました)。
  • スクリプトその1をPlayerAndCameraに、その2をCameraにアタッチする(ここは質問者さんの構成と違っていると思います)。
  • スクリプトその1のSpeedをとりあえず5とする。

C#

1// PlayerAndCameraにアタッチ、スクリプトその1と同等。 2// コードを自動整形した結果、ifにカッコが付いたりthisが増えたりしていますが、内容は同じです 3using UnityEngine; 4 5public class PlayerAndCameraController : MonoBehaviour 6{ 7 public float Speed; 8 9 private void Start() 10 { 11 } 12 13 private void Update() 14 { 15 var vec = Vector3.zero; 16 if (Input.GetKey(KeyCode.W)) 17 { 18 vec.z += 1.0f; 19 } 20 if (Input.GetKey(KeyCode.S)) 21 { 22 vec.z -= 1.0f; 23 } 24 if (Input.GetKey(KeyCode.A)) 25 { 26 vec.x -= 1.0f; 27 } 28 if (Input.GetKey(KeyCode.D)) 29 { 30 vec.x += 1.0f; 31 } 32 vec = vec.normalized; 33 this.transform.position += vec * Time.deltaTime * this.Speed; 34 if (vec.magnitude > 0.0f) 35 { 36 this.transform.rotation = Quaternion.LookRotation(vec); 37 } 38 } 39}

C#

1// Cameraにアタッチ、、スクリプトその2と同等。 2// コードを自動整形した結果、ifにカッコが付いたりthisが増えたりしていますが、内容は同じです 3using UnityEngine; 4 5public class CameraController : MonoBehaviour 6{ 7 private void Start() 8 { 9 } 10 11 private void Update() 12 { 13 if (Input.GetKey(KeyCode.UpArrow)) 14 { 15 this.transform.Rotate(1.0f, 0, 0); 16 } 17 if (Input.GetKey(KeyCode.DownArrow)) 18 { 19 this.transform.Rotate(-1.0f, 0, 0); 20 } 21 if (Input.GetKey(KeyCode.LeftArrow)) 22 { 23 this.transform.Rotate(0, -1.0f, 0); 24 } 25 if (Input.GetKey(KeyCode.RightArrow)) 26 { 27 this.transform.Rotate(0, 1.0f, 0); 28 } 29 } 30}

これで実行すると、下図のようになりました。

実行図1

確かにカメラはプレイヤーに追従しますが、常にプレイヤーの背後へ視点が飛んでめまぐるしい点と、矢印キーでカメラを動かすとカメラを振るような動きになり、プレイヤーをカメラ中心に捉えられない点がいまいちに感じましたので、両スクリプトを下記のように変更しました。

C#

1// 最後の向き設定の部分を、PlayerAndCamera全体ではなくPlayerだけを回転させるように変更 2using UnityEngine; 3 4public class PlayerAndCameraController : MonoBehaviour 5{ 6 public float Speed; 7 private Transform playerTransform; 8 9 private void Start() 10 { 11 // Start内でPlayerのtransformを探しておく 12 this.playerTransform = this.transform.Find("Player"); 13 } 14 15 private void Update() 16 { 17 var vec = Vector3.zero; 18 if (Input.GetKey(KeyCode.W)) 19 { 20 vec.z += 1.0f; 21 } 22 if (Input.GetKey(KeyCode.S)) 23 { 24 vec.z -= 1.0f; 25 } 26 if (Input.GetKey(KeyCode.A)) 27 { 28 vec.x -= 1.0f; 29 } 30 if (Input.GetKey(KeyCode.D)) 31 { 32 vec.x += 1.0f; 33 } 34 vec = vec.normalized; 35 this.transform.position += vec * Time.deltaTime * this.Speed; // もしこのスクリプトをPlayerAndCameraではなくPlayerにアタッチする場合、回転部分には修正を加えず、ここの移動部分を親(つまりPlayerAndCamera)を対象にするよう修正すればいけると思います 36 if (vec.magnitude > 0.0f) 37 { 38 // 自身のtransformに代わり、playerTransformを回転させる 39 this.playerTransform.rotation = Quaternion.LookRotation(vec); 40 } 41 } 42}

C#

1// RotateをRotateAroundに変更 2using UnityEngine; 3 4public class CameraController : MonoBehaviour 5{ 6 private Transform playerTransform; 7 8 private void Start() 9 { 10 // Start内でPlayerのtransformを探しておき、そこを中心にRotateAroundで回転する 11 this.playerTransform = transform.parent.Find("Player"); 12 } 13 14 private void Update() 15 { 16 // RotateAroundの回転軸は水平回転はワールドY軸、垂直回転はローカルX軸としました 17 // 一般的な地上を舞台にしたゲームならこれが妥当かと思いますが、たとえば宇宙空間を飛び回るような場合は両方ローカル軸にしても面白いかもしれません 18 // いろいろ軸をいじってみて、質問者さんのゲームに合った設定にしてみてください 19 if (Input.GetKey(KeyCode.UpArrow)) 20 { 21 this.transform.RotateAround(this.playerTransform.position, transform.right, 1.0f); 22 } 23 if (Input.GetKey(KeyCode.DownArrow)) 24 { 25 this.transform.RotateAround(this.playerTransform.position, transform.right, -1.0f); 26 } 27 if (Input.GetKey(KeyCode.LeftArrow)) 28 { 29 this.transform.RotateAround(this.playerTransform.position, Vector3.up, 1.0f); 30 } 31 if (Input.GetKey(KeyCode.RightArrow)) 32 { 33 this.transform.RotateAround(this.playerTransform.position, Vector3.up, -1.0f); 34 } 35 } 36}

これで実行すると、下図のようになります。

実行図2

さらに、移動部分をカメラローカル軸を基準に移動するように改造すれば、カメラの向きに対する前後左右に移動することも可能かと思います。

C#

1// 移動方向をCameraのtransformのright(ローカルX+)とforward(ローカルZ+)を基準にするよう変更 2using UnityEngine; 3 4public class PlayerAndCameraController : MonoBehaviour 5{ 6 public float Speed; 7 private Transform cameraTransform; 8 private Transform playerTransform; 9 10 private void Start() 11 { 12 // Start内でPlayerに加えCameraのtransformを探しておく 13 this.playerTransform = this.transform.Find("Player"); 14 this.cameraTransform = this.transform.Find("Camera"); 15 } 16 17 private void Update() 18 { 19 var u = 0.0f; 20 var v = 0.0f; 21 if (Input.GetKey(KeyCode.W)) 22 { 23 v += 1.0f; 24 } 25 if (Input.GetKey(KeyCode.S)) 26 { 27 v -= 1.0f; 28 } 29 if (Input.GetKey(KeyCode.A)) 30 { 31 u -= 1.0f; 32 } 33 if (Input.GetKey(KeyCode.D)) 34 { 35 u += 1.0f; 36 } 37 // カメラローカル軸を基準に方向を決め、Y軸を潰して正規化しXZ平面上の方角にして、これをvecとする 38 var dir = (this.cameraTransform.right * u) + (this.cameraTransform.forward * v); 39 var vec = new Vector3(dir.x, 0.0f, dir.z).normalized; 40 this.transform.position += vec * Time.deltaTime * this.Speed; 41 if (vec.magnitude > 0.0f) 42 { 43 this.playerTransform.rotation = Quaternion.LookRotation(vec); 44 } 45 } 46}

これで実行したらこうなりました。実際にプレイしないと違いが分かりにくいかもしれません...

実行図3

いかがでしょうか?ご参考になりましたらさいわいです。

投稿2017/07/05 22:19

編集2017/07/06 14:36
Bongo

総合スコア10807

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

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

nissei

2017/07/06 12:53

0 凹凸の点はご指摘のとおりで改善しました!ありがとうございます!! 逆にこれをプログラムで制御するにはどうしたらいいんでしょうか?? あと自機の移動も上手くいきません(><;
nissei

2017/07/06 15:36

これまたご丁寧にありがとうございます! 初心者の私を充分に理解した上で判りやすい様にわざわざ画像までつけてくれてありがとうございます!! カメラと視点に関しては何とかなりました。 あとは自機のコントロールの方をもう少し模索してみます!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問