unity为啥射线投射到UI上面会返回空?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了unity为啥射线投射到UI上面会返回空?相关的知识,希望对你有一定的参考价值。

射线投射到ui上面返回空。我明明有命名对象的。有部分返回是正确结果。有部分返回的是空值。不知道是不是bug。点击已经生效了,但是他返回说我没有给对象一个引用。可是物体没有名字。这个游戏引擎不支持的呀。

参考技术A 首先先引入头文件

using UnityEngine.EventSystems;
using UnityEngine.UI;
然后创建变量

public GameObject changePanel;(这是要阻挡射线的UI)
public EventSystem es;
Graphics a;
主要代码段

bool CheckGuiRaycastObjects()

PointerEventData eventData = new PointerEventData(es);
eventData.pressPosition = Input.mousePosition;
eventData.position = Input.mousePosition;

List<RaycastResult> list = new List<RaycastResult>();
changeMatCanvas.GetComponent<GraphicRaycaster> ().Raycast (eventData, list);
return list.Count > 0;

在Update中加入

if (CheckGuiRaycastObjects()) return;
这样UI就可以挡住射线,不会点击到后面的碰撞体了。

unity初探之黑暗之光

unity初探之黑暗之光(2)

一、设置角色跟随鼠标点击移动

思路:使用charactercollider的SimpleMove方法来控制角色的移动。通过摄像机的射线投射到地面,通过屏幕上的一个点也就是鼠标单击的点。该射线与地面发生碰撞返回发生碰撞的点,然后让角色转向该点,开始移动。当移动到一定范围时停止移动。

使用到的方法:

Camera.ScreenPointToRay 屏幕位置转射线

 

function ScreenPointToRay (position : Vector3) : Ray

Description描述

Returns a ray going from camera through a screen point.

返回一条射线从摄像机通过一个屏幕点。

Resulting ray is in world space, starting on the near plane of the camera and going through position‘s (x,y) pixel coordinates on the screen (position.z is ignored).

产生的射线是在世界空间中,从相机的近裁剪面开始并穿过屏幕position(x,y)像素坐标(position.z被忽略)。

Screenspace is defined in pixels. The bottom-left of the screen is (0,0); the right-top is (pixelWidth,pixelHeight).

屏幕空间以像素定义。屏幕的左下为(0,0);右上是(pixelWidth,pixelHeight)。

 

Physics.Raycast 光线投射

 

static function Raycast (origin : Vector3, direction : Vector3, distance : float = Mathf.Infinity, layerMask : int = kDefaultRaycastLayers) : bool

Parameters参数

  • origin
    The starting point of the ray in world coordinates.
    在世界坐标,射线的起始点。
  • direction
    The direction of the ray.
    射线的方向。
  • distance
    The length of the ray
    射线的长度。
  • layerMask
    A Layer mask that is used to selectively ignore colliders when casting a ray.
    只选定Layermask层内的碰撞器,其它层内碰撞器忽略。

• static function Raycast (origin : Vector3, direction : Vector3, out hitInfo : RaycastHit, distance : float = Mathf.Infinity, layerMask : int = kDefaultRaycastLayers) : bool

Parameters参数

    • origin
      The starting point of the ray in world coordinates.
      在世界坐标,射线的起始点。
    • direction
      The direction of the ray.
      射线的方向。
    • distance
      The length of the ray
      射线的长度。
    • hitInfo
      If true is returned, hitInfo will contain more information about where the collider was hit (See Also: RaycastHit).
      如果返回true,hitInfo将包含碰到器碰撞的更多信息。
    • layerMask
      A Layer mask that is used to selectively ignore colliders when casting a ray.
      只选定Layermask层内的碰撞器,其它层内碰撞器忽略。 

 

    

Transform.LookAt 注视

function LookAt (target : Transform, worldUp : Vector3 = Vector3.up) : void

Description描述

Rotates the transform so the forward vector points at /target/‘s current position.

旋转物体,这样向前向量指向target的当前位置。简单说,

旋转物体使z轴指向目标物体。

当该物体设置了LookAt并指定了目标物体时,该物体的z轴将始终指向目标物体,在设置了worldUp轴向时,该物体在更接近指定的轴向是旋转便的灵活,注意worldUp指的是世界空间,不论你物体在什么位置,只要接近指定的轴方向,旋转会变的更灵活。


二、绕物相机旋转,拉近拉远

 1    public float maxDis = 20f;
 2     public float minDis = 2f;
 3     public int scrollSpeed = 10;
 4     public float distance=0;
 5     public int rotateSpeed = 1;
 6 
 7     private Transform player;
 8     private Vector3 offSet;
 9     private bool isRotate = false;
10     // Use this for initialization
11     void Start () {
12         player = GameObject.FindGameObjectWithTag(Tags.Player).transform;
13         transform.LookAt(player);
14         offSet = transform.position - player.position;//偏位
15     }
16     
17     // Update is called once per frame
18     void Update () {
19         transform.position = player.position + offSet;
20         
21         Rotate();
22         scroll();
23     }
24     //右键控制相机围绕对象旋转
25     void Rotate()
26     {
27         if (Input.GetMouseButtonDown(1))
28         {
29             isRotate = true;
30         }
31         if (Input.GetMouseButtonUp(1))
32         {
33             isRotate = false;
34         }
35 
36         if (isRotate)
37         {
38             Vector3 originalPosion = transform.position;
39             Quaternion originalRotate = transform.rotation;
40 
41             transform.RotateAround(player.position, Vector3.up, rotateSpeed * Input.GetAxis("Mouse X"));
42 
43             print(rotateSpeed * Input.GetAxis("Mouse Y"));
44             transform.RotateAround(player.position, Vector3.right, rotateSpeed * Input.GetAxis("Mouse Y"));
45             float x = transform.eulerAngles.x;
46             if (x > 80||x<10)
47             {
48                 transform.position = originalPosion;
49                 transform.rotation = originalRotate;
50             }
51         }
52         offSet = transform.position - player.position;//重新得到相机与当前人物对象的向量
53     }
54     //滑轮控制镜头远近
55     void scroll()
56     {
57         distance = offSet.magnitude;
58         distance -= Input.GetAxis("Mouse ScrollWheel")*scrollSpeed;
59         distance = Mathf.Clamp(distance, minDis, maxDis);
60         offSet = offSet.normalized * distance;
61     }

使用到的方法:

Transform.RotateAround 围绕旋转

function RotateAround (point : Vector3, axis : Vector3, angle : float) : void

Description描述

Rotates the transform about axis passing through point in world coordinates by angle degrees.

按照angle度通过在世界坐标的point轴旋转物体。

简单的说,按照多少度在世界坐标的某位置轴旋转物体。

This modifies both the position and the rotation of the transform.

这个修改变换的位置和旋转角度。

 

Input.GetAxis("Mouse X")Input.GetAxis("Mouse Y")可以分别得到鼠标在水平和垂直方向上拖动的动作信息。

Input.GetAxis("Mouse ScrollWheel")可以获得鼠标滚轮的前后滚动的动作信息。

 

 

Vector3.normalized 规范化

var normalized : Vector3

Description描述

Returns this vector with a magnitude of 1 (Read Only).

返回向量的长度为1(只读)。

When normalized, a vector keeps the same direction but its length is 1.0.

当规格化后,向量保持同样的方向,但是长度变为1.0。

Note that the current vector is unchanged and a new normalized vector is returned. If you want to normalize the current vector, use Normalize function.

注意,当前向量是不改变的并且返回一个新的规范化的向量。如果你想规范化当前向量,使用Normalize函数。

If the vector is too small to be normalized a zero vector will be returned.

如果这个向量太小而不能被规范化,一个零向量将会被返回。

 

 

以上是关于unity为啥射线投射到UI上面会返回空?的主要内容,如果未能解决你的问题,请参考以下文章

Unity物理投射(Physics.XXXCast...)相关小问题整理

unity为啥射线检测不到ui

Unity3D日常开发从物体当前方发射一条射线,并返回射线检测到的物体信息

Unity3D日常开发从物体当前方发射一条射线,并返回射线检测到的物体信息

unity初探之黑暗之光

Unity Physics.Raycast 射线投射