Unity3D - 使用EventSystem

时间:2017-06-12 08:06:02

标签: unity3d google-project-tango

我正在使用 Unity3D 中的Android应用程序,我正在尝试在unity3d中运行时实例化和销毁GameObjects。我是团结一致的新人,目前正致力于google的项目探戈,我只是试图将一个物体放置在飞机上,然后通过触摸对该GameObject执行旋转或移动操作。

我正在为我的3D对象使用FBX文件,并利用事件系统来获取触摸更新。找到平面并将对象放置到飞机上是因为他们在docs上有一个清晰的教程。但现在我想通过触摸获得所选的GameObject。

我为导入的fbx对象创建了预制件,并为其添加了 Box Collider 。然后我在我的Tango相机中添加了一个 Physics Raycater 并创建了一个 EventSystem GameObject 来在运行时获取触摸事件。见附图。

GameObject

EventSystem

我的脚本是这样的(参见 IsPointerOverGameObject 方法): -

 using UnityEngine;
 using System.Collections;
 using UnityEngine.EventSystems;
 public class KittyUIController : MonoBehaviour
 {
 public GameObject m_object;
 private TangoPointCloud m_pointCloud;
 private bool isGameObjectSelected = false;
 void Start()
 {
     m_pointCloud = FindObjectOfType<TangoPointCloud>();
     InventoryItemDisplay.onClick += InventoryItemDisplay_onClick;
 }
 void OnDestroy()
 {
     Debug.Log ("MY LOGS - Unsigned-up for onClick");
     InventoryItemDisplay.onClick -= InventoryItemDisplay_onClick;
 }
 void Update ()
 {
     if (Input.touchCount == 1)
     {
         Touch t = Input.GetTouch(0);
         // Trigger place kitten function when single touch ended.
         if (t.phase == TouchPhase.Ended) {
             if (m_object != null && !isGameObjectSelected) {
                 Debug.Log ("MY LOGS - Placing object to the plane");
                 PlaceObject (t.position);
             } else {
                 isGameObjectSelected = false;
             }
         } else if (t.phase == TouchPhase.Began) {
             IsPointerOverGameObject (t.fingerId);    // Here i'm checking weather a GameObject is Touched or not
         }
     }
 }
 /*
 * This method will check whether a game object is touched or not using Event System    
 */
 void IsPointerOverGameObject( int fingerId){

     if (EventSystem.current.IsPointerOverGameObject (fingerId)) {
         isGameObjectSelected = true;
         Debug.Log ("MY LOGS - Is pointing over game object");
         //-------HERE IS THE REAL ISSUE-------//
         Debug.Log ("MY LOGS - GETTING SELECTED GAMEOBJECT : " + EventSystem.current.currentSelectedGameObject);
         GameObject go = EventSystem.current.currentSelectedGameObject;
         Debug.Log ("MY LOGS - Got the game object!!\nTag for game object is : "+go.tag);
         // Destroy if Object is of type 3D object
         if (go.tag == "3DObject") {
             Debug.Log ("MY LOGS - yoo a 3d object is selected");
             Destroy (go);
         } else {
             Debug.Log ("MY LOGS - Oops the selected object don't have a tag of 3d object");
         }
     } else {
         Debug.Log ("MY LOGS - Is not pointing over game object");
     }
 }
 //-------Click listener to listen to the clicks in Side Panel
 void InventoryItemDisplay_onClick (InventoryItem item, GameObject itemObject)
 {
     Debug.Log ("MY LOGS - Vola..You have selected " + item.displayName);
     m_object = itemObject;
 }
 /*
 * This method will place selected gameobject to the plane    
 */
 void PlaceObject(Vector2 touchPosition)
 {
     // Find the plane.
     Camera cam = Camera.main;
     Vector3 planeCenter;
     Plane plane;
     if (!m_pointCloud.FindPlane(cam, touchPosition, out planeCenter, out plane))
     {
         Debug.Log("MY LOGS - cannot find plane.");
         return;
     }
     // Place object on the surface, and make it always face the camera.
     if (Vector3.Angle(plane.normal, Vector3.up) < 30.0f)
     {
         Vector3 up = plane.normal;
         Vector3 right = Vector3.Cross(plane.normal, cam.transform.forward).normalized;
         Vector3 forward = Vector3.Cross(right, plane.normal).normalized;
         Instantiate(m_object, planeCenter, Quaternion.LookRotation(forward, up));
     }
     else
     {
         Debug.Log("MY LOGS - surface is too steep for kitten to stand on.");
     }
    }
 }

我有一个带有列表项的侧面板预制件,它也在运行时创建。因此,当我触摸侧面板上的列表项以选择对象时, IsPointerOverGameObject 方法中的所有内容都运行良好,除了打印所选对象的标记。但当我触摸放置在屏幕表面上的对象时,在 IsPointerOverGameObject 方法

Debug.Log ("MY LOGS - Is pointing over game object");之后它无法正常工作

看到我的logcat后会很清楚。

logcat的

 06-10 15:33:31.094: I/Unity(15009): MY LOGS - Is not pointing over game object
 06-10 15:33:38.619: I/Unity(15009): MY LOGS - Is pointing over game object
 06-10 15:33:38.621: I/Unity(15009): MY LOGS - GETTING SELECTED GAMEOBJECT :  InventoryItemDisplay(Clone) (UnityEngine.GameObject)
 06-10 15:33:38.621: I/Unity(15009): MY LOGS - Got the game object!!
 06-10 15:33:38.622: I/Unity(15009): MY LOGS - Oops the selected object don't have a tag of 3d object
 06-10 15:33:38.665: I/Unity(15009): MY LOGS - Vola..You have selected Rose
 06-10 15:33:45.175: I/Unity(15009): MY LOGS - Is not pointing over game object
 06-10 15:33:45.286: I/Unity(15009): MY LOGS - Placing object to the plane
 06-10 15:33:50.379: I/Unity(15009): MY LOGS - Is pointing over game object
 06-10 15:33:50.379: I/Unity(15009): MY LOGS - GETTING SELECTED GAMEOBJECT : 
 06-10 15:33:54.558: I/Unity(15009): MY LOGS - Is not pointing over game object
 06-10 15:33:54.686: I/Unity(15009): MY LOGS - Placing object to the plane
 06-10 15:33:54.688: I/Unity(15009): MY LOGS - surface is too steep for kitten to stand on.

现在,如果您看到Logcat的第三行,您将看到它打印出所选的Object:InventoryItemDisplay(Clone),但如果您检查{{1},则在下一行中在代码中,你会看到我在Debug.Log()之后没有打印日志。这是我点击侧面板上的项目时。现在看看logcat底部的第四个行。这是当我点击Initialised游戏对象时。它甚至不会在该行之后打印任何内容。它直接打印出用\n....条件写的代码。

为场景添加屏幕 screenshot of the scene

1 个答案:

答案 0 :(得分:0)

据我所知,  EventSystem.current.currentSelectedGameObject只能引用UI对象,即使它没有明确指定in the documentation。您实例化的不是UI对象,而只是场景中的常规GameObject。我无法看到完整的Inspector视图,但我可以看到你没有在实例化过程中将Canvas的变换设置为GameObject的父级,这已经足够了。

如果您希望在场景中引用GameObject,则需要在实例化期间存储对它的引用,或者您需要根据触摸的位置进行Raycast以获取它。该方法取决于您想要实现的目标。