Unity:用于突出显示的光线投射不会检测到对象

我按照本教程选择了对象。 但是,当我导入我的.obj资产并尝试选择/突出显示它们时,看起来raycaster不会接收它们。 当我的鼠标点击我的.obj对象时没有任何反应。 我添加了必要的对撞机(箱式对撞机甚至网格对撞机),没有任何反应。

我究竟做错了什么?

我没有更改提供的源代码。 我刚刚将目标文件导入到场景中并添加了必要的物理。

我想做的就是突出显示我的.obj文件onMouseDown。

AppRoot.cs:

using UnityEngine; using System.Collections; using System.Collections.Generic; public class AppRoot : MonoBehaviour { /////////////////////////////////////////////////////////////////////////// #region Variables // materials for highlight public Material SimpleMat; public Material HighlightedMat; // rotate / pan / zoom object private TransformObject mTransform; // TransformObject implements rotate / pan / zoom private GameObject mGOFlat; // GO rotate around private const string cGONameFlat = "Flat"; // hotspots private string[] mGORoomsNames = new string[] { "Room0", "Room1", "Room2" }; private List mGORooms = new List(); private const float cHotspotSizeX = 70; private const float cHotspotSizeY = 24; // temp rectangle. It's create to do not re-create a new one on each frame private Rect mTmpRect = new Rect(); // selected GameObject private GameObject mSelectedObject; #endregion /////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// #region Interface public void Start() { // Find cGONameFlat in scene mGOFlat = GameObject.Find(cGONameFlat); // foreach (var item in mGORoomsNames) { GameObject goRoom = GameObject.Find(item); mGORooms.Add(goRoom); } // instantiate TransformObject and sets its rotate around object mTransform = new TransformObject(); mTransform.SetTransformRotateAround(mGOFlat.transform); } public void Update() { mTransform.Update(); // process object selection if (Input.GetMouseButtonDown(0)) { SelectObjectByMousePos(); } } public void OnGUI() { // render labels over game objects for (int i = 0; i < mGORooms.Count; i++) { GameObject goRoom = mGORooms[i]; // get position of room in 3d space Vector3 roomPos = goRoom.transform.position; // convert room position from 3d space to screen space (2d) Vector3 hotSpotPos = Camera.mainCamera.WorldToScreenPoint(roomPos); // calculate rect for rendering label mTmpRect.x = hotSpotPos.x - cHotspotSizeX / 2; mTmpRect.y = Screen.height - hotSpotPos.y - cHotspotSizeY / 2; mTmpRect.width = cHotspotSizeX; mTmpRect.height = cHotspotSizeY; // now render label at this point GUI.Box(mTmpRect, mGORoomsNames[i]); } } #endregion /////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// #region Implementation private void SelectObjectByMousePos() { Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); RaycastHit hit; if (Physics.Raycast(ray, out hit, Constants.cMaxRayCastDistance)) { // get game object GameObject rayCastedGO = hit.collider.gameObject; // select object this.SelectedObject = rayCastedGO; } } #endregion /////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// #region Properties ///  /// Gets or sets selected GameObject ///  public GameObject SelectedObject { get { return mSelectedObject; } set { // get old game object GameObject goOld = mSelectedObject; // assign new game object mSelectedObject = value; // if this object is the same - just not process this if (goOld == mSelectedObject) { return; } // set material to non-selected object if (goOld != null) { goOld.renderer.material = SimpleMat; } // set material to selected object if (mSelectedObject != null) { mSelectedObject.renderer.material = HighlightedMat; } } } #endregion /////////////////////////////////////////////////////////////////////////// 

}

TransformObject.cs

 using UnityEngine; using System; public class TransformObject { /////////////////////////////////////////////////////////////////////////// #region Variables // variables #if UNITY_STANDALONE_WIN || UNITY_STANDALONE_OSX || UNITY_WEBPLAYER private float RotationSpeed = 1500; private float MoveSpeed = 50.0f; private float ZoomSpeed = 15.3f; #endif // UNITY_STANDALONE_WIN || UNITY_STANDALONE_OSX || UNITY_WEBPLAYER public float MinDist = 2.0f; public float MaxDist = 50.0f; private Transform mMoveObject = null; #endregion /////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// #region Public methods ///  /// ///  public TransformObject() { EnabledMoving = true; } ///  /// Sets transform that will be used as "center" of the rotate / pan / zoom ///  public void SetTransformRotateAround(Transform goMove) { mMoveObject = goMove; if (mMoveObject == null) { Debug.LogWarning("Error! Cannot find object!"); return; } } public void Update() { if (!EnabledMoving) { return; } Vector3 dir = mMoveObject.position - Camera.main.transform.position; float dist = Math.Abs(dir.magnitude); Vector3 camDir = Camera.main.transform.forward; Vector3 camLeft = Vector3.Cross(camDir, Vector3.down); Vector3 camDown = Vector3.Cross(camDir, camLeft); //Vector3 camUp = Vector3.Cross(camLeft, camDir); #if UNITY_STANDALONE_WIN || UNITY_STANDALONE_OSX || UNITY_WEBPLAYER float dx = Input.GetAxis("Mouse X"); float dy = Input.GetAxis("Mouse Y"); // rotate if (Input.GetMouseButton(0)) { mMoveObject.Rotate(camLeft, dy * RotationSpeed * Time.deltaTime, Space.World); mMoveObject.Rotate(Vector3.down, dx * RotationSpeed * Time.deltaTime, Space.Self); } // move if (Input.GetMouseButton(1)) { Vector3 camPos = Camera.main.transform.position; camPos += -camLeft * MoveSpeed * dx * Time.deltaTime; camPos += -camDown * MoveSpeed * dy * Time.deltaTime; Camera.main.transform.position = camPos; } // zoom if (Input.GetAxis("Mouse ScrollWheel") > 0) { if (dist > MinDist) { mMoveObject.Translate(-dir * ZoomSpeed * Time.deltaTime, Space.World); } } if (Input.GetAxis("Mouse ScrollWheel") < 0) { if (dist < MaxDist) { mMoveObject.Translate(dir * ZoomSpeed * Time.deltaTime, Space.World); } } #endif // UNITY_STANDALONE_WIN || UNITY_STANDALONE_OSX || UNITY_WEBPLAYER } #endregion /////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// #region Properties ///  /// Gets or set value indicating if transformation is enabled ///  public bool EnabledMoving { get; set; } ///  /// Gets game object that moves around ///  public Transform MoveObject { get { return mMoveObject; } } #endregion /////////////////////////////////////////////////////////////////////////// 

}

Constants.cs:

 using System; using System.Collections.Generic; using System.Linq; using System.Text; public class Constants { public const float cMaxRayCastDistance = 1000.0f; } 

原因是“femur_left_1_7_dist / default”和“femur_left_1_7_prox / default”没有碰撞器。 因此有两种方法可以解决此问题:

  1. 在项目视图中选择“femur_left_1_7_dist”和“femur_left_1_7_prox”,然后在导入设置的检查器中选择“生成碰撞器”并按“应用”按钮:

    在此处输入图像描述
    要么

  2. 在场景中选择“femur_left_1_7_dist / default”,然后按“Component / Physics / Box Collider”; 在这里看到结果: https : //dl.dropboxusercontent.com/u/20023505/stackoverflow_forum/s_fix.zip

可能有几件事导致了这一点,但这里有一些要检查的事情。

  • 确保您的GameObject附加了一个Collider Component。
  • 确保GameObjects图层未设置为Ignore Raycast。
  • 确保您使用合适的相机进行Raycasting。

本教程似乎使用了Raycast的默认摄像头,确保场景中的摄像头的标签设置为主摄像头。

我在三个立方体(room0到room2)和一个平面(平面)的场景中使用了你的代码,它运行良好。

但是你的代码有点怪异,尤其是TransformObject类。 此类应该是MonoBehaviour (脚本),并作为Component添加到与AppRoot脚本相同的GameObject中

您甚至可以使用AppRoot类上的RequireComponentAttribute使其自动化。

那么,为什么你的代码不适合你的情况呢?

  • 您是否尝试在运行代码时使用调试器,以查看SelectObjectByMousePos()SelectedObject是否完全被调用?
  • 您想要使用的材料可能不适用于您的网格:尝试使用您的脚本与多维数据集(就像我做的那样)而不是您的.obj
  • 重写您的代码,以便TransformObject是一个MonoBehaviour脚本。
    • 如果您担心执行顺序 ,请参阅此页面: http : //docs.unity3d.com/Documentation/Components/class-ScriptExecution.html
  • 检查碰撞矩阵,可能会禁用某些层到层的碰撞检测。

编辑:光线投射是否适用于非凸面碰撞器?

Interesting Posts