拖动和移动2D gameObject

所以我以前的线程显示,我在运行时使用以下代码从sprite图像创建一个gameObject

  tex = Resources.Load("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(); newSprite.GetComponent().gravityScale = 0f; newSprite.AddComponent(); newSprite.AddComponent(); SR = newSprite.GetComponent(); SR.sprite = sprite; 

如你所见,我添加了一个脚本“ ObjectMovement ”,我想检查这个脚本是否有人正在拖动这个特定的gameObject ,如果有的话,让它按照触摸位置,只是提到 – 这个游戏是2D。 我从未使用RaysRaycast所以我不确定我哪里出错了。 无论如何这里是我的脚本代码:

 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(); 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处于此位置,当移动手指使其跟随时。 拖放。 谢谢。

编辑:我注意到脚本附加到每个没有效果的游戏对象,任何想法?

对于2D,您使用RaycastHit2DPhysics2D.Raycast而不是RaycastHitPhysics.Raycast 。 那些是3D。 其次,确保将对撞机附加到Sprite 。 由于这是2D游戏,因此对撞机必须包含单词“ 2D ”。 例如,编辑器中的Box Colider 2D 。 您也可以使用Circle Collider 2D

我注意到脚本附加到每个没有效果的游戏对象,任何想法?

只需创建一个空GameObject并将该脚本附加到它。 而已。

这是您的代码的固定版本:

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

这只适用于移动设备,但不适用于桌面版本。 我建议你实现IBeginDragHandlerIDragHandlerIEndDragHandler并覆盖它们附带的函数。 现在,它将适用于移动和桌面平台。

注意:对于第二个解决方案,您必须将下面的脚本附加到要拖动的所有Sprite上,而不像上面的第一个脚本。

 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(); 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.AddComponent(); } }