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

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

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

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

Unity3D

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

Unity

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

Q&A

解決済

1回答

1503閲覧

フラグがたったらモデルを決まった角度までゆっくり回転させフラグがfalseになったらゆっくり元の角度に戻したい

Um_kok

総合スコア39

C#

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

Unity3D

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

Unity

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

0グッド

0クリップ

投稿2020/12/11 10:23

編集2020/12/12 09:38

スペースが押されている間、driftRight を true にし、update でゆっくり回転をしているのですが、一回目はちゃんと回ってくれるのですが、スペースを二回目に押すと、その続きから、ゆっくり回っていきます。else 文で Quaternion をゼロにしているはずなのですが、なぜだかわかりません。

やったこと、
本来はFixd Update に回転する処理を書いておりましたが、Update に書き直しました。
↓この方のサイトを見ながらやってみたのですが、二回目以降スペースを押すとうまくいきません。
https://tama-lab.net/2017/06/unity%E3%81%A7%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%82%92%E5%9B%9E%E8%BB%A2%E3%81%95%E3%81%9B%E3%82%8B%E6%96%B9%E6%B3%95%E3%81%BE%E3%81%A8%E3%82%81/
横キーを押しながら、スペースを押したときに、ゆっくり回転し、スーペースを話したら、元の角度にゆっくり回転する挙動にしたいのですが、難しいです。もしヒントだけでも教えてくださる方、ご教示お願いします。

ーーーーーーーーーー修正後コード全体ですーーーーーーーーーーーーーーーーーーーーーーーーー

回答者様すみません。

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5[System.Serializable] 6public class AxleInfo 7{ 8 // 力を加えるCollider 9 public WheelCollider leftWheel; 10 public WheelCollider rightWheel; 11 12 public bool motor; // このホイールがエンジンにアタッチされているかどうか 13 public bool steering; // このホイールがハンドルの角度を反映しているかどうか 14} 15 16public class PlayerCar : MonoBehaviour 17{ 18 // AxleInfo クラスをインスペクタで設定できる 19 [SerializeField] private List<AxleInfo> axleInfos; // 個々の車軸の情報 20 [SerializeField] private float maxMotorTorque; // ホイールに適用可能な最大トルク 21 [SerializeField] private float maxSteerinAngle; // 適用可能最大ハンドル角度 22 23 // 空オブジェクト(Wheel Collider) 24 [SerializeField] private WheelCollider wheelFL; 25 [SerializeField] private WheelCollider wheelFR; 26 [SerializeField] private WheelCollider wheelBL; 27 [SerializeField] private WheelCollider wheelBR; 28 29 // ホイールのモデル 30 [SerializeField] private Transform wheelFLTrans; 31 [SerializeField] private Transform wheelFRTrans; 32 [SerializeField] private Transform wheelBLTrans; 33 [SerializeField] private Transform wheelBRTrans; 34 [SerializeField] private float steering = 0.0f; 35 public float motor = 0.0f; 36 37 // インスペクターで設定 38 [SerializeField,Header("加える力")] private float power; 39 [SerializeField,Header("スリップ値")] private float wheelExtremumSlip; 40 [SerializeField,Header("タイヤそのものの摩擦力")] private float wheelstiffness; 41 [SerializeField,Header("x軸摩擦力")] private float wheelFriction; 42 43 // Wheel Collider の値を保持するための変数 44 private WheelFrictionCurve wheelValueRetentionFL; 45 private WheelFrictionCurve wheelValueRetentionFR; 46 private WheelFrictionCurve wheelValueRetentionBL; 47 private WheelFrictionCurve wheelValueRetentionBR; 48 49 // 変更する値 50 private WheelFrictionCurve wheelChangeValue; 51 52 // ドリフトに必要なモーターの回転 53 private const float motorMax = 600; 54 55 // ドリフト時加える力 56 [SerializeField,Header("ドリフト時のX方向の力")] private float driftPowerX; 57 [SerializeField,Header("ドリフト時のZ方向の力")] private float driftPowerZ; 58 59 // ドリフトTimeを計る 60 [SerializeField,Header("壱段階目のドリフト時間")] private float driftMaxOne = 3; 61 [SerializeField,Header("弐段階目のドリフト時間")] private float driftMaxTwo = 6; 62 private float driftTimer; 63 64 private new Rigidbody rigidbody; // AddForce に使う 65 [SerializeField] private float limitSpeed; // 速度制限 66 67 68 // ジャンプフラグ 69 public bool jumpflg; 70 71 // ドリフトフラグ 72 public bool driftStart; // 始まったか 73 private bool driftDarsh1; // 壱段階目のドリフトダッシュ 74 private bool driftDarsh2; // 弐段階目のドリフトダッシュ 75 76 public int ranking; 77 78 private bool driftRight; 79 private bool driftLeft; 80 [SerializeField] private Transform model; 81 82 83 void Start() 84 { 85 // キャッシュしておく 86 rigidbody = GetComponent<Rigidbody>(); 87 88 // Wheel Collider の 横移動の値を保存しておく 89 wheelValueRetentionFL = wheelFL.sidewaysFriction; 90 wheelValueRetentionFR = wheelFR.sidewaysFriction; 91 wheelValueRetentionBL = wheelBL.sidewaysFriction; 92 wheelValueRetentionBR = wheelBR.sidewaysFriction; 93 } 94 void Update() 95 { 96 WheelRotation(); 97 if (driftRight) 98 { 99 100 float speed = 1f; 101 float step = speed * Time.deltaTime; 102 103 //指定した方向にゆっくり回転する場合 104 model.transform.localRotation = Quaternion.RotateTowards(transform.rotation, Quaternion.Euler(0, 45f, 0), step); 105 } 106 } 107 public void FixedUpdate() 108 { 109 PlayerMove(); 110 CarDrift(); 111 CarDriftDarsh(); 112 } 113 114 /// <summary> 115 /// プレイヤーの入力を受け取りタイヤに力を加える関数 116 /// </summary> 117 private void PlayerMove() 118 { 119 motor = maxMotorTorque * Input.GetAxis("Vertical"); 120 steering = maxSteerinAngle * Input.GetAxis("Horizontal"); 121 122 foreach (AxleInfo axleInfo in axleInfos) 123 { 124 if (axleInfo.steering) 125 { 126 axleInfo.leftWheel.steerAngle = steering; 127 axleInfo.rightWheel.steerAngle = steering; 128 } 129 if (axleInfo.motor) 130 { 131 axleInfo.leftWheel.motorTorque = motor; 132 axleInfo.rightWheel.motorTorque = motor; 133 } 134 } 135 } 136 /// <summary> 137 /// ホイールのモデルを回転する関数 138 /// </summary> 139 private void WheelRotation() 140 { 141 //wheelcolliderの回転速度に合わせてタイヤモデルを回転させる 142 wheelFLTrans.Rotate(wheelFL.rpm / 60 * 360 * Time.deltaTime, 0, 0); 143 wheelFRTrans.Rotate(wheelFR.rpm / 60 * 360 * Time.deltaTime, 0, 0); 144 wheelBLTrans.Rotate(wheelBL.rpm / 60 * 360 * Time.deltaTime, 0, 0); 145 wheelBRTrans.Rotate(wheelBR.rpm / 60 * 360 * Time.deltaTime, 0, 0); 146 147 //wheelcolliderの角度に合わせてタイヤモデルを回転する(フロントのみ) 148 wheelFLTrans.localEulerAngles = new Vector3(wheelFLTrans.localEulerAngles.x, wheelFL.steerAngle - wheelFLTrans.localEulerAngles.z, wheelFLTrans.localEulerAngles.z); 149 wheelFRTrans.localEulerAngles = new Vector3(wheelFRTrans.localEulerAngles.x, wheelFR.steerAngle - wheelFRTrans.localEulerAngles.z, wheelFRTrans.localEulerAngles.z); 150 } 151 152 /// <summary> 153 /// ドリフトをする関数 154 /// </summary> 155 private void CarDrift() 156 { 157 if(motor > motorMax) 158 { 159 if((steering > 0 || steering < 0) 160 && Input.GetKeyDown(KeyCode.Space)){ 161 driftStart = true; 162 } 163 else if(driftStart && Input.GetKey(KeyCode.Space)) 164 { 165 driftTimer += Time.deltaTime; 166 if (driftTimer > driftMaxOne) 167 { 168 driftDarsh1 = true; 169 } 170 if (driftTimer > driftMaxTwo) 171 { 172 driftDarsh2 = true; 173 } 174 // 変更する値 175 wheelChangeValue = wheelFL.sidewaysFriction; 176 wheelChangeValue.extremumSlip = wheelExtremumSlip; 177 wheelChangeValue.asymptoteSlip = wheelExtremumSlip; 178 wheelChangeValue.extremumValue = wheelFriction; 179 wheelChangeValue.asymptoteValue = 0; 180 wheelChangeValue.stiffness = wheelstiffness; 181 182 // 変更の値を代入 183 wheelFL.sidewaysFriction = wheelChangeValue; 184 wheelFR.sidewaysFriction = wheelChangeValue; 185 wheelBL.sidewaysFriction = wheelChangeValue; 186 wheelBR.sidewaysFriction = wheelChangeValue; 187 188 if (steering > 0) 189 { 190 rigidbody.AddForce(new Vector3(driftPowerX, 0, driftPowerZ)); 191 driftRight = true; 192 } 193 if (steering < 0) rigidbody.AddForce(new Vector3(-driftPowerX, 0, driftPowerZ)); 194 195 // 速度制限 196 if (rigidbody.velocity.magnitude > limitSpeed) rigidbody.velocity = rigidbody.velocity.normalized * limitSpeed; 197 } 198 else 199 { 200 driftRight = false; 201 //model.transform.localRotation = new Quaternion(0,0,0,0); 202 //model.transform.rotation = new Vector3(0, 0, 0); 203 //model.transform.localEulerAngles = new Vector3(0f, 0f, 0f); 204 if (driftTimer < driftMaxOne) driftTimer = 0; 205 driftStart = false; 206 wheelFL.sidewaysFriction = wheelValueRetentionFL; 207 wheelFR.sidewaysFriction = wheelValueRetentionFR; 208 wheelBL.sidewaysFriction = wheelValueRetentionBL; 209 wheelBR.sidewaysFriction = wheelValueRetentionBR; 210 211 float speed = 1f; 212 float step = speed * Time.deltaTime; 213 214 //指定した方向にゆっくり回転する場合 215 model.transform.localRotation = Quaternion.RotateTowards(transform.rotation, Quaternion.Euler(0, 0, 0), step); 216 } 217 } 218 } 219 /// <summary> 220 /// ドリフト後ダッシュする関数 221 /// </summary> 222 private void CarDriftDarsh() 223 { 224 if (driftStart) return; 225 if (driftDarsh2) 226 { 227 driftDarsh1 = false; 228 driftDarsh2 = false; 229 driftTimer = 0; 230 rigidbody.AddForce(transform.forward * 600000); // パーティクル入れるエフェクト 231 } 232 else if (driftDarsh1) 233 { 234 driftDarsh1 = false; 235 driftTimer = 0; 236 rigidbody.AddForce(transform.forward * 500000); // パーティクル入れるエフェクト 237 } 238 } 239} 240

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

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

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

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

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

guest

回答1

0

ベストアンサー

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

早速ですがコードが大変なことになっています。

一応修正しましたが、条件分岐の部分がコードとして成り立っていません…。

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class PlayerCar : MonoBehaviour 6{ 7 8 // 変数がきちんと宣言できていない 9 float steering; 10 bool driftStart; 11 Transform model; 12 bool driftRight; 13 14 // コードをコピペしたら変数エラーでたので勝手に追加 15 float motor, motorMax; 16 17 void Update() { 18 float speed = 1f; 19 float step = speed * Time.deltaTime; 20 21 model.transform.localRotation = Quaternion.RotateTowards(transform.rotation, Quaternion.Euler(0, 45f, 0), step); 22 } 23 24 // CarDrift()はどこからコールされている? 25 private void CarDrift() { 26 if (motor > motorMax) { 27 // ここがおかしい 28 /*if ((steering > 0 || steering < 0) && Input.GetKeyDown(KeyCode.Space)) { 29 // 何かしらの処理? 30 } else if (driftStart && Input.GetKey(KeyCode.Space)) { 31 if (steering > 0) { 32 driftRight = true; 33 } 34 if (steering < 0) driftRight = true; 35 else { 36 driftRight = false; 37 model.transform.localRotation = new Quaternion(0, 0, 0, 0); 38 //model.transform.rotation = new Vector3(0, 0, 0); 39 //model.transform.localEulerAngles = new Vector3(0f, 0f, 0f); 40 } 41 }*/ 42 } 43 } 44}

基本、ソースコードはコピペでいいと思います。

質問への修正依頼ではコードが載せられないので回答へ。
修正していただいたら、回答へ移ります。

追記

とりあえず、ヒントになりそうなコードを載せます。

Y軸だけ回転させる処理を実装してみます。
一旦floatで計算し、Yに当てはめる方法を取ります。

C#

1// usingやクラス部分は省きます。 2 3 4// 入力を格納 5private int inputRaw; 6 7// 回転させる角度 8public float driftAngle = 45f; 9 10// ドリフト時の回転速度 11public float driftSpeed = 10f; 12 13// ドリフト中か? 14bool isDrifting = false; 15// 滑らかにしたあとのYを格納 16float easedY; 17// イージングが必要かどうか 18bool needEasing = true; 19 20void Update(){ 21 // 入力受付 22 // Input.GetAxisRaw("Horizontal")は左を-1、右を1で取得します。 23 // 直前に(int)を付けることで、floatから変換 24 inputRaw = (int)Input.GetAxisRaw("Horizontal"); 25 26 if (Input.GetKeyDown(KeyCode.Space)) { 27 isDrifting = true; 28 needEasing = true; 29 } 30 if (Input.GetKeyUp(KeyCode.Space)) { 31 isDrifting = false; 32 } 33 34 if (isDrifting) { 35 // 回したい角度に入力(-1, 1)を掛けることで角度を反転させている 36 easedY = Mathf.Lerp(easedY, driftAngle * inputRaw, Time.deltaTime * driftSpeed); 37 } else { 38 // ドリフト中でなくて、イージングが必要なフラグがtrueなら 39 if(needEasing) { 40 // 0に向けてイージング 41 easedY = Mathf.Lerp(easedY, 0, Time.deltaTime * driftSpeed); 42 43 if(Mathf.Abs(easedY) < 0.1f) { 44 // easedYの絶対値が0.1未満ならeasedYを0にしてイージングフラグをfalseに 45 easedY = 0; 46 needEasing = false; 47 } 48 } 49 } 50 51 // 実際にtransformに代入(y以外は何も変わらない) 52 transform.localRotation = Quaternion.Euler(transform.localRotation.x, easedY, transform.localRotation.z); 53}

投稿2020/12/12 08:52

編集2020/12/12 15:06
PinoMatcha

総合スコア368

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

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

Um_kok

2020/12/12 09:30

お返事遅れましてすみません。すみません!見にくいと思って余分な所を省いてしまいました。すぐに全部のせます。
Um_kok

2020/12/12 09:33

省いたコードを確認しておりませんでした。申し訳ないです。
PinoMatcha

2020/12/12 10:02

コード全文、ありがとうございます。 質問があるのですが、スペースを押したら規定値分の回転を与え、スペースを離したら元の角度に戻るのは分かりました。 そこで、「元の角度」がなんなのか知りたいです。 「スペースを押したときの角度」のことなのか、走行中だと思うので「進行方向」なのか。 挙動が変わってしまうため質問させていただきます。
Um_kok

2020/12/12 10:18

お返事ありがとうございます。 スペースを押し、押されているキーの向きで、右か、左に(左の回転の処理も後で書くつもりです)回転します。スペースが離されるまで、同じ向きに回転(最初に左を押したらスペースを離すまで指定値分、左にゆっくり回転、スペースを押している間に右を押しても、左回転のまま) 元の角度というのは モデルは、 車のオブジェクト(ホイールコライダ)の子にしております。 なので、ローカルで(0,0,0)です。 説明下手で申し訳ありませんが、やりたい挙動としてはスペースを押し右に押していたら、ゆっくり右に回転し、スペースを離すとその角度からゆっくりローカルの(0,0,0)に戻るようにしたいです。 マリオカートっぽい動きにしたいので、そのようにしたいです。わかりにくくてすみません
PinoMatcha

2020/12/12 10:24

なるほど。 だからローカル座標を使っているわけですね。 納得しました。 マリオカートっぽい挙動でしたら、回転させるのはY軸だけでいいと思います。 回答にコードを追記しますのでお待ちください。
Um_kok

2020/12/12 10:29

そうです!Y軸だけ回転させているつもりでしたが、(´;ω;`) まだまだ勉強が足りませんね。もっと勉強頑張ります。いつまでも待ちます。
Um_kok

2020/12/12 14:28

分かりやすい回答ありがとうございます。お返事遅れてすみません。上記のコードを試してみたら、何故かうまくいかなくて、カメラがガタガタしたり、移動が可笑しくなって悩んでおりましたが、コードをよく見てみたら、自分のrotation を動かしていました。(´;ω;`) だからか!と解決して良かったです。 私にわかりやすいようにコメント打ってあってすごくわかりやすかったです! ヒントという形で回答してくださったので、もうちょっと細かくしてやりたいような挙動を目指して頑張ります!自分で考えないと力になりませんからね。本当にありがとうございました。困ったことがあったらまたお願いします。m(_ _"m)
PinoMatcha

2020/12/12 14:33

プログラミングくらいしか力添え出来ませんが、頑張ってください
Um_kok

2020/12/12 15:40

はい!頑張ります!精進します。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問