Q&A
実現したいこと
Unityで現在地からクリックした地点まで放物線を描くように動かしたいです。
また、移動速度は調整できるようにしたいです。
試したこと①
初めにSlerp関数を使ってみましたが、孤の方向を操作できず、孤が横に向いてしまい放物線になりません。
恥ずかしながら線形補完の数学的な理屈はふんわりとしか理解できてません…
また機能(関数)としても使うのは初めてです。
知らないだけで引数などで孤の方向を指定できるのであれば話は早いのですが…
cs
1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class Throw : MonoBehaviour 6{ 7 /* 8 * 1.マウスクリック 9 * 2.クリックされた座標を取得 10 * 3.取得した座標にSleap関数で移動 11 */ 12 13 //落下地点(クリックした座標) 14 Vector3 ThrowPoint = new Vector3(0, 0, 0); 15 16 //投げるスピード 17 public float speed = 10; 18 19 //投げるフラグ 20 bool Throwing = false; 21 22 float distance_two = 0; 23 24 private void Update() 25 { 26 print(Input.mousePosition); 27 print("world;"+Camera.main.ScreenToWorldPoint(Input.mousePosition)); 28 _Throw(); 29 } 30 31 void _Throw() 32 { 33 34 //左クリック時のマウス座標を取得 35 if (Input.GetMouseButtonDown(0)) 36 //&& !Throwing) 37 { 38 //スクリーン座標からワールド座標に変換してから代入 39 var MousePos = Input.mousePosition; 40 var ScreenPos = new Vector3(MousePos.x, MousePos.y, 40f); 41 ThrowPoint = Camera.main.ScreenToWorldPoint(ScreenPos); 42 ThrowPoint.y = 1; 43 44 print(ThrowPoint); 45 46 //二点間の距離を代入(スピード調整に使う) 47 distance_two = Vector3.Distance(transform.position, ThrowPoint); 48 49 Throwing = true; 50 51 } 52 53 if (Throwing) 54 { 55 // 現在の位置 56 float present_Location = (Time.time * speed) / distance_two; 57 58 // オブジェクトの移動 59 transform.position = Vector3.Slerp(transform.position, ThrowPoint, present_Location); 60 } 61 } 62} 63
試したこと②
次にRigidbodyのAddForceで物理的に目的地まで角度をつけて発射するやり方を見つけたのですが速度をコントロールする方法わかりません。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Throw2 : MonoBehaviour { /* * 1.マウスクリック * 2.クリックされた座標を取得 * 3.取得した座標にSleap関数で飛ばす */ //落下地点(クリックした座標) Vector3 ThrowPoint = new Vector3(0, 0, 0); // 射出角度 public float ThrowingAngle = 60; private void Update() { _Throw(); } void _Throw() { //左クリック時のマウス座標を取得 if (Input.GetMouseButtonDown(0)) { //スクリーン座標からワールド座標に変換してから代入 var MousePos = Input.mousePosition; var ScreenPos = new Vector3(MousePos.x, MousePos.y, 40f); ThrowPoint = Camera.main.ScreenToWorldPoint(ScreenPos); ThrowPoint.y = 1; Throwing(); } } private void Throwing() { // 射出速度を算出 Vector3 velocity = CalculateVelocity(transform.position, ThrowPoint, ThrowingAngle); // 射出 Rigidbody rid = this.GetComponent<Rigidbody>(); rid.AddForce(velocity * rid.mass, ForceMode.Impulse); } private Vector3 CalculateVelocity(Vector3 pointA, Vector3 pointB, float angle) { // 射出角をラジアンに変換 float rad = angle * Mathf.PI / 180; // 水平方向の距離x float x = Vector2.Distance(new Vector2(pointA.x, pointA.z), new Vector2(pointB.x, pointB.z)); // 垂直方向の距離y float y = pointA.y - pointB.y; // 斜方投射の公式を初速度について解く float speed = Mathf.Sqrt(-Physics.gravity.y * Mathf.Pow(x, 2) / (2 * Mathf.Pow(Mathf.Cos(rad), 2) * (x * Mathf.Tan(rad) + y))); if (float.IsNaN(speed)) { // 条件を満たす初速を算出できなければVector3.zeroを返す return Vector3.zero; } else { return (new Vector3(pointB.x - pointA.x, x * Mathf.Tan(rad), pointB.z - pointA.z).normalized * speed); } } }
こちらのサイト(https://qiita.com/_udonba/items/a71e11c8dd039171f86c)
を参考にしました(発射機構ほぼコピってます)
追記
-
後々調整しやすそうなので、できればSlerp関数で実現したいと考えています。
-
teratailを使うのは初めてなので、使い方や書き方に至らぬ点があるかもしれませんがご容赦ください。
もしそういった点があれば教えていただけると幸いです。
- C#、Unityについても初心者なので細かく教えていただけるとありがたいです。
補足情報(FW/ツールのバージョンなど)
Unity:2021.3.5.f1
回答1件
あなたの回答
tips
プレビュー
下記のような回答は推奨されていません。
このような回答には修正を依頼しましょう。
2022/07/24 09:27