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

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

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

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

Unity

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

Q&A

解決済

1回答

5760閲覧

Unity シューティングゲームでの移動について

naop

総合スコア10

C#

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

Unity

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

0グッド

1クリップ

投稿2016/10/08 07:02

編集2016/10/08 08:41

###前提・実現したいこと
Unityの学習でiPhone用シューティングゲームを制作しています。
自機の移動について質問させてください。

以下のサイト様のサンプルコードを参考に自機の相対移動を実装しました。
http://qiita.com/Nicky/items/d5fa514243cb65a5d4d4

このソースを元に自機のショットボタンをタッチする機能を付加したいです。
・移動しながらショットボタンを押すことで、移動しながらショットを発射できる
・ショットボタンを押している最中でも2本目の指で移動できる

###発生している問題
1本指での操作だと想定通りの移動をしてくれます。
(移動の指を置きなおしても、自機の現在地から移動を再開する)
ですが、2本指となると挙動がおかしくなります。

・移動のドラッグ操作(A)→ショットボタンを押しっぱなし(B)→移動の指の置きなおし(C)
└(A)の指を離した座標と(C)の座標の差分だけ自機が瞬間移動する。
瞬間移動後は正常な動作。

・ショットボタンを押しっぱなし(A)→移動のためにタッチ(B)
└(B)の位置へ自機が瞬間移動する。
瞬間移動後は(B)の指に追従する

###自機オブジェクトにアタッチしたソースコード

C#

1using UnityEngine; 2using System.Collections; 3 4public class PlayerMove : MonoBehaviour 5{ 6 7 //移動関連 8 public float adjustment = 0.3f;//カメラ位置で調整 9 public GameObject shotButton;//ショットボタン 10 public GameObject moveArea;//タッチ範囲 11 12 private Vector3 playerPos; 13 private Vector3 mousePos; 14 15 void Update() 16 { 17 playerControl(); 18 clamp(); 19 } 20 21 //プレイヤーの操作 22 private void playerControl() 23 { 24 //タッチ入力があったら 25 if (Input.touchCount > 0) 26 { 27 //全てのタッチを判定 28 for (int i = 0; i < Input.touchCount; i++) 29 { 30 //移動エリアを取得 31 Vector3 aTapPoint = Camera.main.ScreenToWorldPoint(Input.GetTouch(i).position); 32 Collider2D aCollider2d = Physics2D.OverlapPoint(aTapPoint); 33 GameObject obj = aCollider2d.transform.gameObject; 34 35 //移動エリアのタッチなら 36 if (obj == moveArea) 37 { 38 if (Input.GetMouseButtonDown(0)) 39 { 40 playerPos = this.transform.position; 41 mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition); 42 } 43 44 if (Input.GetMouseButton(0)) 45 { 46 Vector3 diff = Camera.main.ScreenToWorldPoint(Input.mousePosition) - mousePos; 47 48 diff = Camera.main.ScreenToWorldPoint(Input.GetTouch(i).position) - mousePos; 49 diff.z = 0.0f; 50 this.transform.position = playerPos + diff; 51 52 } 53 54 if (Input.GetMouseButtonUp(0)) 55 { 56 playerPos = Vector3.zero; 57 mousePos = Vector3.zero; 58 } 59 } 60 } 61 } 62 } 63 64 //プレイヤーの移動制限 65 void clamp() 66 { 67 // 画面左下のワールド座標をビューポートから取得 68 Vector2 min = Camera.main.ViewportToWorldPoint(new Vector2(0, 0)); 69 70 // 画面右上のワールド座標をビューポートから取得 71 Vector2 max = Camera.main.ViewportToWorldPoint(new Vector2(1, 1)); 72 73 // プレイヤーの座標を取得 74 Vector2 pos = transform.position; 75 76 // プレイヤーの位置が移動可能エリアに収まるように制限をかける 77 pos.x = Mathf.Clamp(pos.x, -2.0f, max.x); 78 pos.y = Mathf.Clamp(pos.y, min.y, 1.0f); 79 80 // 制限をかけた値をプレイヤーの位置とする 81 transform.position = pos; 82 } 83 84}

###試したこと
自機の移動制限であるclampメソッドをコメントアウトしても挙動は変わりませんでした。
当初はタッチした指の本数やFingerIDで制御しようかとしましたが、
どこをタッチしたかで制御したほうが簡単かと思い、上記のコードとしました。
上記のコードの修正以外にも、他に良い方法等がございましたらご教示ください。

###補足情報(言語/FW/ツール等のバージョンなど)
Unity5.4.1

###追記
複数タッチ時、Input.GetMouseButtonUp(0)が反応していないことが原因のようです。
この問題を解決するためのアルゴリズムを模索中ですが、よい案がございましたらご教示ください。

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

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

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

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

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

guest

回答1

0

自己解決

自己解決いたしました。
原因はInput.mousePositionを使用したことによるものだったようです。
最終的なコードは以下のようになりました。

C#

1using UnityEngine; 2using System.Collections; 3 4public class PlayerMove : MonoBehaviour 5{ 6 7 //移動関連 8 //public float adjustment = 0.3f;//カメラ位置で調整 9 public GameObject shotButton;//ショットボタン 10 public GameObject moveArea;//タッチ範囲 11 12 private Vector3 playerPos; 13 private Vector3 mousePos; 14 private int touchFinger = -1; 15 16 private Vector3 test; 17 18 void Start() 19 { 20 test = this.transform.position; 21 } 22 23 void Update() 24 { 25 playerControl(); 26 clamp(); 27 } 28 29 //プレイヤーの操作 30 private void playerControl() 31 { 32 //タッチ入力があったら 33 if (Input.touchCount > 0) 34 { 35 //全てのタッチを判定 36 for (int i = 0; i < Input.touchCount; i++) 37 { 38 //移動エリアを取得 39 Vector3 aTapPoint = Camera.main.ScreenToWorldPoint(Input.GetTouch(i).position); 40 Collider2D aCollider2d = Physics2D.OverlapPoint(aTapPoint); 41 GameObject obj = aCollider2d.transform.gameObject; 42 43 //移動エリアのタッチなら 44 if (obj == moveArea) 45 { 46 if (Input.GetTouch(i).phase == TouchPhase.Began) 47 { 48 touchFinger = Input.GetTouch(i).fingerId; 49 playerPos = this.transform.position; 50 mousePos = Camera.main.ScreenToWorldPoint(Input.GetTouch(i).position);//スクリーン座標をワールド座標へ 51 } 52 if ((Input.GetTouch(i).phase == TouchPhase.Moved) && Input.GetTouch(i).fingerId == touchFinger) 53 { 54 Vector3 prePos = this.transform.position; 55 Vector3 diff = Camera.main.ScreenToWorldPoint(Input.GetTouch(touchFinger).position) - mousePos; 56 diff.z = 0.0f; 57 this.transform.position = playerPos + diff; 58 } 59 60 if (Input.GetTouch(touchFinger).phase == TouchPhase.Ended) 61 { 62 playerPos = Vector3.zero; 63 mousePos = Vector3.zero; 64 } 65 } 66 67 } 68 } 69 } 70 71 //プレイヤーの移動制限 72 void clamp() 73 { 74 // 画面左下のワールド座標をビューポートから取得 75 Vector2 min = Camera.main.ViewportToWorldPoint(new Vector2(0, 0)); 76 77 // 画面右上のワールド座標をビューポートから取得 78 Vector2 max = Camera.main.ViewportToWorldPoint(new Vector2(1, 1)); 79 80 // プレイヤーの座標を取得 81 Vector2 pos = transform.position; 82 83 // プレイヤーの位置が移動可能エリアに収まるように制限をかける 84 pos.x = Mathf.Clamp(pos.x, -2.0f, max.x); 85 pos.y = Mathf.Clamp(pos.y, min.y, 1.0f); 86 87 // 制限をかけた値をプレイヤーの位置とする 88 transform.position = pos; 89 } 90 91} 92

投稿2016/10/08 19:30

naop

総合スコア10

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問