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

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

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

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

Unity3D

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

Unity

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

Q&A

解決済

2回答

1382閲覧

2点間でのワープ機能について【動画あり】

Benway

総合スコア3

C#

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

Unity3D

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

Unity

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

0グッド

0クリップ

投稿2023/01/30 13:17

前提

Unityでワープ機能、A地点からB地点、B地点からA地点を作りたくてコードを書きました。
しかし挙動がおかしくA地点からB地点までは正常に動作するのですが、B地点からA地点へ行こうとすると何故かB地点からB地点にワープとなってしまい理由もわからず困っています。
https://youtu.be/WwO_63G4hx0

実現したいこと

A地点からB地点、B地点からA地点へのワープ、またそのオブジェクトのプレハブ化

発生している問題・エラーメッセージ

該当のソースコード

C#

1public class Warp : MonoBehaviour 2{ 3 4 public GameObject player; //自分自身です、Unity自機を入れています 5 6 public GameObject nextWarpObject;//次にワープしたいオブジェクトを入れるやつです 7 8 private Vector3 trans; //いろんなサイトを見て回った結果にできたnextWarpObjectのpositionの格納先です 9 10 PlayerController script; //プレイヤーを動かすためのスクリプトを外部から引っ張ってきています 11 12 PlayerInput playerInput; //Fキーを押したら移動するよという動作を作りたかったのでInputActioinを使用しています 13 14 15 16 // Update is called once per frame 17 18 private void Awake() 19 { 20 21 script = player.GetComponent<PlayerController>(); //代入しています 22 23 playerInput = new PlayerInput(); //InputActionです 24 25 26 27 playerInput.Player.CoverAction.started += CoverAction;//同 28 29 playerInput.Enable();//同 30 } 31 32 private void Start() 33 { 34 trans = nextWarpObject.transform.position; //ここでtransの中に”移動先”のオブジェクトの座標を代入しています。 35 Debug.Log(trans); //移動先の座標の確認です、しっかりと別々の座標になってました。 36 } 37 private void CoverAction(InputAction.CallbackContext obj) 38 { 39 if (script.onWarpPoint) 40 { 41 Debug.Log("Warp"); 42 43 player.transform.position = trans; //押された時にplayerの座標を書き換えます 44 } 45 } 46 47 48 private void Update() 49 { 50 51 } 52 53 void OnTriggerStay(Collider other) //これはBoxコライダーの中にいるときに自分の頭上に目印を出すスクリプトです 54 { 55 56 if (other.gameObject.tag == "Player") 57 { 58 Debug.Log("CanWarp"); 59 script.onWarpPoint = true;  60 61 62 63 } 64 } 65 66 private void OnTriggerExit(Collider other) 67 { 68 script.onWarpPoint = false; 69 } 70}

試したこと

上記のように一行一行丁寧に見ました、またDebug.Logでお互いの座標が違うことを確認しました。
A地点とB地点をつなげるのではなく、移動先の指定を空のオブジェクトに指定しても同じ状況になります。

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

Unity2021.3.15f1

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

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

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

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

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

Benway

2023/02/01 11:33

BAの内容を忘れないようにここにメモをします、 今回のバグが起こった原因は ①CoverActioinの登録はAwake以外で出来るということを知らなかった ②おんなじスクリプトを使いまわしていると一つの変数に2通りのパターンが登録されることを知らなかった ①についてはInputActioinの使い方の中でAwakeで登録した方がいいと書いてあったためその通りに使ったがほかの場所でも使えるということを知らなかったため起きてしまった。これは知識不足であった ②についてが一番重要で、同じスクリプト、(今回はWarp)を複数のオブジェクトアタッチしたときに複数のオブジェクトそれそれのスクリプトが独立していると考えていたが実際はそうではなく、それそれの値を独立していない、一つのスクリプトが管理していたという動作をしていた。そのため一つの変数の中に複数の値が入り、それらの値が2つあると2回実行する、3つあると3回実行する、という動作をしていたということになる。そのため今回のBAでは、値の登録を重複させないために、フラグを踏んだ時に変数に値を代入するという処理を行ったと思われます。
guest

回答2

0

ベストアンサー

Awakeの中でplayerInputを通してPlayerにCoverAction(ワープのメソッド)を登録してますよね。

C#

1playerInput.Player.CoverAction.started += CoverAction;//同

で、今回はWarp(ワープオブジェクト)が2つ置いてありますよね。
ということは、WarpのAwakeは2回呼ばれてるってことですよね。
つまりゲームを起動時、Playerには2箇所のCoverAction(ワープ処理)が登録されるということですよね。

Acrtionを発火すると登録されている処理は全て実行されます。
今回でいうとPlayer.CoverAction.startedを実行するたびに「1-1のCoverAction」と「1-2のCoverAction」が順番に実行されるということです。
コンソールにもワープが行われるたびに"Warp"が2ずつ増えてますよね?
これは「1-2にワープした後、1-1にワープする」という2回のワープ処理が一度に行われているからです。
なので1-1を踏んでも1-1に飛ばされているんじゃないでしょうか?

故にワープ処理の登録&削除を
「ワープに触れた瞬間、ワープ処理をPlayerに登録する」
「ワープが終わったら、ワープ処理をPlayerから削除する」
という風にして、「ワープする時、Playerには1つのワープ処理しか登録されていない状態」にすれば動くんじゃないでしょうか。

つまり

C#

1playerInput.Player.CoverAction.started += CoverAction;

をAwakeからOnTriggerStayに移し、CoverAction内に

C#

1playerInput.Player.CoverAction.started -= CoverAction;

を追加で書く的な感じです。

投稿2023/01/31 04:00

編集2023/01/31 10:18
UnchFullburst

総合スコア663

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

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

Benway

2023/02/01 10:42

出来ました、ありがとうございます
guest

0

B→AにワープしてからすぐにA→Bに再度ワープしていないでしょうか?
PlayerControllerにワープが有効状態かどうかのフラグ(仮にbool isWarpEnable)を持たせて、最初はtrueにしておき、

C#

1 private void CoverAction(InputAction.CallbackContext obj) 2 { 3 if (script.onWarpPoint && script.isWarpEnable ) 4 { 5 Debug.Log("Warp"); 6 7 player.transform.position = trans; //押された時にplayerの座標を書き換えます 8 script.isWarpEnable = false; 9 } 10 } 11 12 private void OnTriggerExit(Collider other) 13 { 14 script.onWarpPoint = false; 15 script.isWarpEnable = true; 16 } 17

こんな感じで試してみてください。

投稿2023/01/30 14:10

編集2023/01/30 14:11
ganta7188

総合スコア436

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

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

Benway

2023/01/30 15:32

出来なかったです、再起動してもダメです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問