I never get inside if (Physics.Raycast(ray, out hit,Mathf.Infinity, touchInputMask)

烂漫一生 提交于 2020-01-06 07:11:10

问题


What I want to do is when user touch a object he can move it, and specially with multitouch finger on the screen

I tried to do this ray with mouse click too, but still have the same problem

for that, I use this code on update

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

EDIT

screen shot


回答1:


I am writing this answer based off of information I got from the comments.

In order for Physics.Raycast to work correctly, you first need a Collider on the objects you wants your Raycast to collide with. If your object does not have a Collider then your Raycast will not return anything(As it didn't collide with anything).

Collider and Rigidbody are not the same thing, A Collider is generally used for collision detection, and is often times used by a Rigidbody to handle physics based collision responses. An object with a Rigidbody will not collide with a Raycast unless that object also has a Collider.

Physics and RigidBody will work with only 3d Colliders. Physics2D and RigidBody2D is for dealing with 2d physics you cannot mix 2d Physics and 3d Physics components as they will not work with each other in Unity.

LayerMask, is a tool to determine which Collision layer you want to deal with, every object just under their name has a tag, and a layer. This is used for determining which Collision Layer you want this object on. If you check the physics settings you can determine which layer collide/trigger each other.

So a solution would be to add a new Layer called TouchableObject, then assign any object you want to be "Touchable" to that layer, and give it the appropriate Collider(2d Collider or 3d in your code you would want a 3d collider, or convert your Physics.Raycast call to a Physics2D.Raycast). In your Touch script you would then make the LayerMask only target that layer.




回答2:


i was able to resolve the problem like this

            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)

and of course rigidbody of hit are my object i clicked on

thanks @Eddge for your help



来源:https://stackoverflow.com/questions/48304293/i-never-get-inside-if-physics-raycastray-out-hit-mathf-infinity-touchinputma

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!