🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C#

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

Unity3D

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

Unity

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

Q&A

解決済

3回答

1805閲覧

追従しながらその追従しているオブジェクトを中心に一定の角度まで回転したい。(カメラ)

Um_kok

総合スコア39

C#

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

Unity3D

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

Unity

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

0グッド

0クリップ

投稿2021/01/19 08:47

こんにちは、只今ゲーム制作をしております。

カメラの移動について質問させていただきます。タイトルの通りですが、
フラグがたったら、カメラを動かしたいというものです。
コードです。

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class Camera : MonoBehaviour 6{ 7 8 // キャラクター 9 [SerializeField] private Transform target; 10 11 // カメラの高さ 12 [SerializeField, Range(1, 100)] 13 private float camHeight = 5.0f; 14 15 // キャラクターからの(Z軸における)距離 16 [SerializeField, Range(1, 100)] 17 private float camDistance = 5.0f; 18 19 20 public bool goalFlg; // ゴールしたか 21 private bool cameraMoveFlg; // カメラが移動したか 22 private int numberOfRotations = 0; // カメラを回転した数 23 private float cameraDistance; // カメラとプレイヤーの距離 24 private int count = 100; 25 26 27 28 void Update() 29 { 30 if (!goalFlg) {// ゴールしたか 31 32 PlayerCamera(); 33 } 34 else { 35 36 GoalAngleCamera(); 37 if (cameraMoveFlg) { 38 39 transform.position = target.position + (target.forward * cameraDistance); 40 transform.LookAt(target); 41 } 42 } 43 } 44 45 /// <summary> 46 /// プレイヤーを写すカメラ 47 /// </summary> 48 private void PlayerCamera() 49 { 50 // キャラクターの位置から距離分後ろに下がり、高さ分上にあがる処理 51 transform.position = target.position - (target.forward * camDistance) + new Vector3(0, camHeight, 0); 52 transform.LookAt(target); 53 } 54 /// <summary> 55 /// プレイヤーのゴール時、カメラを動かす 56 /// </summary> 57 private void GoalAngleCamera() 58 { 59 60 if (cameraMoveFlg) return; // カメラの移動が終わったら通らない 61 62 var rotate = 0.4f; // 回転する角度 63 64 65 // ここがおかしい 66 //Vector3 offset = target.position - transform.position; 67 //transform.position = transform.position + offset; 68 69 var targetPos = transform.position; 70 targetPos.y = target.position.y; 71 transform.position = targetPos; 72 73 74 75 76 77 Vector3 axis = transform.TransformDirection(target.transform.up); 78 transform.RotateAround(target.transform.position, axis, rotate); 79 80 81 82 numberOfRotations++; 83 if (numberOfRotations > count) { 84 85 cameraMoveFlg = true; 86 cameraDistance = Vector3.Distance(target.position, transform.position); 87 } 88 89 90 //var rot = Quaternion.AngleAxis(2, target.up); 91 //Quaternion q = this.transform.rotation; 92 //this.transform.rotation = q * rot; 93 } 94}

やった事

やりたい挙動としては、ゴールしてないときは後ろから追従しております。そして、ゴール時に target を中心にゆっくり回って、
一定の角度(インスペクタで設定)まで行ったら、そこで止まるというものです。ですが、targetを中心に回ることはできたのですが、追従の処理がうまくいきません。

C#

1//Vector3 offset = target.position - transform.position; 2 //transform.position = transform.position + offset;

距離を格納して、その距離のまま回転したいのですが、うまくいきません。
どうかお力添えお願いします。へたくそなコードを直したいです。

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

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

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

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

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

guest

回答3

0

ベストアンサー

CraftTableさんの回答にもありますが、sin cos使ってみました

イメージ説明

RotateTest.csをMainCameraに付けて、targetはcubeを指定しています
targetが移動しても常に中心に捉えつつ回転をしている感じになりました

C#

1public class RotateTest : MonoBehaviour { 2 public Transform target; 3 4 public float distance = 5; // targetとの距離 5 public float T = 3; // 何秒で1周するか 6 7 private void Update() { 8 float f = 1 / T; 9 10 float value = Time.time * 2 * Mathf.PI * f; 11 transform.position = target.position + new Vector3(Mathf.Sin(value), 0, Mathf.Cos(value)) * distance; 12 transform.LookAt(target); 13 } 14}

参考
【Unity】Sin関数の使い方
【Unity】Mathf.Sin、Mathf.Cosで任意の位置から円運動させる

投稿2021/01/21 18:27

lazh

総合スコア300

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

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

Um_kok

2021/01/22 00:58

ご回答ありがとうございます。 お返事遅れました。ご教示頂いたやり方で上手く行きました。 少し理解を深めるためにしつもんさせてください。 float f は割合を出しているのは分かるのですが、float value は何をやっているのか分かりません。もし宜しければ教えて貰えませんか?
Um_kok

2021/01/22 01:09

何となくは掴めたのですが、はっきりとは掴めていません。
lazh

2021/01/22 02:12 編集

float fは周波数ですね sin(x)の周期は2πなので2 * Mathf.PIをかけてます(?) https://ja.wikipedia.org/wiki/%E5%91%A8%E6%9C%9F%E9%96%A2%E6%95%B0#/media/%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB:Sine.svg お分かりの通り正直、ふわーーーーーとしか理解してないので、 参考のリンク先↓にvalueの内容の解説があるのでそちらを見てもらった方がいいかなと思います... 2 × Mathf.PI (π) https://qiita.com/Nekomasu/items/f526b9392fd16f2bd243#sin%E9%96%A2%E6%95%B0%E3%82%92%E8%87%AA%E7%94%B1%E3%81%AB%E5%88%B6%E5%BE%A1%E3%81%97%E3%81%9F%E3%81%84 それか「Sin Cos 円運動」で調べた方が理解を深めるのに断然良いと思います
Um_kok

2021/01/22 02:18

分かりました。自分でも調べて見ます。ありがとうございました。また分からないことがあれば、宜しくお願いします。
guest

0

回答依頼ありがとうございます。

追従がうまくいかない

まだ検証していないので確証はありませんが、原因としては

C#

1transform.position = transform.position + offset;

ここじゃないですかね?

これ、違う書き方をすると
transform.position += offset;
こうなります。
なので、transform.positionにoffsetを毎フレーム足していく処理になってしまっています。

解決策

C#

1transform.position = target.position + offset;

ターゲット位置にオフセットを足しましょう。

追記: 不安定なカメラ挙動

恐らく原因はこれですね。

C#

1transform.RotateAround(target.transform.position, axis, rotate);

毎フレームrotateの値(ここでは0.4f)で回転・移動する処理です。
0.4fずつ回っていくので、テレポートみたいに移動します。
それに加え、毎フレーム0.4f回転・移動という処理なので他の端末で動かすとフレーム数に差がありますので速度が変わります。
Time.deltaTimeを掛けましょう。

C#

1transform.RotateAround(target.transform.position, axis, rotate * Time.deltaTime);

(恐らくrotateの値を上げないとかなり遅いです)

追記2

ちょっと検証してきました。
カメラがチカチカする原因が判明しました。
前述の通り、**Transform.RotateAround()は「ある軸を中心に、周りをぐるぐる移動して回る処理」です。
なので
transform.position = target.position + offset;をやってしまうと、別々の移動処理が呼ばれることになります。
よって、カメラが高速で2ヶ所を移動することになり、チカチカしていたんだと思います。
ですので
transform.position = target.position + offset;**は必要ありません。
以下、参考に

C#

1using UnityEngine; 2 3public class RotateAround : MonoBehaviour 4{ 5 6 [SerializeField] Transform target; 7 8 [SerializeField] float rotate; 9 10 // Update is called once per frame 11 void Update() 12 { 13 // 要らない 14 // Vector3 offset = target.position - transform.position; 15 // transform.position = target.position + offset; 16 17 // 高さ合わせ 18 var targetPos = transform.position; 19 targetPos.y = target.position.y; 20 transform.position = targetPos; 21 22 // targetを中心に回る 23 Vector3 axis = transform.TransformDirection(target.up); 24 transform.RotateAround(target.position, axis, rotate * Time.deltaTime); 25 26 // targetの方を向く 27 transform.LookAt(target); 28 } 29}

投稿2021/01/19 09:17

編集2021/01/21 15:52
PinoMatcha

総合スコア368

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

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

Um_kok

2021/01/19 09:41

お返事遅れました。いつも回答ありがとうございます。 貴方様の言うとおり、targetをくっつけたら追従できたのですが、 カメラを動かすときにチカチカしてしまいます。 私のコードの書き方が悪いんでしょうか?ゴール時(NavMeshAgentに切り替えております)
Um_kok

2021/01/19 09:52 編集

すみません。間違えました。回線の影響で、二回送ってしまいました。 navmeshAgent のspeed を変えてもチカチカしてしまいます
PinoMatcha

2021/01/19 09:51

「カメラを動かすときにチカチカする」というのがどんな挙動か分かりませんが、カメラの追従処理はLateUpdate()に書くと良いそうです。
Um_kok

2021/01/19 09:57

チカチカするというのは、カメラの動きがとぎれとぎれになってて、見にくいということです。滑らかじゃないとも言えます。すみません。 LateUpdate にも書いてみたのですが、とぎれとぎれになってしまいます。
PinoMatcha

2021/01/20 02:36

返信遅れましたが回答に追記しておきました。
Um_kok

2021/01/20 05:09

お返事ありがとうございます。 Time.deltaTimeをかけて見たのですが まだカメラの動きが変です。よく動きを見てみたのですが、カメラが回っていないように見えます。
PinoMatcha

2021/01/20 05:13

transform.LookAt(target); が処理に入ってないからじゃないですかね?
Um_kok

2021/01/20 05:30

お返事ありがとうございます。 transform.RotateAround の下にlookAt(target)を書いてみたのですが、 まだ治らなくて、途切れ途切れに前後にカメラが瞬間移動して.targetを見つめている感じになってしまいます。rotate を調整しても変わりませんでした。コードが悪いですね。すみません。
PinoMatcha

2021/01/21 15:53

ごめんなさい、返信遅れました…。 回答に追記しておきました。
Um_kok

2021/01/22 00:38

お返事ありがとうございます。 いえいえ、大丈夫です。 すみません,それだと何故か追従しなくなってしまうんですよね、、、 なので、サインコサインで1回やってみます。
Um_kok

2021/01/22 02:21

別の回答者様のサインコサインのやり方で上手く行きました。PinoMatcha様ありがとうございました。何で上手くいかなかったのか分からないですが、ありがとうございました。
guest

0

ものすごく安直な考えですが、
1.空のオブジェクトを作成
2.1のオブジェクトを追従したいオブジェクトと一緒に動かすスクリプトを組む

//例 [SerializeField] GameObject Target; void Update() { transform.position = Target.transform.position; }

3.1のオブジェクトの子にカメラを設定
それなら回転も空のオブジェクトを動かすだけでいいですし追従もするはずです

また、このような方法もあるそうです
カメラのX座標 = キャラのX座標 + Cos( カメラの回転量 ) × 離したい距離
カメラのY座標 = キャラのY座標 + Sin( カメラの回転量 ) × 離したい距離
引用元:https://teratail.com/questions/26455
ご参考にどうぞ(少し違うかもしれませんが)

投稿2021/01/19 09:11

CraftTable

総合スコア234

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

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

Um_kok

2021/01/19 10:06

回答ありがとうございます。 1つ目のオブジェクトを動かすというのは、WheelColliderを使っているので、難しいですが。 2つ目のは真似してやってみます。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問