从下面的代码中,缩放是用两个手指(捏到缩放)进行的,但是我的旋转不能通过单次滑动来进行。为了进行测试,我添加了文本。滑动时,文本通过“一键移动”进行更新屏幕。
无法理解缩放正常,但旋转无效。我下载了最新的ARcore SDK。我使用HelloAR示例场景放置了对象,在检测到飞机时我会在HeartModel上实例化该对象。>
public class HelloARController : MonoBehaviour
{
/// <summary>
/// The first-person camera being used to render the passthrough camera image (i.e. AR
/// background).
/// </summary>
public Camera FirstPersonCamera;
/// <summary>
/// A prefab for tracking and visualizing detected planes.
/// </summary>
public GameObject DetectedPlanePrefab;
/// <summary>
/// A model to place when a raycast from a user touch hits a plane.
/// </summary>
public GameObject AndyPlanePrefab;
public GameObject HeartModel;
/// <summary>
/// A model to place when a raycast from a user touch hits a feature point.
/// </summary>
public GameObject AndyPointPrefab;
/// <summary>
/// The rotation in degrees need to apply to model when the Andy model is placed.
/// </summary>
private const float k_ModelRotation = 180.0f;
/// <summary>
/// True if the app is in the process of quitting due to an ARCore connection error,
/// otherwise false.
/// </summary>
private bool m_IsQuitting = false;
public static HelloARController helloinstance;
public GameObject ExampleControl;
//To spawn only once
private bool spawned = false;
private void Start()
{
helloinstance = this;
}
/// <summary>
/// The Unity Update() method.
/// </summary>
public void Update()
{
_UpdateApplicationLifecycle();
// If the player has not touched the screen, we are done with this update.
Touch touch;
if (Input.touchCount < 1 || (touch = Input.GetTouch(0)).phase != TouchPhase.Began)
{
return;
}
// Should not handle input if the player is pointing on UI.
if (EventSystem.current.IsPointerOverGameObject(touch.fingerId))
{
return;
}
// Raycast against the location the player touched to search for planes.
TrackableHit hit;
//TrackableHitFlags raycastFilter = TrackableHitFlags.PlaneWithinPolygon |
//TrackableHitFlags.FeaturePointWithSurfaceNormal;
TrackableHitFlags raycastFilter = TrackableHitFlags.PlaneWithinInfinity;
if (Frame.Raycast(touch.position.x, touch.position.y, raycastFilter, out hit) && spawned==false)
{
// Use hit pose and camera pose to check if hittest is from the
// back of the plane, if it is, no need to create the anchor.
if ((hit.Trackable is DetectedPlane) &&
Vector3.Dot(FirstPersonCamera.transform.position - hit.Pose.position,
hit.Pose.rotation * Vector3.up) < 0)
{
Debug.Log("Hit at back of the current DetectedPlane");
}
else
{
// Choose the Andy model for the Trackable that got hit.
GameObject prefab;
if (hit.Trackable is FeaturePoint)
{
//prefab = AndyPointPrefab;
prefab = null;
}
else
{
// prefab = AndyPlanePrefab;
prefab = HeartModel;
}
// Instantiate Andy model at the hit pose.
var andyObject = Instantiate(prefab, hit.Pose.position, hit.Pose.rotation);
// Compensate for the hitPose rotation facing away from the raycast (i.e.
// camera).
//andyObject.transform.Rotate(0, k_ModelRotation, 0, Space.Self);
// andyObject.transform.Rotate(0, 0, 0, Space.Self);
// Create an anchor to allow ARCore to track the hitpoint as understanding of
// the physical world evolves.
var anchor = hit.Trackable.CreateAnchor(hit.Pose);
// Make Andy model a child of the anchor.
andyObject.transform.parent = anchor.transform;
}
spawned = true;
}
}
/// <summary>
/// Check and update the application lifecycle.
/// </summary>
private void _UpdateApplicationLifecycle()
{
// Exit the app when the 'back' button is pressed.
if (Input.GetKey(KeyCode.Escape))
{
Application.Quit();
}
// Only allow the screen to sleep when not tracking.
if (Session.Status != SessionStatus.Tracking)
{
const int lostTrackingSleepTimeout = 15;
Screen.sleepTimeout = lostTrackingSleepTimeout;
}
else
{
Screen.sleepTimeout = SleepTimeout.NeverSleep;
}
if (m_IsQuitting)
{
return;
}
// Quit if ARCore was unable to connect and give Unity some time for the toast to
// appear.
if (Session.Status == SessionStatus.ErrorPermissionNotGranted)
{
_ShowAndroidToastMessage("Camera permission is needed to run this application.");
m_IsQuitting = true;
Invoke("_DoQuit", 0.5f);
}
else if (Session.Status.IsError())
{
_ShowAndroidToastMessage(
"ARCore encountered a problem connecting. Please start the app again.");
m_IsQuitting = true;
Invoke("_DoQuit", 0.5f);
}
}
}
我在下面添加了另一个用于缩放和旋转的脚本。在固定更新中,我使用触摸在y轴上滑动一个手指,这不起作用。但是同时捏住缩放是有效的。**所以我的疑问是模型的旋转是否锁定到原点?**旋转脚本在下面给出,这是另一个脚本(我已将其附加到预制件上的Rotate.cs)
void FixedUpdate()
{
if (Input.touchCount > 0 && isLocked==true)
{
var touch = Input.GetTouch(0);
if ((Input.touchCount > 0 && Input.touchCount < 2 && Input.GetTouch(0).phase == TouchPhase.Moved) && !EventSystem.current.IsPointerOverGameObject(touch.fingerId) )
{
// Get movement of the finger since last frame
Debug.Log("One touch Move");
Vector2 touchDeltaPosition = Input.GetTouch(0).deltaPosition;
Messagetxt.text = this.gameObject.name;
this.transform.Rotate(Vector3.up, -touchDeltaPosition.x * rotspeed * Time.deltaTime, Space.World);
}
if (Input.touchCount == 2 && !EventSystem.current.IsPointerOverGameObject(touch.fingerId))
{
// Store both touches.
Touch touchZero = Input.GetTouch(0);
Touch touchOne = Input.GetTouch(1);
// Find the position in the previous frame of each touch.
Vector2 touchZeroPrevPos = touchZero.position - touchZero.deltaPosition;
Vector2 touchOnePrevPos = touchOne.position - touchOne.deltaPosition;
// Find the magnitude of the vector (the distance) between the touches in each frame.
float prevTouchDeltaMag = (touchZeroPrevPos - touchOnePrevPos).magnitude;
float touchDeltaMag = (touchZero.position - touchOne.position).magnitude;
// Find the difference in the distances between each frame.
float deltaMagnitudeDiff = prevTouchDeltaMag - touchDeltaMag;
float scale = deltaMagnitudeDiff * perspectiveZoomSpeed * Time.deltaTime;
Vector3 tt;
tt.x = scale;
tt.y = scale;
tt.z = scale;
if (this.transform.localScale.x > 0 && this.transform.localScale.y > 0 && this.transform.localScale.z > 0)
{
this.transform.localScale += new Vector3(-scale, -scale, -scale);
}
if (this.transform.localScale.x < 1 && this.transform.localScale.y < 1 && this.transform.localScale.z < 1)
{
this.transform.localScale += new Vector3(scale, scale, scale);
}
if (this.transform.localScale.x > 3 && this.transform.localScale.y > 3 && this.transform.localScale.z > 3)
{
this.transform.localScale += new Vector3(scale, scale, scale);
}
}
}
}
public void Lock_Unlock()
{
if (!isLocked)
{
Lock_Unlock_btn.GetComponent<Image>().sprite = Locksprite;
isLocked = true;
// UnityARHitTestExample.InstanceHitManger.m_HitTransform.GetComponent<UnityARHitTestExample>().enabled = false;
HelloARController.helloinstance.ExampleControl.GetComponent<HelloARController>().enabled = false;
hidecanvas.SetActive(false);
}
else
{
Lock_Unlock_btn.GetComponent<Image>().sprite = Unlocksprite;
isLocked = false;
//UnityARHitTestExample.InstanceHitManger.m_HitTransform.GetComponent<UnityARHitTestExample>().enabled = true;
HelloARController.helloinstance.ExampleControl.GetComponent<HelloARController>().enabled = true;
}
}