こんにちは。
昨日に引き続きUnityに関して質問させて頂きます。
###解決したいこと
現在、以下画像のようにシューティングゲームを作成したいと思っています。
左下のUIが中央の青いオブジェクト(プレイヤー)を動かすジョイスティックで、右下のUIがプレイヤーから弾を発射させるボタンです。
スティックで移動させながら弾を発射出来るようにしたのですが、発射ボタンを押すとタップ感知が反応してしまい、ジョイスティックが右側に持っていかれてしまいプレイヤーの挙動がおかしなことになってしまいます。
移動や発射自体はそれぞれ問題無くうごくのですが、両立させる方法が中々思いつきません…
もし何か良いアイディア等あればご教授頂ければと思います。
編集追記
方法として、タップ処理でタップできる箇所の範囲を制限する。
あるいはドラッグ中の場合のタップを受け付けないといった物を思いついたのですが、
上手く実装できません……
C#
1using UnityEngine; 2using UnityEngine.UI; 3using UnityEngine.EventSystems; 4using System.Collections; 5using System.Collections.Generic; 6 7/// <summary> 8/// ジョイスティック 9/// </summary> 10public class Joystick : Graphic, IPointerDownHandler, IPointerUpHandler, IEndDragHandler, IDragHandler 11{ 12 13 //実際に動くスティック部分 14 [SerializeField] 15 [Header("実際に動くスティック部分(自動設定)")] 16 private GameObject _stick = null; 17 private const string STICK_NAME = "Stick"; 18 19 //スティックが動く範囲の半径 20 [SerializeField] 21 [Header("スティックが動く範囲の半径")] 22 private float _radius = 100; 23 24 //指を離した時にスティックが中心に戻るか 25 [SerializeField] 26 [Header("指を離した時にスティックが中心に戻るか")] 27 private bool _shouldResetPosition = true; 28 29 //現在地(x,y共に値が-1~1の範囲になる) 30 [SerializeField] 31 [Header("現在地(自動更新)")] 32 private Vector2 _position = Vector2.zero; 33 public Vector2 Position { get { return _position; } } 34 35 //スティックの位置(Setter) 36 private Vector3 _stickPosition 37 { 38 set 39 { 40 _stick.transform.localPosition = value; 41 _position = new Vector2( 42 _stick.transform.localPosition.x / _radius, 43 _stick.transform.localPosition.y / _radius 44 ); 45 } 46 } 47 48 //================================================================================= 49 //初期化 50 //================================================================================= 51 52 protected override void Awake() 53 { 54 base.Awake(); 55 Init(); 56 } 57 58 //初期化 59 private void Init() 60 { 61 //スティックを生成する必要があれば生成し、位置を中心に設定 62 CreateStickIfneeded(); 63 _stickPosition = Vector3.zero; 64 65 //スティックのImage取得(なければ追加)、タッチ判定を取られないようにraycastTargetをfalseに 66 Image stickImage = _stick.GetComponent<Image>(); 67 if (stickImage == null) 68 { 69 stickImage = _stick.AddComponent<Image>(); 70 } 71 stickImage.raycastTarget = false; 72 73 //タッチ判定を受け取れるようにRaycastTargetをTrueに 74 raycastTarget = true; 75 76 //タッチ判定をとる範囲は表示されないように透明に 77 color = new Color(0, 0, 0, 0); 78 } 79 80 //スティックを生成する必要があれば生成 81 private void CreateStickIfneeded() 82 { 83 //スティックが設定されていれば終了 84 if (_stick != null) 85 { 86 return; 87 } 88 89 //スティックが子にあるか検索、あれば取得し終了 90 if (transform.Find(STICK_NAME) != null) 91 { 92 _stick = transform.Find(STICK_NAME).gameObject; 93 return; 94 } 95 96 //スティック生成 97 _stick = new GameObject(STICK_NAME); 98 _stick.transform.SetParent(gameObject.transform); 99 _stick.transform.localRotation = Quaternion.identity; 100 } 101 102 //================================================================================= 103 //タップ 104 //================================================================================= 105 106 //タップ開始時 107 public void OnPointerDown(PointerEventData eventData) 108 { 109 //タップした瞬間にドラッグを開始した事にする 110 OnDrag(eventData); 111 } 112 113 //タップ終了時(ドラッグ終了時には呼ばれない) 114 public void OnPointerUp(PointerEventData eventData) 115 { 116 //タップした終了した時にドラッグを終了した時と同じ処理をする 117 OnEndDrag(eventData); 118 } 119 120 //================================================================================= 121 //ドラッグ 122 //================================================================================= 123 124 //ドラッグ終了時 125 public void OnEndDrag(PointerEventData eventData) 126 { 127 if (_shouldResetPosition) 128 { 129 //スティックを中心に戻す 130 _stickPosition = Vector3.zero; 131 } 132 } 133 134 //ドラッグ中 135 public void OnDrag(PointerEventData eventData) 136 { 137 //タップ位置を画面内の座標に変換し、スティックを移動 138 Vector2 screenPos = Vector2.zero; 139 RectTransformUtility.ScreenPointToLocalPointInRectangle(GetComponent<RectTransform>(), 140 new Vector2(Input.mousePosition.x, Input.mousePosition.y), 141 null, 142 out screenPos 143 ); 144 145 _stickPosition = screenPos; 146 147 //移動場所が設定した半径を超えてる場合は制限内に抑える 148 float currentRadius = Vector3.Distance(Vector3.zero, _stick.transform.localPosition); 149 if (currentRadius > _radius) 150 { 151 152 //角度計算 153 float radian = Mathf.Atan2(_stick.transform.localPosition.y, _stick.transform.localPosition.x); 154 155 //円上にXとYを設定 156 Vector3 limitedPosition = Vector3.zero; 157 limitedPosition.x = _radius * Mathf.Cos(radian); 158 limitedPosition.y = _radius * Mathf.Sin(radian); 159 160 _stickPosition = limitedPosition; 161 } 162 163 } 164 165 //================================================================================= 166 //更新 167 //================================================================================= 168 169#if UNITY_EDITOR 170 //Gizmoを表示する 171 private void OnDrawGizmos() 172 { 173 //スティックが移動できる範囲をScene上に表示 174 UnityEditor.Handles.color = Color.green; 175 UnityEditor.Handles.DrawWireDisc(transform.position, transform.forward, _radius * 0.5f); 176 } 177#endif 178 179}

回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/01/16 06:29
2019/01/16 09:50
2019/01/18 01:36
2019/01/18 09:06
2019/01/22 02:07