//tips
//ボタンドラッグ操作で対象オブジェクトを操作する
imageをオブジェクトと連動させ、imageのドラッグ操作で対象オブジェクトを操作する。
先日までのエラーの要因はVector3 TargetPos = Camera.main.ScreenToWorldPoint(test1.transform.position)の部分がCamera.main.ScreenToWorldPoint(test1pos
);となっていたことにある。
Startでtestposにtestの座標を代入しているが、この場合実行開始時点でのtestの座標が変数に入り、その後testが移動してもtestposの値は変わらないことから起こっていた。Vector3等は参照型ではないので要注意。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class DragEventTest2 : MonoBehaviour
{
[SerializeField] private GameObject test;//操作対象sphere
[SerializeField] private GameObject test1;//操作用image
Vector3 testpos;//操作対象sphere
Vector3 test1pos;//操作用image
//imageをドラッグで操作することで、その移動分を操作対象オブジェクトに加算したい
void Start()
{
testpos = test.transform.position;
test1pos = test1.transform.position;
}
void Update()
{
Vector3 TargetPos = Camera.main.ScreenToWorldPoint(test1.transform.position);//ワールド座標への変換
//TargetPos.z = 0;
//testpos += test1pos;
//test.transform.position += TargetPos;
Vector3 AddPos = new Vector3 (7,5,0);//sphere初期位置調整用
test.transform.position = TargetPos - AddPos;
}
}
Imageの変化分ではなく初期位置も操作対象に影響してしまうためその分はAddPosで除外するようにしている。
Imageの初期地点もワールド座標でだし、シンプルにimageの移動分のみを操作対象に加えるように変更した。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class DragEventTest2 : MonoBehaviour
{
[SerializeField] private GameObject test;//操作対象sphere
[SerializeField] private GameObject test1;//操作用image
Vector3 testpos;//操作対象sphere
Vector3 test1pos;//操作用image
//imageをドラッグで操作することで、その移動分を操作対象オブジェクトに加算したい
void Start()
{
testpos = test.transform.position;
test1pos = test1.transform.position;
}
void Update()
{
Vector3 TargetPos = Camera.main.ScreenToWorldPoint(test1.transform.position);//ワールド座標への変換
//TargetPos.z = 0;
Vector3 STargetPos = Camera.main.ScreenToWorldPoint(test1pos);//image初期地点のワールド座標
//testpos += test1pos;
//test.transform.position += TargetPos;
//Vector3 AddPos = new Vector3 (7,5,0);//sphere初期位置調整用
Vector3 AddPos = TargetPos - STargetPos;
test.transform.position = testpos + AddPos;
}
}
//スクリプトでオブジェクトの回転を実装する
カメラの回転操作を行いたいのでまずはスクリプトでオブジェクトの回転を実装する。
transform.Rotateを使用して実装した。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ORotate : MonoBehaviour
{
// Start is called before the first frame update
void Update()
{
transform.Rotate(new Vector3(0, 0, 5));
}
}
//image画像のドラッグ操作でオブジェクトの回転を操作する
操作対象であるオブジェクトの回転をVector3 worldAngle = testTransform.eulerAngles;で取得し、その変数をworldAngle.y = AddPos.x * 90;のように imageの移動量であるAddPosの位置の変化と連動させる。
//image画像のドラッグ操作でカメラの回転を操作する
Subcameraにもphysics2Draycasterの付与およびcameraのprojectionをorthographicに変更することを忘れない。
orthographicは、Perspectiveのようにそのままの景色をレンダリング(遠近法を使った描写)するのではなく、景色を平面に落とし込んで(平行投射を使った描写)描写する点で異なる。
ビューの近さはsizeを小さくするほど近づき、大きくするほど遠のく。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class DragRotate : MonoBehaviour
{
[SerializeField] private GameObject test;//操作対象sphere
[SerializeField] private GameObject test1;//操作用image
Transform testTransform;//操作対象sphere
Vector3 test1pos;//操作用image
//imageをドラッグで操作することで、その移動分を操作対象オブジェクトに加算したい
void Start()
{
testTransform = test.gameObject.GetComponent<Transform>();
test1pos = test1.transform.position;
}
void Update()
{
Vector3 TargetPos = Camera.main.ScreenToWorldPoint(test1.transform.position);//現image座標のワールド座標への変換
//TargetPos.z = 0;
Vector3 STargetPos = Camera.main.ScreenToWorldPoint(test1pos);//image初期地点のワールド座標
Vector3 AddPos = TargetPos - STargetPos;
Vector3 worldAngle = testTransform.eulerAngles;
Debug.Log(AddPos.x);
worldAngle.y = AddPos.x * 10;
testTransform.eulerAngles = worldAngle;
//test.transform.position = testpos + AddPos;
}
}
//ドラッグ移動させたimageとsubcameraの回転を初期化する
ドラッグ移動させたimage座標とsubcameraの回転をpublic void OnEndDrag(PointerEventData eventData)を使用して初期化する。
また、空オブジェクトを使用しなくても、imageに下記スクリプトをアタッチすれば直接操作できるようにした。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class DragEventCamera : MonoBehaviour, IDragHandler, IEndDragHandler
{
[SerializeField] private GameObject test;//操作対象subcamera
Transform testTransform;//操作対象subcamera
Vector3 test1pos;//操作用image
//imageをドラッグで操作することで、その移動分を操作対象オブジェクトに加算したい
Vector3 testbaseangle;
void Start()
{
testTransform = test.gameObject.GetComponent<Transform>();
test1pos = transform.position;
testbaseangle = testTransform.eulerAngles;
}
public void OnDrag(PointerEventData data)
{
Vector3 TargetPos = data.position;
TargetPos.z = 0;
transform.position = TargetPos;
//追加
Vector3 FinalPos = Camera.main.ScreenToWorldPoint(transform.position);//現image座標のワールド座標への変換
//TargetPos.z = 0;
Vector3 STargetPos = Camera.main.ScreenToWorldPoint(test1pos);//image初期地点のワールド座標
Vector3 AddPos = FinalPos - STargetPos;
Vector3 worldAngle = testTransform.eulerAngles;
worldAngle.y = AddPos.x * 10;
testTransform.eulerAngles = worldAngle;
}
public void OnEndDrag(PointerEventData eventData)
{
testTransform.eulerAngles = testbaseangle;//subcameraの角度を初期値へ
transform.position = test1pos;//imageの場所を初期位置へ
}
}