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

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

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

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

受付中

ドラッグでキャラクターをエリアの端に移動する際に画面外へ移動しないようにしたい

Wings-12
Wings-12

総合スコア0

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

2回答

0評価

0クリップ

11閲覧

投稿2019/03/24 22:06

編集2022/01/12 10:55

お世話になります。

現在下記リンクの動画にあるように、
Androidのスマホ上でキャラクターをドラッグして移動し、
タップしたら、タップした位置に移動するように処理を作っています。

参考にした動画

今実現したい処理は、上記の移動処理を
下記の画像にある青いエリア内のみに実装することです。

問題は、上記のキャラクター移動の際に、下記画像のような、
青いエリアの右端へキャラクターが移動した際に、
キャラクターがずっと上に行くか下に行くかしてしまうことがあることです。

下記画像:
イメージ説明

作成したソースコード:

C#

using System.Collections; using System.Collections.Generic; using UnityEngine; using Common; using System; /// <summary> /// Player1を操作するクラス /// 主に移動処理を書いている。 /// </summary> public class Player1Controller : MonoBehaviour { // Player1のバトル開始座標 Vector3 player1_startPosition = new Vector3(-410.0f, -92.0f, 0.0f); // タッチパネルをタップした位置を取得 Touch touch; Vector3 touchPosition; // Player1を1マス分前へ表示 Vector3 oneSquareForward = new Vector3(60.0f, 0.0f); // ワールド座標でthis.transform.positionプロパティをアップデートする変数 Vector3 player1Position; // Rigidbody2Dを使ったドラッグ移動処理 Rigidbody2D rigidbody2D; Vector3 moveDirection; float moveSpeed = 20.0f; // Use this for initialization void Start() { // このtransform自身のlocalPositionを初期化 this.transform.localPosition = player1_startPosition; player1Position = this.transform.position; //Rigidbody2Dのコンポート取得 rigidbody2D = GetComponent<Rigidbody2D>(); } // Update is called once per frame void Update() { if (Input.touchCount > 0) { // タッチパネルをタップした位置を取得 touch = Input.GetTouch(0); touchPosition = Camera.main.ScreenToWorldPoint(touch.position); touchPosition.z = 0.0f; // 以下青エリア内から赤エリアへフリック入力すると //Player1が画面外へ飛んで行く不具合あり // 青エリア内の移動処理 if (touchPosition.y < BattleArea.myUpperSide && BattleArea.myLowerSide < touchPosition.y && touchPosition.x + oneSquareForward.x < BattleArea.myRightSide && BattleArea.myLeftSide < touchPosition.x + oneSquareForward.x) { // ドラッグ移動処理 moveDirection = touchPosition + oneSquareForward - this.transform.position; rigidbody2D.velocity = new Vector2(moveDirection.x, moveDirection.y) * moveSpeed; if (touch.phase == TouchPhase.Ended) { rigidbody2D.velocity = Vector2.zero; } } // 青エリア外右側の処理 else if (BattleArea.myRightSide - oneSquareForward.x <= touchPosition.x && // 敵エリアをタップしたら移動しないように自エリア最前列まで移動可能 touchPosition.x < BattleArea.myRightSide) { moveDirection = touchPosition + oneSquareForward - this.transform.position; if (touch.phase == TouchPhase.Ended) { rigidbody2D.velocity = Vector2.zero; } else if (touch.phase == TouchPhase.Stationary) { rigidbody2D.velocity = Vector2.zero; } else if (touch.phase == TouchPhase.Moved) { rigidbody2D.velocity = new Vector2(0.0f, moveDirection.y) * moveSpeed; if (this.transform.position.y <= BattleArea.myLowerSide) { player1Position.x = BattleArea.myRightSide; player1Position.y = BattleArea.myLowerSide; this.transform.position = player1Position; } else if (BattleArea.myUpperSide <= this.transform.position.y) { player1Position.x = BattleArea.myRightSide; player1Position.y = BattleArea.myUpperSide; this.transform.position = player1Position; } } else { rigidbody2D.velocity = new Vector2(0.0f, moveDirection.y) * moveSpeed; } Debug.Log("touch.phaseの中身は:" + touch.phase); Debug.Log("rigidbody2D.velocityの値は:" + rigidbody2D.velocity); } } } }
using System.Collections; using System.Collections.Generic; using UnityEngine; namespace Common { public static class BattleArea { // 1マス分の移動量 public const float oneSquareUpDown = 162.0f; public const float oneSquareRightLeft = 165.0f; // 自エリアにおける各辺の座標 public const float myUpperSide = 210.0f; public const float myLowerSide = -33.0f; public const float myLeftSide = 98.0f; public const float myRightSide = 289.0f; } }

解決のために試したことは、
まず、青いエリアから赤いエリアへフリック入力するようにキャラクターを移動させると、上記のソースコードの中の条件文(下記のソースコードの箇所)
の中に入るので、その際のtouch.phaseの値と、rigidbody2D.velocityの値を確認しました。

// 青エリア外右側の処理 else if (BattleArea.myRightSide - oneSquareForward.x <= touchPosition.x && // 敵エリアをタップしたら移動しないように自エリア最前列まで移動可能 touchPosition.x < BattleArea.myRightSide)

確認したtouch.phaseの値と、rigidbody2D.velocityの値:
イメージ説明

確認結果から、touch.phaseがMovedのときにrigidbody2D.velocityが処理され、
青いエリアの外へキャラクターが移動してしまうことが分かったので、
Movedのときの処理を修正しようと思いました。

しかしどう修正したら、実現したい処理を作れるのか分かりませんでした。

Movedのときに、rigidbody2D.velocity = Vector2.zeroしたら、
今度は青いエリアの右端でキャラクターが動かなくなってしまうし、

そうであれば、Movedのときはthis.transform.positionの座標をプロパティを使って更新しようとしたら、
rigidbody2D.velocityが処理され続けてしまうのか、キャラクターが青エリア外へ移動してしまうし...

どうか解決のためのアドバイスをお願いします。

良い質問の評価を上げる

以下のような質問は評価を上げましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

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

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

teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

  • プログラミングに関係のない質問
  • やってほしいことだけを記載した丸投げの質問
  • 問題・課題が含まれていない質問
  • 意図的に内容が抹消された質問
  • 過去に投稿した質問と同じ内容の質問
  • 広告と受け取られるような投稿

評価を下げると、トップページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

sakura_hana
sakura_hana

2019/03/25 02:42

そもそも(強制的に静止させる目的以外で)velocityに対し直接値を代入してしまうのはあまりよくない(物理演算が狂うかもしれないから)というのはさておき。 「青いエリアの右端でキャラクターが動かなくなってしまう」のは意図に反するような書き方をしていますが、希望する動きはどんなものでしょうか?
Wings-12
Wings-12

2019/03/25 10:49

アドバイスとご指摘をありがとうございます。 質問内容を修正し、希望する動きを加筆ました。 まだわかりくいところがありましたら、大変申し訳ありませんが、もしよろしければご指摘をお願いします。

まだ回答がついていません

会員登録して回答してみよう

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

ただいまの回答率
87.20%

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

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

質問する

関連した質問

同じタグがついた質問を見る

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。