拖动和移动2D游戏对象 [英] Dragging and moving 2D gameObject
问题描述
因此,正如我之前的线程所显示的那样,我正在使用以下代码在运行时从精灵图像创建gameObject
:
so as my previous threads show, I am creating a gameObject
from sprites images at runtime using this code:
tex = Resources.Load<Texture2D>("pig") as Texture2D;
Sprite sprite = new Sprite();
sprite = Sprite.Create(tex, new Rect(0, 0, 250, 150), new Vector2(0.5f, 0.5f));
GameObject newSprite = new GameObject();
newSprite.AddComponent<Rigidbody2D>();
newSprite.GetComponent<Rigidbody2D>().gravityScale = 0f;
newSprite.AddComponent<ObjectMovement>();
newSprite.AddComponent<SpriteRenderer>();
SR = newSprite.GetComponent<SpriteRenderer>();
SR.sprite = sprite;
如您所见,我添加了一个脚本"ObjectMovement
",我想在此脚本中检查是否有人拖动了该特定的gameObject
,如果这样,请使其跟随触摸位置,仅此提及-该游戏是2D.我从未使用过Rays
或Raycast
,所以我不确定哪里出了问题.无论如何,这是我的脚本代码:
As you see I added a script "ObjectMovement
", I want to check in this script if someone is dragging this particular gameObject
and if so, make it follow the touch position, just to mention - this game is 2D. I never used Rays
orRaycast
so I am not sure where I gone wrong. Anyway here is my script code:
public SpriteRenderer selection=null;
void Update()
{
if (Input.touchCount >= 1)
{
foreach (Touch touch in Input.touches)
{
Ray ray = Camera.main.ScreenPointToRay(touch.position);
RaycastHit hit;
switch (touch.phase)
{
case TouchPhase.Began:
if (Physics.Raycast(ray, out hit, 100))
selection = hit.transform.gameObject.GetComponent<SpriteRenderer>();
break;
case TouchPhase.Moved:
selection.transform.position = new Vector2(selection.transform.position.x + touch.position.x / 10, selection.transform.position.y + touch.position.y / 10);
break;
case TouchPhase.Ended:
selection = null;
break;
}
}
}
}
所以基本上-触摸屏幕时,发射ray
并检查哪个gameObject
处于此位置,移动手指时使其跟随它.拖放.谢谢.
So basically - when touching the screen, fire a ray
and check which gameObject
is in this position, when moving the finger make it follow it. Drag and drop. Thanks.
编辑:我注意到该脚本已附加到每个gameObject
上,这无效,有什么想法吗?
I noticed the script is attached to every gameObject
which is not effective, any ideas?
推荐答案
对于2D,您使用RaycastHit2D
和Physics2D.Raycast
而不是RaycastHit
和Physics.Raycast
.这些是用于3D的.其次,确保将对撞机连接到Sprite
.由于这是2D游戏,因此对撞机中必须包含单词" 2D ".例如,编辑器中的Box Colider 2D
.您也可以使用Circle Collider 2D
.
For 2D, you use RaycastHit2D
and Physics2D.Raycast
instead of RaycastHit
and Physics.Raycast
. Those are for 3D. Secondly, Make sure to attach a collider to the Sprite
. Since this is a 2D game, the collider must have word "2D" in it. For example, Box Colider 2D
from the Editor. You can also use Circle Collider 2D
.
我注意到该脚本已附加到每个gameObject上,而不是 有效,有什么想法吗?
I noticed the script is attached to every gameObject which is not effective, any ideas?
只需创建一个空的GameObject并将该脚本附加到它.就是这样.
Just create an empty GameObject and attach that script to it. That's it.
这是您代码的固定版本:
Here is fixed version of your code:
float tempZAxis;
public SpriteRenderer selection;
void Update()
{
Touch[] touch = Input.touches;
for (int i = 0; i < touch.Length; i++)
{
Vector2 ray = Camera.main.ScreenToWorldPoint(Input.GetTouch(i).position);
RaycastHit2D hit = Physics2D.Raycast(ray, Vector2.zero);
switch (touch[i].phase)
{
case TouchPhase.Began:
if (hit)
{
selection = hit.transform.gameObject.GetComponent<SpriteRenderer>();
if (selection != null)
{
tempZAxis = selection.transform.position.z;
}
}
break;
case TouchPhase.Moved:
Vector3 tempVec = Camera.main.ScreenToWorldPoint(touch[i].position);
tempVec.z = tempZAxis; //Make sure that the z zxis never change
if (selection != null)
{
selection.transform.position = tempVec;
}
break;
case TouchPhase.Ended:
selection = null;
break;
}
}
}
那将仅在移动设备上有效,而在Desktop Build上无效.我建议您实现IBeginDragHandler
,IDragHandler
,IEndDragHandler
,并覆盖它们随附的功能.现在,它可以在移动和台式机平台上使用.
That would only work on mobile but not on the Desktop Build. I suggest you implement IBeginDragHandler
, IDragHandler
, IEndDragHandler
and override the functions that comes with them. Now, it will work with both mobile and desktop platforms.
注意:对于第二个解决方案,您必须将下面的脚本附加到要拖动的所有Sprite上,这与上面的第一个脚本不同.
Note: For the second solution you have to attach the script below to all Sprites you want to drag unlike the first script above.
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using UnityEngine.EventSystems;
public class Dragger : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
{
Camera mainCamera;
float zAxis = 0;
Vector3 clickOffset = Vector3.zero;
// Use this for initialization
void Start()
{
//Comment this Section if EventSystem system is already in the Scene
addEventSystem();
mainCamera = Camera.main;
mainCamera.gameObject.AddComponent<Physics2DRaycaster>();
zAxis = transform.position.z;
}
public void OnBeginDrag(PointerEventData eventData)
{
clickOffset = transform.position - mainCamera.ScreenToWorldPoint(new Vector3(eventData.position.x, eventData.position.y, zAxis));
}
public void OnDrag(PointerEventData eventData)
{
//Use Offset To Prevent Sprite from Jumping to where the finger is
Vector3 tempVec = mainCamera.ScreenToWorldPoint(eventData.position) + clickOffset;
tempVec.z = zAxis; //Make sure that the z zxis never change
transform.position = tempVec;
}
public void OnEndDrag(PointerEventData eventData)
{
}
//Add Event Syste to the Camera
void addEventSystem()
{
GameObject eventSystem = new GameObject("EventSystem");
eventSystem.AddComponent<EventSystem>();
eventSystem.AddComponent<StandaloneInputModule>();
}
}
这篇关于拖动和移动2D游戏对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!