お世話になります。
現在下記リンクの動画にあるように、
Androidのスマホ上でキャラクターをドラッグして移動し、
タップしたら、タップした位置に移動するように処理を作っています。
今実現したい処理(希望する動き)は、上記の移動処理を以下の①、②ように実装することです。
①下記画像の明るい黄色で囲っている青いエリア内でドラッグしたときに、キャラクターがドラッグした動きに追従して移動すること。
②下記画像の明るい黄色で囲っている青いエリア内でタップしたときに、タップした位置まで、キャラクターがタップする前の位置からずっと描画されながら(ワープするのではなく)直線的に移動すること。
問題は、上記のキャラクター移動の際に、下記画像のような、
青いエリアの右端へキャラクターが移動した際に、
キャラクターがずっと上に行くか下に行くかしてしまうことがあることです。
作成したソースコード:
C#
1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4using Common; 5using System; 6/// <summary> 7/// Player1を操作するクラス 8/// 主に移動処理を書いている。 9/// </summary> 10public class Player1Controller : MonoBehaviour 11{ 12 // Player1のバトル開始座標 13 Vector3 player1_startPosition = new Vector3(-410.0f, -92.0f, 0.0f); 14 // タッチパネルをタップした位置を取得 15 Touch touch; 16 Vector3 touchPosition; 17 // Player1を1マス分前へ表示 18 Vector3 oneSquareForward = new Vector3(60.0f, 0.0f); 19 // ワールド座標でthis.transform.positionプロパティをアップデートする変数 20 Vector3 player1Position; 21 // Rigidbody2Dを使ったドラッグ移動処理 22 Rigidbody2D rigidbody2D; 23 Vector3 moveDirection; 24 float moveSpeed = 20.0f; 25 26 // Use this for initialization 27 void Start() 28 { 29 // このtransform自身のlocalPositionを初期化 30 this.transform.localPosition = player1_startPosition; 31 player1Position = this.transform.position; 32 33 //Rigidbody2Dのコンポート取得 34 rigidbody2D = GetComponent<Rigidbody2D>(); 35 } 36 // Update is called once per frame 37 void Update() 38 { 39 if (Input.touchCount > 0) 40 { 41 // タッチパネルをタップした位置を取得 42 touch = Input.GetTouch(0); 43 touchPosition = Camera.main.ScreenToWorldPoint(touch.position); 44 touchPosition.z = 0.0f; 45 46 // 以下青エリア内から赤エリアへフリック入力すると 47 //Player1が画面外へ飛んで行く不具合あり 48 49 // 青エリア内の移動処理 50 if (touchPosition.y < BattleArea.myUpperSide && 51 BattleArea.myLowerSide < touchPosition.y && 52 touchPosition.x + oneSquareForward.x < BattleArea.myRightSide && 53 BattleArea.myLeftSide < touchPosition.x + oneSquareForward.x) 54 { 55 // ドラッグ移動処理 56 moveDirection = touchPosition + oneSquareForward - this.transform.position; 57 rigidbody2D.velocity = new Vector2(moveDirection.x, moveDirection.y) * moveSpeed; 58 if (touch.phase == TouchPhase.Ended) 59 { 60 rigidbody2D.velocity = Vector2.zero; 61 } 62 } 63 // 青エリア外右側の処理 64 else if (BattleArea.myRightSide - oneSquareForward.x <= touchPosition.x && 65 // 敵エリアをタップしたら移動しないように自エリア最前列まで移動可能 66 touchPosition.x < BattleArea.myRightSide) 67 { 68 moveDirection = touchPosition + oneSquareForward - this.transform.position; 69 if (touch.phase == TouchPhase.Ended) 70 { 71 rigidbody2D.velocity = Vector2.zero; 72 } 73 else if (touch.phase == TouchPhase.Stationary) 74 { 75 rigidbody2D.velocity = Vector2.zero; 76 } 77 else if (touch.phase == TouchPhase.Moved) 78 { 79 rigidbody2D.velocity = new Vector2(0.0f, moveDirection.y) * moveSpeed; 80 if (this.transform.position.y <= BattleArea.myLowerSide) 81 { 82 player1Position.x = BattleArea.myRightSide; 83 player1Position.y = BattleArea.myLowerSide; 84 this.transform.position = player1Position; 85 } 86 else if (BattleArea.myUpperSide <= this.transform.position.y) 87 { 88 player1Position.x = BattleArea.myRightSide; 89 player1Position.y = BattleArea.myUpperSide; 90 this.transform.position = player1Position; 91 } 92 } 93 else 94 { 95 rigidbody2D.velocity = new Vector2(0.0f, moveDirection.y) * moveSpeed; 96 } 97 Debug.Log("touch.phaseの中身は:" + touch.phase); 98 Debug.Log("rigidbody2D.velocityの値は:" + rigidbody2D.velocity); 99 } 100 } 101 } 102}
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が処理され続けてしまうのか、キャラクターが青エリア外へ移動してしまうし...
どうか解決のためのアドバイスをお願いします。