基本代码:
using UnityEngine;
public class Player : MonoBehaviour
{
Camera RayCamera;
void Start()
{
Input.multiTouchEnabled = true; //开启多点触碰
try
{
RayCamera = GameObject.FindGameObjectWithTag("RayCamera").transform.GetComponent<Camera>();
}
catch (System.Exception)
{
Debug.LogError("未找到用于射线检测的摄像头");
}
}
// Update is called once per frame
void Update()
{
if (Input.GetMouseButtonDown(0))
{
RayHitFunction(Input.mousePosition);
}
if ((Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Moved))
{
for (int i = 0; i < Input.touchCount; i++)
{
if(Input.GetTouch(i).phase == TouchPhase.Began)
{
RayHitFunction(Input.GetTouch(i).deltaPosition);
}
}
}
}
// 射线检测
void RayHitFunction(Vector2 pos)
{
UnityEngine.Ray ray = RayCamera.ScreenPointToRay(pos);
RaycastHit[] hits = Physics.RaycastAll(ray);
if (hits.Length > 0)
{
foreach (var item in hits)
{
print(item.collider.gameObject.name);
}
}
}
}
后面继续研究,关于layer分层检测的问题,有点头疼,有时间要继续刚
3D射线检测:
1.射线普通检测,如果 Ray 跟系统命名冲突,只需要在前面加上 UnityEngine. 就行了
UnityEngine.Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray,out hit))
{
if (hit.collider.gameObject.name == "Cube" )
{
print("你检测到了一个 Cube");
}
}
2.射线检测多个物体
UnityEngine.Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit[] hits = Physics.RaycastAll(ray);
if (hits.Length > 0)
{
foreach (var item in hits)
{
print(item.collider.gameObject.name);
}
}
3.射线分层检测,丫的,这个只有第一个 bool 是成立的,能够实现分层检测,其他两个就是不能,有人知道的话告诉我 ,万分感激(丫的,同样的代码,晚上一试就都行了,我真的是日狗了)还有一个问题就是第三个 bool 从摄像机到 鼠标点画线不知道为什么方向是错的
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Ray : MonoBehaviour {
public Transform cam;
public Transform cube;
// Update is called once per frame
void Update () {
UnityEngine.Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
LayerMask mask =1 << LayerMask.NameToLayer("layer");
RaycastHit hit;
// bool grounded = Physics.Raycast(cam.position, transform.forward, out hit, 10000f, 1 << LayerMask.NameToLayer("layer"));
bool grounded = Physics.Raycast(ray, out hit,10000f, mask.value);
// bool grounded = Physics.Raycast(cam.position,cam.position - Input.mousePosition, out hit,10000f, 1 << LayerMask.NameToLayer("layer"));
Debug.DrawRay(ray.origin,ray.direction* 10000f, Color.red);
if (grounded)
{
if (hit.collider.CompareTag("layer"))
{
Debug.LogError("发生了碰撞");
Debug.LogError("距离是:" + hit.distance);
Debug.LogError("被碰撞的物体是:" + hit.collider.gameObject.name);
}else
{
Debug.LogError("This layer no this tag!");
}
}
else
{
Debug.LogError("碰撞结束");
}
}
}
4. 忽略第8层的 collider ,查看layer层信息,菜单栏 Edit=> Project Settings=> Tags And Layers
Ray ray = Camera.main.ScreenPointToRay(pressGesture.ScreenPosition);
int layerMask = 1 << 8;
layerMask = ~layerMask;
RaycastHit hit;
if(Physics.Raycast(ray,out hit,1000f,layerMask))
{
Debug.Log(hit.collider.gameObject.tag + " " + hit.collider.gameObject.name);
if (hit.collider.gameObject.CompareTag("Asteroid")) {
if(asteroid_Explosion != null) Instantiate(asteroid_Explosion, hit.point,Quaternion.identity);
Destroy(hit.collider.gameObject);
}
if (hit.collider.gameObject.CompareTag("Enemy")) {
if (enemy_Explosion != null) Instantiate(enemy_Explosion, hit.point, Quaternion.identity);
Destroy(hit.collider.gameObject);
}
}
2D射线检测:
canvas renderMode记得改成空间模式
摄像头-> 鼠标
RaycastHit2D hit = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(Input.mousePosition), Vector2.zero);
if (hit.collider != null)
{
Debug.Log("hit.collider.gameObject.name: " + hit.collider.gameObject.name);
}
摄像头-> 世界坐标下的对象
RaycastHit2D hit = Physics2D.Raycast(transform.position + mMoveDirectionCell, Vector2.zero);
if (hit.collider != null)
{
Debug.Log("hit.collider.gameObject.name: " + hit.collider.gameObject.name);
}
忽略某层写法,例如忽略 UI 层(在Edit->Project Settings->Tags and Layers中可以看到Layers的编号,UI 层编号为5)
RaycastHit2D hit = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(Input.mousePosition), Vector2.zero,100f,~5);
if (hit.collider.IsNotNull())
{
if (hit.collider.CompareTag("Monster"))
{
// 调用 Monster 身上的显示UI方法
hit.collider.GetComponent<Monster>().MonsterDisplay(true);
}
}