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

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

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

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

Unity

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

Q&A

解決済

2回答

2486閲覧

標的を決めずにプレイヤーの向いている方向に放物線を描いて弾をとばしたい

futonmin

総合スコア33

Unity3D

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

Unity

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

0グッド

0クリップ

投稿2020/09/05 09:08

編集2020/09/05 09:25

前提・実現したいこと

前提:
下のコードは標的となるオブジェクトを決めて、マウスを離したらプレイヤーオブジェクトから標的に向かって放物線を描いた弾が発射されるようになっています。
※弾にはRigidbody、SphereColliderのついたSphereオブジェクトを使っています。

実現したいこと:
下のコードをベースに、プレイヤーオブジェクトの向いている方向(標的を決めず)に放物線を描いてまっすぐに弾をとばしたい。
例:スマホゲームの「コンパス」というゲームの「まとい」というキャラクターのため技のようなものを実装したい。

該当のソースコード

C#

1using System.Collections; 2using System.Collections.Generic; 3using System.Collections.Specialized; 4using UnityEngine; 5 6public class ThrowingSphere : MonoBehaviour 7{ 8 //射出するオブジェクト 9 [SerializeField] 10 private GameObject throwingObject; 11 //標的となるオブジェクト 12 [SerializeField] 13 private GameObject enemyObject; 14 //射出角度 15 [SerializeField] 16 private float throwingAngle; 17 18 // Start is called before the first frame update 19 void Start() 20 { 21 Collider collider = GetComponent<Collider>(); 22 if (collider != null) 23 { 24 // 干渉しないようにisTriggerをつける 25 collider.isTrigger = true; 26 } 27 } 28 29 // Update is called once per frame 30 void Update() 31 { 32 if (Input.GetMouseButtonUp(0)) 33 { 34 // マウス左クリックを離してボールを射出する 35 ThrowingBall(); 36 } 37 38 } 39 40 //ボールを射出する 41 private void ThrowingBall() 42 { 43 if (throwingObject != null && enemyObject != null) 44 { 45 // Ballオブジェクトの生成 46 GameObject ball = Instantiate(throwingObject, this.transform.position, Quaternion.identity); 47 // 標的の座標 48 Vector3 targetPosition = enemyObject.transform.position; 49 // 射出角度 50 float angle = throwingAngle; 51 // 射出速度を算出 52 Vector3 velocity = CalculateVelocity(this.transform.position, targetPosition, angle); 53 // 射出 54 Rigidbody rid = ball.GetComponent<Rigidbody>(); 55 rid.AddForce(velocity * rid.mass, ForceMode.Impulse); 56 } 57 else 58 { 59 throw new System.Exception("射出するオブジェクトまたは標的のオブジェクトが未設定です。"); 60 } 61 } 62 63 //標的に命中する射出速度の計算 64 // <param name="pointA">射出開始座標</param> 65 // <param name="pointB">標的の座標</param> 66 // <returns>射出速度</returns> 67 private Vector3 CalculateVelocity(Vector3 pointA, Vector3 pointB, float angle) 68 { 69 // 射出角をラジアンに変換 70 float rad = angle * Mathf.PI / 180; 71 //水平方向の距離x 72 float x = Vector2.Distance(new Vector2(pointA.x, pointA.z), new Vector2(pointB.x, pointB.z)); 73 // 垂直方向の距離y 74 float y = pointA.y - pointB.y; 75 // 斜方投射の公式を初速度について解く 76 float speed = Mathf.Sqrt(-Physics.gravity.y * Mathf.Pow(x, 2) / (2 * Mathf.Pow(Mathf.Cos(rad), 2) * (x * Mathf.Tan(rad) + y))); 77 if (float.IsNaN(speed)) 78 { 79 // 条件を満たす初速を算出できなければVector3.zeroを返す 80 return Vector3.zero; 81 } 82 else 83 { 84 return (new Vector3(pointB.x - pointA.x, x * Mathf.Tan(rad), pointB.z - pointA.z).normalized * speed); 85 } 86 } 87}

C#

1//参考になるか分かりませんが、プレイヤーオブジェクトとして使っているUnityちゃんのソースコードです。 2// Mecanimのアニメーションデータが、原点で移動しない場合の Rigidbody付きコントローラ 3// サンプル 4// 2014/03/13 N.Kobyasahi 5// 6using UnityEngine; 7using System.Collections; 8using System.Runtime.CompilerServices; 9 10namespace UnityChan 11{ 12// 必要なコンポーネントの列記 13 [RequireComponent(typeof(Animator))] 14 [RequireComponent(typeof(CapsuleCollider))] 15 [RequireComponent(typeof(Rigidbody))] 16 17 public class UnityChanControlScriptWithRgidBody : MonoBehaviour 18 { 19 20 public float animSpeed = 1.5f; // アニメーション再生速度設定 21 public float lookSmoother = 3.0f; // a smoothing setting for camera motion 22 public bool useCurves; // Mecanimでカーブ調整を使うか設定する 23 // このスイッチが入っていないとカーブは使われない 24 public float useCurvesHeight = 0.5f; // カーブ補正の有効高さ(地面をすり抜けやすい時には大きくする) 25 26 // 以下キャラクターコントローラ用パラメタ 27 // 前進速度 28 public float PlayerSpeed = 3.0f; 29 // 後退速度 30 //public float backwardSpeed = 2.0f; 31 // 旋回速度 32 public float rotateSpeed = 2.0f; 33 // ジャンプ威力 34 public float jumpPower = 3.0f; 35 36 // 移動速度の入力に対する追従度 37 public float moveForceMultiplier; 38 //カメラ取得 39 public GameObject mainCamera; 40 // カメラの向きに合わせて移動させたい場合はtrue(慣性) 41 public bool isUseCameraDirection = true; 42 43 // キャラクターコントローラ(カプセルコライダ)の参照 44 private CapsuleCollider col; 45 //private Rigidbody rb; 46 public Rigidbody rb; //自分で書き換えた 47 // キャラクターコントローラ(カプセルコライダ)の移動量 48 private Vector3 velocity; 49 private Vector3 velocityX; 50 // CapsuleColliderで設定されているコライダのHeiht、Centerの初期値を収める変数 51 private float orgColHight; 52 private Vector3 orgVectColCenter; 53 private Animator anim; // キャラにアタッチされるアニメーターへの参照 54 private AnimatorStateInfo currentBaseState; // base layerで使われる、アニメーターの現在の状態の参照 55 56 //private GameObject cameraObject; // メインカメラへの参照 57 58 // アニメーター各ステートへの参照 59 static int idleState = Animator.StringToHash ("Base Layer.Idle"); 60 static int locoState = Animator.StringToHash ("Base Layer.Locomotion"); 61 static int jumpState = Animator.StringToHash ("Base Layer.Jump"); 62 static int restState = Animator.StringToHash ("Base Layer.Rest"); 63 64 // 初期化 65 void Start () 66 { 67 // Animatorコンポーネントを取得する 68 anim = GetComponent<Animator>(); 69 // CapsuleColliderコンポーネントを取得する(カプセル型コリジョン) 70 col = GetComponent<CapsuleCollider>(); 71 rb = GetComponent<Rigidbody>(); 72 //メインカメラを取得する 73 //cameraObject = GameObject.FindWithTag ("MainCamera"); 74 // CapsuleColliderコンポーネントのHeight、Centerの初期値を保存する 75 orgColHight = col.height; 76 orgVectColCenter = col.center; 77 } 78 79 void Update() 80 { 81 //範囲指定 82 float fPosX, fPosY; 83 fPosX = fPosY = 0.0f; 84 if (transform.position.x > 30.0f) 85 { 86 fPosX = 30.0f; 87 } 88 else if (transform.position.x < -30.0f) 89 { 90 fPosX = -30.0f; 91 } 92 else 93 { 94 fPosX = transform.position.x; 95 } 96 if (transform.position.y < 0.55f) 97 { 98 fPosY = 0.55f; 99 } 100 else 101 { 102 fPosY = transform.position.y; 103 } 104 transform.position = new Vector3(fPosX, fPosY, transform.position.z); 105 } 106 107 108 // 以下、メイン処理.リジッドボディと絡めるので、FixedUpdate内で処理を行う. 109 void FixedUpdate () 110 { 111 Vector3 moveVector = Vector3.zero; // 移動速度の入力 112 113 float h = Input.GetAxis ("Horizontal"); // 入力デバイスの水平軸をhで定義 114 float v = Input.GetAxis ("Vertical"); // 入力デバイスの垂直軸をvで定義 115 anim.SetFloat ("Speed", v); // Animator側で設定している"Speed"パラメタにvを渡す 116 anim.SetFloat ("Direction", h); // Animator側で設定している"Direction"パラメタにhを渡す 117 anim.speed = animSpeed; // Animatorのモーション再生速度に animSpeedを設定する 118 currentBaseState = anim.GetCurrentAnimatorStateInfo (0); // 参照用のステート変数にBase Layer (0)の現在のステートを設定する 119 rb.useGravity = true;//ジャンプ中に重力を切るので、それ以外は重力の影響を受けるようにする 120 121 122 123 // 以下、キャラクターの移動処理 124 velocity = new Vector3 (0, 0, v); // 上下のキー入力からZ軸方向の移動量を取得 125 // キャラクターのローカル空間での方向に変換 126 velocity = transform.TransformDirection (velocity); 127 //以下のvの閾値は、Mecanim側のトランジションと一緒に調整する 128 if (v > 0.1) { 129 velocity *= PlayerSpeed; // 移動速度を掛ける 130 } else if (v < -0.1) { 131 velocity *= PlayerSpeed; // 移動速度を掛ける 132 } 133 134 135 // 上下のキー入力でキャラクターを移動させる 136 transform.localPosition += velocity * Time.fixedDeltaTime; 137 // 左右のキー入力でキャラクタをY軸で旋回させる 138 transform.Rotate(0, h * rotateSpeed, 0); 139 140 141 142 if (isUseCameraDirection) 143 { 144 Vector3 cameraForward = mainCamera.transform.forward; 145 //Vector3 cameraRight = mainCamera.transform.right; 146 cameraForward.y = 0.0f; // 水平方向に移動させたい場合はy方向成分を0にする 147 //cameraRight.y = 0.0f; 148 149 moveVector = PlayerSpeed * (/*cameraRight.normalized * h +*/ cameraForward.normalized * v); 150 } 151 else 152 { 153 moveVector.x = PlayerSpeed * h; 154 moveVector.z = PlayerSpeed * v; 155 } 156 157 //Rigidbodyを使った慣性 158 rb.AddForce(moveForceMultiplier * (moveVector - rb.velocity)); 159 160 // 以下、Animatorの各ステート中での処理 161 // Locomotion中 162 // 現在のベースレイヤーがlocoStateの時 163 if (currentBaseState.nameHash == locoState) { 164 //カーブでコライダ調整をしている時は、念のためにリセットする 165 if (useCurves) { 166 resetCollider (); 167 } 168 } 169 170 // IDLE中の処理 171 // 現在のベースレイヤーがidleStateの時 172 else if (currentBaseState.nameHash == idleState) { 173 //カーブでコライダ調整をしている時は、念のためにリセットする 174 if (useCurves) { 175 resetCollider (); 176 } 177 // スペースキーを入力したらRest状態になるs 178 if (Input.GetButtonDown ("Jump")) { 179 anim.SetBool ("Rest", true); 180 } 181 } 182 // REST中の処理 183 // 現在のベースレイヤーがrestStateの時 184 else if (currentBaseState.nameHash == restState) { 185 //cameraObject.SendMessage("setCameraPositionFrontView"); // カメラを正面に切り替える 186 // ステートが遷移中でない場合、Rest bool値をリセットする(ループしないようにする) 187 if (!anim.IsInTransition (0)) { 188 anim.SetBool ("Rest", false); 189 } 190 } 191 } 192 193 194 195 196 197 198 // キャラクターのコライダーサイズのリセット関数 199 void resetCollider () 200 { 201 // コンポーネントのHeight、Centerの初期値を戻す 202 col.height = orgColHight; 203 col.center = orgVectColCenter; 204 } 205 } 206}

試したこと

下のサイトを参考にプレイヤーから標的に放物線を描いてとんでいくコードを書いた。
https://qiita.com/_udonba/items/a71e11c8dd039171f86c

補足情報(FW/ツールのバージョンなど)

環境:Windows10、Unity2020.1.0b8、VisualStudio2019

※「コンパス」の「まとい」のため技の画像
イメージ説明

ご指摘などありましたらよろしくお願いいたします。

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

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

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

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

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

guest

回答2

0

自己解決

localPositionを使って解決した。

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4using UnityChan; 5 6public class MatoiAbility : MonoBehaviour 7{ 8 public float matoiCircleSpeed = 0.01f; 9 public GameObject matoiCircle; 10 public GameObject playerObject; 11 Vector3 playerPos; 12 float shootTime; 13 bool shootBool; 14 ThrowingSphere t1; 15 16 // Start is called before the first frame update 17 void Start() 18 { 19 playerPos = playerObject.transform.position; 20 shootTime = Time.deltaTime; 21 shootBool = false; 22 t1 = GetComponent<ThrowingSphere>(); 23 } 24 25 private void Update() 26 { 27 // 28 if (shootBool) 29 { 30 if (shootTime > 2f) 31 { 32 shootTime = 0f; 33 shootBool = false; 34 matoiCircle.transform.position = playerPos; 35 matoiCircle.transform.localPosition = new Vector3(0, 0.06f, 3f); 36 } 37 shootTime++; 38 } 39 40 //MatoiAbilityが一定距離に達したら 41 if (matoiCircle.transform.localPosition.z >= 10.0f) 42 { 43 //Debug.Log("一定距離に達しましたZZZZZZZ"); 44 t1.ThrowingBall(); 45 } 46 } 47 48 // Update is called once per frame 49 public void FixedUpdate() 50 { 51 if (Input.GetMouseButton(0)) 52 { 53 matoiCircle.transform.localPosition += new Vector3(0f, 0f, matoiCircleSpeed); 54 } 55 if (Input.GetMouseButtonUp(0)) 56 { 57 shootBool = true; 58 } 59 } 60} 61

投稿2020/10/07 12:28

futonmin

総合スコア33

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

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

0

下のコードをベースに、プレイヤーオブジェクトの向いている方向(標的を決めず)に放物線を描いてまっすぐに弾をとばしたい。

それでしたら、角度と射出速度だけ決めておいてプレイヤーの向いている方向に打てば出来ると思います。

投稿2020/09/08 00:10

stdio

総合スコア3307

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問