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”没有碰撞器。 因此有两种方法可以解决此问题:
-
在项目视图中选择“femur_left_1_7_dist”和“femur_left_1_7_prox”,然后在导入设置的检查器中选择“生成碰撞器”并按“应用”按钮:
要么 -
在场景中选择“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
- 检查碰撞矩阵,可能会禁用某些层到层的碰撞检测。
编辑:光线投射是否适用于非凸面碰撞器?