Я никогда не попаду внутрь, если (Physics.Raycast(ray, out hit,Mathf.Infinity, touchInputMask)

Что я хочу сделать, так это когда пользователь прикасается к объекту, он может его перемещать, и особенно с помощью мультитач-пальца на экране.

Я тоже пытался сделать этот луч щелчком мыши, но у меня все та же проблема.

для этого я использую этот код при обновлении

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;
             }
         }
     }
   }
 }

ИЗМЕНИТЬ

снимок экрана

введите здесь описание изображения


person tamtoum1987    schedule 17.01.2018    source источник
comment
У объекта, к которому вы пытаетесь прикоснуться, есть коллайдеры?   -  person AresCaelum    schedule 17.01.2018
comment
Также вы можете включить скриншот вашей маски слоя? и вы уверены, что ваши объекты находятся на этом слое?   -  person AresCaelum    schedule 17.01.2018
comment
я просто добавляю скрин   -  person tamtoum1987    schedule 17.01.2018
comment
@Eddge да, у меня есть hardbody2d, скрипт прикреплен к этому объекту, который я хочу переместить, поэтому я полагаю, что они находятся в одном слое?   -  person tamtoum1987    schedule 17.01.2018
comment
Вы попадаете в цикл for? Поместите Debug.Log туда, чтобы проверить   -  person Programmer    schedule 17.01.2018
comment
@tamtoum1987 tamtoum1987 Я просил скриншот вашей маски слоя, то, что вы показываете, не показывает мне, что находится в вашей маске слоя, кроме того, hardbody2d - это не то же самое, что коллайдер. объекты, к которым вы пытаетесь прикоснуться с помощью raycast, нуждаются в коллайдере. поэтому, пожалуйста, опубликуйте скриншот того, что находится в маске сенсорного ввода, и скриншот инспектора объекта, к которому вы пытаетесь прикоснуться. Чтобы это работало, объекты, которые вы пытаетесь напечатать, нуждаются в коллайдере (не твердом теле, так как это для физики, а не для столкновений.) И должны быть на правильном слое.   -  person AresCaelum    schedule 17.01.2018
comment
Еще одна ключевая вещь, которую следует отметить, ваше использование physics.raycast, поэтому ваш коллайдер должен быть 3D-коллайдером, чтобы сделать raycast против 2D-коллайдера, вам нужно использовать physics2d.raycast   -  person AresCaelum    schedule 17.01.2018
comment
@Eddge да, именно эта история с 3D вызвала у меня проблемы :(   -  person tamtoum1987    schedule 17.01.2018
comment
спасибо за ваши ответы   -  person tamtoum1987    schedule 17.01.2018


Ответы (2)


Я пишу этот ответ на основе информации, которую я получил из комментариев.

Чтобы Physics.Raycast работало правильно, вам сначала нужно Collider на объектах, с которыми вы хотите, чтобы ваш Raycast столкнулся. Если у вашего объекта нет Collider, то ваш Raycast ничего не вернет (поскольку он ни с чем не сталкивался).

Collider и Rigidbody - это не одно и то же. Collider обычно используется для обнаружения столкновений и часто используется Rigidbody для обработки ответов на столкновения, основанных на физике. Объект с Rigidbody не будет сталкиваться с Raycast, если этот объект также не имеет Collider.

Physics и RigidBody будут работать только с 3D-коллайдерами. Physics2D и RigidBody2D предназначены для работы с 2D-физикой, вы не можете смешивать компоненты 2D-физики и 3D-физики, поскольку они не будут работать друг с другом в Unity.

LayerMask — это инструмент для определения, с каким слоем Collision вы хотите иметь дело, у каждого объекта сразу под его именем есть тег и слой. Это используется для определения того, на каком слое столкновений вы хотите разместить этот объект. Если вы проверите настройки физики, вы сможете определить, какие слои сталкиваются/запускают друг друга.

Таким образом, решением было бы добавить новый слой с именем TouchableObject, затем назначить любой объект, который вы хотите сделать «прикасаемым», к этому слою и присвоить ему соответствующий Collider (2d Collider или 3d в вашем коде, который вам нужен 3d-коллайдер, или преобразовать ваш вызов Physics.Raycast в Physics2D.Raycast). В вашем сценарии Touch вы затем сделаете LayerMask нацеленным только на этот слой.

person AresCaelum    schedule 17.01.2018

я смог решить проблему так

            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 за вашу помощь

person tamtoum1987    schedule 17.01.2018
comment
Это хорошая альтернатива, и она работает на 2D-плоскости, просто измените touch.position на Input.mousePosition, если вы хотите, чтобы она работала при щелчке мышью. - person Peter; 21.05.2020