こんばんは、ちきなるです。
今、カードゲームを作っているのですが・・・。
Scroll Viewが、言うことを聞いてくれない!!
あーしたい。
こーしたい。
色々あるのですが、思うように動いてくれません。
ネットで調べたり、実際に動かしたり、試行錯誤。
何とか、
最低限の動きが出来たので、書いておきます。
具体的に言うと、
スクロールの制御。
条件を満たすと、スクロールをして、
満たさないと、スクロールをしない。
(カードの一覧をスクロールさせたり、カードを掴んだりしたい)
参考にさせて、いただいたのは、
こちらのブログ。
なのですが、
私の頭では、理解しきれませんでした。
なんとなくは、わかるのですが、
応用出来るほど、理解出来ませんでした。
(ゲームに合わせた調整が出来なった)
なので、
これは、こうかな?
と、試して、上手くいった方法を書いておきます。
ScrollRectを継承させる
まずは、
Scriptを作って、ScrollRectを継承させます。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
//ScrollRectを継承する
public class ScrollTest : ScrollRect
{
}
これをすると、
Scroll Viewでのマウスイベントを取ることが出来ます。
ですが、
ScrollRectを継承した後、Scroll Viewにスクリプトを追加しようとすると、エラーが出ます。
(Inspectorビューで追加)
(ScrollRectが、重複しているよ。って、エラーです)
なので、
元々ついている、ScrollRectを削除(Remove Component)して、
追加します。
設定は、リセットされるので、入力し直す必要があります。
Content, Viewport, Horizontal Scrollbar, Vertival Scrollbarを忘れない。
(Scroll Viewを追加した時、自動で入力されるので、ScrollRectを変える時は、要注意)
ScrollRectのイベント
ScrollRectで、使うイベントは4つ。
//Scroll Viewでマウスボタン押下時
public override void OnInitializePotentialDrag(PointerEventData eventData)
{
//継承元のOnInitializePotentialDrag処理を呼び出す
base.OnInitializePotentialDrag(eventData);
}
//マウスボタン押下中に初めてマウスを動かした時
public override void OnBeginDrag(PointerEventData eventData)
{
//継承元のOnBeginDrag処理を呼び出す
base.OnBeginDrag(eventData);
}
//マウスボタン押下中にマウスを動かしている間
public override void OnDrag(PointerEventData eventData)
{
//継承元のOnDrag処理を呼び出す
base.OnDrag(eventData);
}
//マウスボタンを放した時
public override void OnEndDrag(PointerEventData eventData)
{
//継承元のOnEndDrag処理を呼び出す
base.OnEndDrag(eventData);
}
Scroll Viewで、マウスボタンを押下した時に、
OnInitializePotentialDragが、呼ばれます。
(左右どちらでも呼ばれる)
その後、
ボタン押下中に、始めてマウスを動かすと、
OnBeginDragが、呼ばれます。
ボタン押下中に、マウスを動かしている間は、
OnDragが、呼ばれ続ける。
(動かしている間は、何度も呼ばれる。
止めている間は、呼ばれない)
ボタンを離すと、
OnEndDragが、呼ばれます。
OnInitializePotentialDrag | マウスボタンを押下した時 |
OnBeginDrag | ボタン押下中にマウスが初めて動いた時 |
OnDrag | ボタン押下中にマウスが動いている間 |
OnEndDrag | マウスボタンを離した時 |
スクロールを止める
どうやって、スクロールを止めるのか。
それは、
継承元のOnBeginDragまたはOnDragを呼ばない。
(どちらかを呼ばないようにすると、スクロールしなくなりました)
(動き的には、OnDragを呼ばないようにする方が、良い気がします)
//マウスボタン押下中にマウスを動かしている間
public override void OnDrag(PointerEventData eventData)
{
//継承元のOnDrag処理を呼び出す
//base.OnDrag(eventData);
}
こうすると、スクロールしなくなります。
ですが、
このままだと、Scroll Viewの意味が無くなるので、
条件分岐で、スクロールの有無を判定させます。
(マウスの動きが、
横方向なら、スクロールする
縦方向なら、スクロールしない)
//スクロールするかどうかのフラグ
private bool MoveChack = false;
//マウスボタン押下中に初めてマウスを動かした時
public override void OnBeginDrag(PointerEventData eventData)
{
//継承元のOnBeginDrag処理を呼び出す
base.OnBeginDrag(eventData);
if (Mathf.Abs(eventData.delta.x) < Mathf.Abs(eventData.delta.y))
{
MoveChack = false;
return;
}
MoveChack = true;
}
//マウスボタン押下中にマウスを動かしている間
public override void OnDrag(PointerEventData eventData)
{
if(MoveChack)
//継承元のOnDrag処理を呼び出す
base.OnDrag(eventData);
}
eventData.deltaってのは、マウスの動いた距離が見れます。
説明だと、最後の更新からのデルタポインタ。
と、なっているのですが、デルタポインタがわかりません。
多分、
最後の更新時のマウスの位置から、現在のマウスの位置の方向ベクトルかな?
と、思います。
(Mathf.Absで、絶対値を出して比較すれば、
縦横どちらが大きく動いたのか、わかります)
まとめ。
ScrollRecを継承すると、
Scroll Viewに対する、マウスのイベントが取れます。
(IInitializePotentialDragHandler, IBeginDragHandler, IEndDragHandler, IDragHandlerこれを継承させて、Scroll Viewにスクリプトを付けても同じ事が出来ます)
・OnInitializePotentialDragが、ボタン押下時。
・OnBeginDragが、ボタン押下中にマウスが始めて動いた時
・OnDragが、ボタン押下中に、マウスが動いている間
・OnEndDragが、ボタンを離した時。
OnInitializePotentialDrag | マウスボタンを押下した時 |
OnBeginDrag | ボタン押下中にマウスが初めて動いた時 |
OnDrag | ボタン押下中にマウスが動いている間 |
OnEndDrag | マウスボタンを離した時 |
継承元の、
OnBeginDragまたは、OnDrag、
どちらかを呼ばないようにすると、スクロールしなくなります。
(OnDragを止める方が良さそう)
マウスが横に動いた時、スクロールする。
マウスが縦に動いた時、スクロールしない。
(1度のクリック中常に)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
//ScrollRectを継承する
public class ScrollTest : ScrollRect
{
//Scroll Viewでマウスボタン押下時
public override void OnInitializePotentialDrag(PointerEventData eventData)
{
//継承元のOnInitializePotentialDrag処理を呼び出す
base.OnInitializePotentialDrag(eventData);
}
//スクロールするかどうかのフラグ
private bool MoveChack = false;
//マウスボタン押下中に初めてマウスを動かした時
public override void OnBeginDrag(PointerEventData eventData)
{
//継承元のOnBeginDrag処理を呼び出す
base.OnBeginDrag(eventData);
//マウスの動きが縦か横の判定
if (Mathf.Abs(eventData.delta.x) < Mathf.Abs(eventData.delta.y))
{
//縦ならスクロールを止める
MoveChack = false;
return;
}
//横ならスクロールする
MoveChack = true;
}
//マウスボタン押下中にマウスを動かしている間
public override void OnDrag(PointerEventData eventData)
{
//横の時スクロールする
if(MoveChack)
//継承元のOnDrag処理を呼び出す
base.OnDrag(eventData);
}
//マウスボタンを放した時
public override void OnEndDrag(PointerEventData eventData)
{
//継承元のOnEndDrag処理を呼び出す
base.OnEndDrag(eventData);
}
}
てな感じです。
スクロールを止めることが出来たので、
縦方向にドラッグした時、
カードを掴んで、デッキに追加する処理を作れば完璧です!!
コメント