Skip to content

Instantly share code, notes, and snippets.

@su10
Created April 10, 2017 07:54
Show Gist options
  • Save su10/90d46b6b7baeeccba3c21f6041078082 to your computer and use it in GitHub Desktop.
Save su10/90d46b6b7baeeccba3c21f6041078082 to your computer and use it in GitHub Desktop.
【Unity】UniRxを使ったドラッグ移動のサンプル【UniRx】 ref: http://qiita.com/su10/items/ae3fd460a5762438a9d1
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using UniRx;
using UniRx.Triggers;
public class Drag : MonoBehaviour
{
public RectTransform target;
public bool horizontal = true;
public bool vertical = true;
public bool interactable {
get { return this.graphic.raycastTarget; }
set { this.graphic.raycastTarget = value; }
}
private Canvas _canvas;
public Canvas canvas {
get {
if (_canvas == null) {
_canvas = this.GetComponentInParent<Canvas>();
}
return _canvas;
}
set { _canvas = value; }
}
private Graphic _graphic;
private Graphic graphic {
get { return _graphic ?? (_graphic = this.GetComponent<Graphic>()); }
}
private ObservableEventTrigger _trigger;
private ObservableEventTrigger trigger {
get { return _trigger ?? (_trigger = this.gameObject.GetOrAddComponent<ObservableEventTrigger>()); }
}
void Awake()
{
if (this.graphic == null) {
Debug.LogWarning("Graphic component is required.");
this.gameObject.AddComponent<Image>().color = Color.clear;
}
if (this.target == null) {
this.target = this.GetComponent<RectTransform>();
}
this.trigger
.OnBeginDragAsObservable()
.Where(e => this.interactable && this.target)
.SelectMany(this.trigger.OnDragAsObservable())
.TakeUntil(this.trigger.OnEndDragAsObservable())
.TakeWhile(e => this.interactable && this.target)
.Select(e => GetPosition(e))
.Pairwise() // NOTE: Buffer(2,1)だと最後にペアでない値が来る
.RepeatUntilDestroy(this)
.Subscribe(OnDrag)
.AddTo(this);
}
private Vector3 GetPosition(PointerEventData eventData)
{
var screenPosition = eventData.position;
var result = Vector3.zero;
switch (this.canvas.renderMode) {
case RenderMode.ScreenSpaceOverlay:
case RenderMode.ScreenSpaceCamera:
RectTransformUtility.ScreenPointToWorldPointInRectangle(
this.target,
screenPosition,
eventData.pressEventCamera,
out result);
break;
case RenderMode.WorldSpace:
// TODO: WorldSpaceのCanvas対応
Debug.LogWarning("not supported RenderMode.WorldSpace.");
break;
}
return result;
}
private void OnDrag(Pair<Vector3> positions)
{
var deltaX = this.horizontal ? positions.Current.x - positions.Previous.x : 0;
var deltaY = this.vertical ? positions.Current.y - positions.Previous.y : 0;
this.target.position += new Vector3(deltaX, deltaY, 0);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment