我正在尝试旋转相机(在X中旋转50度),并且还在触摸位置之后放置一个对象,这是我的脚本,可以旋转相机并移动对象,但是由于它是透视图,所以该对象没有移动正确地跟随手指,有关如何实现此目标的任何提示?
目标是实现本视频https://www.youtube.com/watch?v=Ljnpp5ibfGQ
中的类似内容using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CameraRotator : MonoBehaviour
{
private float initialX;
public float offset = 10f;
public float speed = 10f;
public GameObject cube;
public bool movingPlayer = false;
void Update()
{
if (Input.touchCount > 0 && !movingPlayer)
{
Touch touch = Input.GetTouch(0);
Vector3 touchPosition = Camera.main.ScreenToWorldPoint(touch.position);
switch (touch.phase)
{
case TouchPhase.Began:
initialX = touch.position.x;
break;
case TouchPhase.Moved:
if (touch.position.x + offset < initialX)
transform.rotation = Quaternion.Euler(0f, transform.rotation.eulerAngles.y - speed, 0f);
else if (touch.position.x - offset > initialX)
transform.rotation = Quaternion.Euler(0f, transform.rotation.eulerAngles.y + speed, 0f);
initialX = touch.position.x;
break;
}
}
if (Input.touchCount > 0 && movingPlayer)
{
Touch touch = Input.GetTouch(0);
Vector3 touchPosition = Camera.main.ScreenToWorldPoint(touch.position);
Ray raycast = Camera.main.ScreenPointToRay(Input.GetTouch(0).position);
if (Input.GetTouch(0).phase == TouchPhase.Moved)
{
Ray ray = Camera.main.ScreenPointToRay(Input.GetTouch(0).position);
Vector3 xx = ray.GetPoint(10f);
xx.y = 1f;
xx.x = (int)xx.x;
xx.z = (int)xx.z;
cube.transform.position = xx;
}
}
}
}
答案 0 :(得分:2)
我前段时间创建了类似的东西。
您需要注意ScreenToWorldPoint()
。单击位置基本上不是世界上的3D点,而是光线。空间中有一整行位置会全部出现在屏幕的同一位置。
Unity函数ScreenToWorldPoint()
使用输入向量中的Z坐标作为距离。由于您只是从Input.GetTouch()
捡起它,所以肯定不是您想要的距离。
文档:https://docs.unity3d.com/2020.1/Documentation/ScriptReference/Camera.ScreenToWorldPoint.html
最好使用Camera.ScreenPointToRay()
。然后使用该射线确定要考虑单击的点。
在我的抓取实现中,我用它来调用Physics.Raycast()
或Physics.RaycastAll()
,查看找到的匹配项,然后确定一个匹配点。
当玩家拖动时,您需要确定如何更改距离。如果像在示例视频链接中那样在地图上单击,则可以保持单击目标的Y坐标,然后对于每次鼠标移动,将新Ray与该Y平面相交。
在我的示例中,我只是保持了距离,并且让玩家移动了一个物品,并保持与拾取时相同的距离。
从我的示例中,单击以执行以下操作:
// try to grab something.
Ray beam = new Ray(){origin=head.transform.position,direction=head.transform.forward};
RaycastHit hit;
if( ! Physics.Raycast(beam,out hit,15.0f) )
return;
grab_item = hit.rigidbody;
if( grab_item==null || grab_item.isKinematic )
return;
grab_pos_on_item = grab_item.transform.InverseTransformPoint(hit.point);
grab_distance = (hit.point-beam.origin).magnitude;
然后,在每次更新中,检查新点在哪里,然后将项目移到那里。
if(grab_item!=null)
{
// p1: hand, p2: item
Vector3 p1 = head.transform.position + head.transform.forward * grab_distance;
Vector3 p2 = grab_item.transform.TransformPoint(grab_pos_on_item);
Vector3 dist = p1-p2;
// code to make the item move by 'dist'
如果我理解正确,那么您可能会想保持Y坐标恒定?