2 个项目被放置在 AR 中。我想在屏幕中间旋转这些项目中的 1 个(使用触摸控件和 Raycast)。
我希望在相机注视物体时执行代码的所有旋转部分。
这是我在放置在场景中的对象上使用的脚本,移动功能起作用,因为只有在您点击对象所在的屏幕并将其拖走(光线转换到碰撞器)时才会激活该功能。但是,当我在任何地方滑动时,我的旋转适用于场景中的所有对象,因为如果我在对撞机上滑动,我会移动对象,因此对于旋转,我必须留在该对撞机之外。
public class MoveObject : MonoBehaviour
{
public bool holding;
private Component rotator;
int doubleTap = 0;
void Start()
{
holding = false;
}
void Update()
{
if (holding)
{
Move();
}
// One finger
if (Input.touchCount == 1)
{
// Tap on Object
if (Input.GetTouch(0).phase == TouchPhase.Began)
{
Ray ray = Camera.main.ScreenPointToRay(Input.GetTouch(0).position);
RaycastHit hitTouch;
if (Physics.Raycast(ray, out hitTouch, 100f))
{
if (hitTouch.transform == transform)
{
holding = true;
}
}
}
// Release
if (Input.GetTouch(0).phase == TouchPhase.Ended)
{
holding = false;
}
}
if (Input.touchCount == 1 && !holding) //THIS is the rotation part
{
// GET TOUCH 0
Touch touch0 = Input.GetTouch(0);
// APPLY ROTATION
if (touch0.phase == TouchPhase.Moved)
{
transform.Rotate(0f, touch0.deltaPosition.x * 0.5f, 0f);
}
}
}
void Move()
{
RaycastHit hit;
Ray ray = Camera.main.ScreenPointToRay(Input.GetTouch(0).position);
// The GameObject this script attached should be on layer "Surface"
if (Physics.Raycast(ray, out hit, 30.0f,
LayerMask.GetMask("Surface")))
{
transform.position = new Vector3(hit.point.x,
transform.position.y,
hit.point.z);
}
}
}
最佳答案
您可能需要另一个类似于 holding
的标志,以确保您不会旋转屏幕中心在滑动过程中经过的对象,例如当相机移动和物体穿过屏幕的中心。
您可以使用 Camera.ViewportPointToRay
输入 new Vector3(0.5f, 0.5f, 0)
以创建一条来自屏幕中心的光线。从那里开始,该过程类似于您的持有代码。
此外,通过稍微重新排列,您可以重新使用已用于检查此对象是否被触摸的光线转换,因为它还会检查是否有任何对象被触摸。仅当第一个光线转换没有接触到任何东西时才检查开始旋转可以避免在该对象位于屏幕中心但另一个物体被触摸的情况下旋转(和不必要的光线转换)。
作为旁注,它是 recommended to cache the result of Camera.main
因为每次您引用它时它都会在内部执行 FindGameObjectsWithTag
,这会增加额外的计算时间。
总的来说,它可能看起来像这样:
private bool rotating;
private Camera cam;
void Start()
{
holding = false;
rotating = false;
cam = Camera.main;
}
void Update()
{
// One finger
if (Input.touchCount == 1)
{
Touch touch0 = Input.GetTouch(0);
if (touch0.phase == TouchPhase.Began)
{
Ray ray;
RaycastHit hitTouch;
// test hold start
ray = cam.ScreenPointToRay(touch0.position);
if (Physics.Raycast(ray, out hitTouch, 100f))
{
if (hitTouch.transform == transform)
{
holding = true;
}
}
else // avoid rotating/raycasting again in situation
// where this object may be in center of screen
// but this or other object was touched.
{
// test rotate start
ray = cam.ViewportPointToRay(new Vector3(0.5f, 0.5f, 0));
if (Physics.Raycast(ray, out hitTouch, 100f)))
{
if (hitTouch.transform == transform)
{
rotating = true;
}
}
}
}
else if (touch0.phase == TouchPhase.Moved)
{
if (holding)
{
Move();
}
else if (rotating)
{
transform.Rotate(0f, touch0.deltaPosition.x * 0.5f, 0f);
}
}
// Release
else if (touch0.phase == TouchPhase.Ended)
{
holding = false;
rotating = false;
}
}
}
关于c# - 旋转我正在查看的对象 (ARFoundation),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57790059/