c# - raycasthit - Unidad: el objeto no está siendo detectado por raycast para resaltar
unity c# raycast hit (3)
La razón fue que "femur_left_1_7_dist / default" y "femur_left_1_7_prox / default" no tienen colisionadores. Entonces, hay dos formas de resolver este problema:
En la vista del proyecto, seleccione "femur_left_1_7_dist" y "femur_left_1_7_prox", y en el inspector, en la configuración de importación, seleccione "Generate Colliders" y presione el botón "Aplicar":
OSeleccione "femur_left_1_7_dist / default" en la escena y presione "Component / Physics / Box Collider"; vea el resultado aquí: https://dl.dropboxusercontent.com/u/20023505/stackoverflow_forum/s_fix.zip
Seguí este tutorial sobre selección de objetos. Sin embargo, cuando importo mis activos .obj y trato de seleccionarlos / resaltarlos, parece que el raycaster no los recoge. No ocurre nada cuando mi mouse hace clic en mi objeto .obj. Agregué los colisionadores necesarios (colisionador de caja y colisionador de malla) y no pasó nada.
¿Qué estoy haciendo mal?
No cambié el código de la fuente proporcionada. Acabo de importar mi archivo objeto a la escena y agregué la física necesaria.
Todo lo que quiero hacer es resaltar mi archivo .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<GameObject> mGORooms = new List<GameObject>();
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
/// <summary>
/// Gets or sets selected GameObject
/// </summary>
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
/// <summary>
///
/// </summary>
public TransformObject()
{
EnabledMoving = true;
}
/// <summary>
/// Sets transform that will be used as "center" of the rotate / pan / zoom
/// </summary>
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
/// <summary>
/// Gets or set value indicating if transformation is enabled
/// </summary>
public bool EnabledMoving
{
get;
set;
}
/// <summary>
/// Gets game object that moves around
/// </summary>
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;
}
Puede haber varias cosas que causan esto, pero aquí hay algunas cosas que debe verificar.
- Asegúrate de que tu GameObject tenga un Componente Collider asociado.
- Asegúrate de que la capa de GameObjects no esté configurada para Ignorar Raycast.
- Asegúrate de que estás emitiendo rayos desde la cámara correcta.
El tutorial parece estar usando una cámara predeterminada para el Raycast, asegúrese de tener una cámara en la escena que tiene su etiqueta configurada como cámara principal.
Usé tu código en una escena con tres cubos (habitación0 a habitación2) y un avión (plano) y funcionó bien.
Pero su código es un poco raro, especialmente la clase TransformObject . Esta clase debe ser un MonoBehaviour (un script) y debe agregarse como un Componente al mismo GameObject que su script de AppRoot .
Incluso puede hacerlo de forma automática mediante el uso de RequireComponentAttribute en su clase de AppRoot .
Ahora bien, ¿por qué no funciona su código en su caso?
- ¿ Intentó utilizar el depurador mientras ejecutaba su código, para ver si SelectObjectByMousePos () y SelectedObject se llamaron?
- Es posible que el material que desea utilizar no esté funcionando con sus mallas: intente utilizar su secuencia de comandos con cubos (como lo hice) en lugar de su .obj
- Reescribe tu código para que TransformObject sea un script de MonoBehaviour .
- Si le preocupa el orden de ejecución , consulte esta página: http://docs.unity3d.com/Documentation/Components/class-ScriptExecution.html
- Verifique la matriz de colisión, quizás la detección de colisión de capa a capa esté deshabilitada.
editar: ¿funciona el raycasting con colisionadores no convexos?