问题描述
我想做的是,当用户触摸一个对象时,他可以移动它,特别是在屏幕上用多点触摸手指
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;
}
}
}
}
}
编辑
屏幕截图
推荐答案
我正在根据从评论中获得的信息来编写此答案.
I am writing this answer based off of information I got from the comments.
为使Physics.Raycast
正常工作,首先需要在要与Raycast
发生碰撞的对象上放置一个Collider
.如果您的对象没有Collider
,那么您的Raycast
将不会返回任何内容(因为它不会与任何内容发生碰撞).
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
和Rigidbody
是不同的东西,A Collider
通常用于碰撞检测,并且经常被Rigidbody
用于处理基于物理的碰撞响应.带有Rigidbody
的对象不会与Raycast
碰撞,除非该对象也具有Collider
.
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
和RigidBody
仅适用于3d碰撞器. Physics2D
和RigidBody2D
用于处理2d物理,您不能混合使用2d Physics和3d Physics组件,因为它们在Unity中无法相互配合.
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
是确定您要处理哪个Collision层的工具,每个在其名称下的对象都有一个标签和一个层.这用于确定您要将此对象放置在哪个碰撞层上.如果检查物理设置,则可以确定哪个层相互碰撞/触发.
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.
因此,一种解决方案是添加一个名为TouchableObject的新图层,然后将要成为"Touchable"对象的任何对象分配给该图层,并为其提供适当的Collider
(2d Collider或3d在您想要的代码中3d对撞机,或将您的Physics.Raycast
调用转换为Physics2D.Raycast
).然后,在您的Touch
脚本中,使LayerMask
仅针对该图层.
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.
这篇关于如果(Physics.Raycast(ray,out hit,Mathf.Infinity,touchInputMask)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!