Unityのアプリで、画面タッチを利用したカメラのスクロール処理を実装します。今回は、スマホ画面のタッチ(スワイプ操作)にある程度追従する形でカメラを動かします。
また、スマホだけでなくPC操作の際はマウスでも操作できるように調整したいと思います。
プロジェクトの準備
まず初めに、今回は以下の記事で昔書いたスワイプ処理を利用します。
記事のサンプルコードの項目に、以下の「ScreenInput」がありますので、コピーしてスクリプトを作っておいてください。
スクリプトがコピーできたら、プロジェクト内に空のオブジェクトを作り、アタッチを行います。ちょうどプロジェクトが以下のような状態になればOKです。
※プラットフォームはiOSまたはAndroidに変更しておきます。
また、スクロール状態を確認しやすいように、Cubeのオブジェクトを一つ出し、さらにカメラを傾けて斜め下を見ている状態にしておきます。今回はこの位置を基準にスクロール処理を実装していきたいと思います。
サンプルコード
次に実際にカメラを動かすためのサンプルコードを実装します。以下のコードをコピーして、カメラにアタッチしてください。
■CameraMove
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CameraMove : MonoBehaviour
{
[SerializeField]
private ScreenInput _input;
[SerializeField]
private float Speed = 0.02f;
private bool MoveFlg;
private Vector3 pos;
// カメラ位置の更新
void Update()
{
if(_input.GetNowSwipe() != ScreenInput.SwipeDirection.NONE)
{
if(!MoveFlg) pos = this.transform.localPosition;
MoveFlg = true;
this.transform.localPosition = new Vector3(
pos.x - _input.GetSwipeRangeVec().x * Speed,
pos.y,
pos.z - _input.GetSwipeRangeVec().y * Speed);
}
else
{
MoveFlg = false;
}
}
}
メインカメラにアタッチしたら、ScreenInputの設定されているオブジェクトをインスペクターに設定してください。
これで、スクロール処理の実装は完了です。実際に再生して、Game画面でマウスの左クリックを押しっぱなしにしてカーソルを左右に動かしてみてください!
※スクロールのスピードが速いと感じた場合はインスペクターにある「Speed」の値を下げてみてください。
追加実装 ピンチイン・ピンチアウト
追加の実装として、ピンチインとピンチアウト(拡大と縮小)を実装してみたいと思います。こちらも比較的簡単に実装できるので、ぜひ試してみてください!
まずはScreenInputに以下のコードを追加します。行数は201行目付近でOKです。
// ピンチイン・ピンチアウト
private bool PinchFlg;
private float PinchDistance;
private float PinchSpeed = 0.02f;
private float PinchMin = -20;
private float PinchMax = 20;
private Vector3 UnityPinchStartPos;
private float StartDistance;
private float PinchAdj;
private void CheckPinch()
{
if (Input.touchCount == 2 || Input.GetMouseButton(1))
{
// Unity上での操作取得
if (Application.isEditor)
{
if (!PinchFlg) UnityPinchStartPos = Input.mousePosition;
PinchFlg = true;
if (UnityPinchStartPos.y < Input.mousePosition.y) PinchAdj = 1.0f;
else PinchAdj = -1.0f;
PinchDistance += Vector3.Distance(UnityPinchStartPos, Input.mousePosition) * PinchAdj * PinchSpeed * Time.deltaTime;
if (PinchDistance < PinchMin) PinchDistance = PinchMin;
else if (PinchMax < PinchDistance) PinchDistance = PinchMax;
}
// 端末上での操作取得
else
{
if (!PinchFlg) StartDistance = Vector2.Distance(Input.touches[0].position, Input.touches[1].position);
PinchFlg = true;
if (StartDistance < Vector2.Distance(Input.touches[0].position, Input.touches[1].position)) PinchAdj = 1.0f;
else PinchAdj = -1.0f;
PinchDistance += Vector2.Distance(Input.touches[0].position, Input.touches[1].position) * PinchAdj * PinchSpeed * Time.deltaTime;
if (PinchDistance < PinchMin) PinchDistance = PinchMin;
else if (PinchMax < PinchDistance) PinchDistance = PinchMax;
}
}
else
{
PinchFlg = false;
}
}
// 制限設定
public void SetPinchLimits(float _min, float _max, float _speed)
{
PinchMin = _min;
PinchMax = _max;
PinchSpeed = _speed;
}
// フラグ取得
public bool GetPinchFlg()
{
return PinchFlg;
}
// 距離取得
public float GetPinchDistance()
{
return PinchDistance;
}
追加後は48行目のUpdateに「CheckPinch()」を追加します。追加は51行目に行えばOKです。
ここまで追加できたら、上書き保存を行いCameraMoveの編集を行います。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CameraMove : MonoBehaviour
{
[SerializeField]
private ScreenInput _input;
[SerializeField]
private float Speed = 0.02f;
private bool MoveFlg;
private Vector3 pos;
private Camera _camera;
private float StartFieldOfView;
private void Start()
{
_input.SetPinchLimits(-20, 20, 0.2f);
_camera = this.transform.GetComponent<Camera>();
StartFieldOfView = _camera.fieldOfView;
}
// カメラ位置の更新
void Update()
{
if (_input.GetNowSwipe() != ScreenInput.SwipeDirection.NONE && !_input.GetPinchFlg())
{
if (!MoveFlg) pos = this.transform.localPosition;
MoveFlg = true;
this.transform.localPosition = new Vector3(
pos.x - _input.GetSwipeRangeVec().x * Speed,
pos.y,
pos.z - _input.GetSwipeRangeVec().y * Speed);
}
else
{
MoveFlg = false;
}
if (_input.GetPinchFlg())
{
_camera.fieldOfView = StartFieldOfView - _input.GetPinchDistance();
}
}
}
あとは上書き保存を行い再生をするだけです。Unityでの操作は、Game画面上で右クリックを押したままカーソルを上もしくは下に動かすことで拡大縮小が行われます。
Startで呼び出している「_input.SetPinchLimits(-20, 20, 0.2f);」でそれぞれのパラメーター制限を設定しています。第一引数から「最小値、最大値、移動速度」です。それぞれプロジェクトに合った数値を入れてお使いください。
ピンチインなどの操作を実装すると、拡大や縮小が完了した際に急にカメラがスクロールしてしまう現象が発生します。これはピンチインなどの操作中もスクロール距離を取得していることが原因です。
ScreenInputの以下の場所を「== 1」に変更すると現象が解消されます。気になる方は変更してみてください!
まとめ
以上がカメラスクロールと、追加でピンチイン・ピンチアウト(拡大縮小)についてのまとめでした。Unityだと結構簡単に実装ができるようになっているので、どんどん試してみてください!