我正在使用 Unity3D 中的Android应用程序,我正在尝试在unity3d中运行时实例化和销毁GameObjects。我是团结一致的新人,目前正致力于google的项目探戈,我只是试图将一个物体放置在飞机上,然后通过触摸对该GameObject执行旋转或移动操作。
我正在为我的3D对象使用FBX文件,并利用事件系统来获取触摸更新。找到平面并将对象放置到飞机上是因为他们在docs上有一个清晰的教程。但现在我想通过触摸获得所选的GameObject。
我为导入的fbx对象创建了预制件,并为其添加了 Box Collider 。然后我在我的Tango相机中添加了一个 Physics Raycater 并创建了一个 EventSystem GameObject 来在运行时获取触摸事件。见附图。
我的脚本是这样的(参见 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....
条件写的代码。
答案 0 :(得分:0)
据我所知,
EventSystem.current.currentSelectedGameObject
只能引用UI对象,即使它没有明确指定in the documentation。您实例化的不是UI对象,而只是场景中的常规GameObject。我无法看到完整的Inspector视图,但我可以看到你没有在实例化过程中将Canvas的变换设置为GameObject的父级,这已经足够了。
如果您希望在场景中引用GameObject,则需要在实例化期间存储对它的引用,或者您需要根据触摸的位置进行Raycast以获取它。该方法取决于您想要实现的目标。