【问题标题】:I never get inside if (Physics.Raycast(ray, out hit,Mathf.Infinity, touchInputMask)如果 (Physics.Raycast(ray, out hit,Mathf.Infinity, touchInputMask)
【发布时间】:2018-01-17 15:13:46
【问题描述】:

我想要做的是当用户触摸一个对象时,他可以移动它,特别是在屏幕上用多点触控手指

我也试过用鼠标点击这个射线,但还是有同样的问题

为此,我在更新时使用此代码

public LayerMask touchInputMask;
private static List<GameObject> touchList = new List<GameObject>();
public static Dictionary<int, objectst> touchobjects = new 
Dictionary<int, objectst>();
private GameObject[] touchesOld;
private RaycastHit hit;
public GUIText Count, IndexLift;
private Vector3 targetPos;
public struct objectst { public Vector3 screenPoint; public Vector3 offset; 
}

void Update(){

 if (nbTouches > 0)
  {
     //nbTouches = 5;
     //print(nbTouches + " touch(es) detected");
     touchesOld = new GameObject[touchList.Count];
     touchList.CopyTo(touchesOld);
     touchList.Clear();
     for (int i = 0; i < nbTouches; i++)
     {
         Touch touch = Input.GetTouch(i);
         //print("Touch index " + touch.fingerId + " detected at 
  position " + touch.position);
         Ray ray = Camera.main.ScreenPointToRay(touch.position);
         if (Physics.Raycast(ray, out hit,Mathf.Infinity,  
   touchInputMask))
         {
             GameObject recipient = hit.transform.gameObject;
             print("#### touch hit name object "+recipient.name);
             touchList.Add(recipient);
             //recipient.;
             if (touch.phase == TouchPhase.Began)
             {
                 print("#### tcouh begin");

                 objectst tempobj = new objectst();
                 tempobj.screenPoint = 
    Camera.main.WorldToScreenPoint(recipient.transform.position);
                 tempobj.offset = recipient.transform.position - 
   Camera.main.ScreenToWorldPoint(new Vector3(touch.position.x, 
  touch.position.y, tempobj.screenPoint.z));
                 touchobjects.Add(touch.fingerId, tempobj);
             }
             if (touch.phase == TouchPhase.Stationary || touch.phase 
  == TouchPhase.Moved)
             {
                 print("#### tcouh stationary or moved");
                 Vector3 curScreenPoint = new Vector3(touch.position.x, touch.position.y,
                     touchobjects[touch.fingerId].screenPoint.z);
                 Vector3 curPosition = Camera.main.ScreenToWorldPoint(curScreenPoint) + touchobjects[touch.fingerId].offset;
                 print("#### objet doit être deplacer x = "+curPosition.x+"y = "+curPosition.y);
                 recipient.transform.position = curPosition;
             }
             if (touch.phase == TouchPhase.Ended)
             {
                 print("#### tcouh ended");
                 Vector3 curScreenPoint = new Vector3(touch.position.x, touch.position.y,
                     touchobjects[touch.fingerId].screenPoint.z);
                 Vector3 curPosition = Camera.main.ScreenToWorldPoint(curScreenPoint) - touchobjects[touch.fingerId].offset;
                 recipient.transform.position = curPosition;
             }
         }
     }
   }
 }

编辑

屏幕截图

【问题讨论】:

  • 您尝试触摸的对象是否有碰撞器?
  • 您还可以附上您的图层蒙版的屏幕截图吗?你确定你的对象在那个层上吗?
  • 我只是添加一个屏幕截图
  • @Eddge 是的,我有一个rigidbody2d,脚本附加到我想移动的这个对象上,所以我想在同一层?
  • 另一个需要注意的关键点,你的使用 physics.raycast 所以你的对撞机需要是一个 3d 对撞机,要对 2d 对撞机进行射线投射,你需要使用 physics2d.raycast

标签: c# unity3d raycasting


【解决方案1】:

我是根据从 cmets 获得的信息来写这个答案的。

为了使Physics.Raycast 正常工作,您首先需要在您希望Raycast 碰撞的对象上添加一个Collider。如果您的对象没有Collider,那么您的Raycast 将不会返回任何内容(因为它没有与任何内容发生碰撞)。

ColliderRigidbody 不是一回事,Collider 通常用于碰撞检测,Rigidbody 经常使用它来处理基于物理的碰撞响应。具有Rigidbody 的对象不会与Raycast 发生冲突,除非该对象也具有Collider

PhysicsRigidBody 仅适用于 3d 碰撞器。 Physics2DRigidBody2D 用于处理 2d 物理,您不能混合 2d 物理和 3d 物理组件,因为它们在 Unity 中无法相互配合。

LayerMask, 是一个工具来确定你想要处理哪个碰撞层,每个对象在他们的名字下都有一个标签和一个层。这用于确定您希望此对象位于哪个碰撞层上。如果您检查物理设置,您可以确定哪个层相互碰撞/触发。

因此一个解决方案是添加一个名为 TouchableObject 的新层,然后将您想要“可触摸”的任何对象分配给该层,并在您的代码中为其指定适当的 Collider(2d Collider 或 3d) 3d 对撞机,或将您的 Physics.Raycast 调用转换为 Physics2D.Raycast)。然后,在您的 Touch 脚本中,您将使 LayerMask 仅针对该层。

【讨论】:

    【解决方案2】:

    我能够像这样解决问题

                RaycastHit2D hit = Physics2D.Raycast(new Vector2(Camera.main.ScreenToWorldPoint(touch.position).x, Camera.main.ScreenToWorldPoint(touch.position).y), Vector2.zero, 0f);
    
    
                if (hit.rigidbody != null)
    

    当然,命中的刚体是我点击的对象

    感谢@Eddge 的帮助

    【讨论】:

    • 这是一个很好的替代方案,适用于 2d 平面,如果您希望它适用于鼠标单击,只需将 touch.position 更改为 Input.mousePosition
    猜你喜欢
    • 1970-01-01
    • 2014-12-07
    • 1970-01-01
    • 2019-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多