实现一个简单的Unity3D三维拾取——3D Picking (1)
2014-05-20 21:21
489 查看
3D Picking 原理就是从相机位置向空间中发射一条射线,根据射线击中的物体来进行拾取。
这里我们使用触摸屏触摸来进行拾取,鼠标的拾取原理一样,只不过选用的API不同。
从unity3D官网Manual里找到以下Input内容:
http://docs.unity3d.com/Documentation/Manual/Input.html
其中有段例子程序:
Following is an example script which will shoot a ray whenever the user taps on the screen:
查找ScreenPointToRay文档:
http://docs.unity3d.com/Documentation/ScriptReference/Camera.ScreenPointToRay.html
节选文档中主要描述和一段例子
Ray
ScreenPointToRay(Vector3
position);
Returns a ray going from camera through a screen point.
上面的Debug.DrawRay留着后面调试时使用,可以看到发射的射线。
接下来Camera.main.ScreenPointToRay中的Camera.main是什么意思呢,查找Camera.main
static Camera main;
The first enabled camera tagged "MainCamera" (Read Only).
即unity新建一个工程后,默认的一个main Camera
查找Physics.Raycast文档,
http://docs.unity3d.com/Documentation/ScriptReference/Physics.Raycast.html
文档内容很多,其中有一个
static bool Raycast(Vector3origin, Vector3direction, RaycastHithitInfo, float distance = Mathf.Infinity, int layerMask = DefaultRaycastLayers);
红色的两个参数我们后面将会用到,在查看RaycastHithitInfo,
http://docs.unity3d.com/Documentation/ScriptReference/RaycastHit.html
至此,我们可以实现一个简单的Picking了,创建sphere, plane, Direction Light,和一个Empty GameObject取名GameController,并新建一个脚本与其绑定。
打开GameController.cs,输入以下代码:
在移动设备上使用Unity remote,用手触摸屏幕,将会看到一道黄线,若触摸到小球Sphere或地面Plane后,可看到在Console中有Hit something信息,即射线击中了物体。
下面我们想分别选中物体,即只picking小球而忽略地面plane,查看Layer文档:
http://docs.unity3d.com/Documentation/Components/Layers.html
其中讲的很细致,关键就是要新建Tags和设定layerMask
打开Edit,选择Project Settings->Tags and Layers
在Layer 8输入Player,Layer 9输入Background
将Sphere 和 Plane的Layer 设为相应的层
修改GameController.cs,
此时,只有当我们触摸到Sphere时才绘制黄色射线提示,由于设置了LayerMask射线将忽略Plane。
下面我们尝试当射线击中Spheres时绘制黄色提示线,先击中Sphere后击中Plane时绘制红色提示线。
修改GameController.cs,
点击Play,效果如下,
这里我们使用触摸屏触摸来进行拾取,鼠标的拾取原理一样,只不过选用的API不同。
从unity3D官网Manual里找到以下Input内容:
http://docs.unity3d.com/Documentation/Manual/Input.html
其中有段例子程序:
Following is an example script which will shoot a ray whenever the user taps on the screen:
var particle : GameObject; function Update () { for (var touch : Touch in Input.touches) { if (touch.phase == TouchPhase.Began) { // Construct a ray from the current touch coordinates var ray = Camera.main.ScreenPointToRay (touch.position); if (Physics.Raycast (ray)) { // Create a particle if hit Instantiate (particle, transform.position, transform.rotation); } } } }
var ray = Camera.main.ScreenPointToRay (touch.position); if (Physics.Raycast (ray))这两句代码是关键代码,我们从这里入手。
查找ScreenPointToRay文档:
http://docs.unity3d.com/Documentation/ScriptReference/Camera.ScreenPointToRay.html
节选文档中主要描述和一段例子
Ray
ScreenPointToRay(Vector3
position);
Returns a ray going from camera through a screen point.
using UnityEngine; using System.Collections; public class Example : MonoBehaviour { void Update() { Ray ray = camera.ScreenPointToRay(new Vector3(200, 200, 0)); Debug.DrawRay(ray.origin, ray.direction * 10, Color.yellow); } }
上面的Debug.DrawRay留着后面调试时使用,可以看到发射的射线。
接下来Camera.main.ScreenPointToRay中的Camera.main是什么意思呢,查找Camera.main
static Camera main;
The first enabled camera tagged "MainCamera" (Read Only).
即unity新建一个工程后,默认的一个main Camera
查找Physics.Raycast文档,
http://docs.unity3d.com/Documentation/ScriptReference/Physics.Raycast.html
文档内容很多,其中有一个
static bool Raycast(Vector3origin, Vector3direction, RaycastHithitInfo, float distance = Mathf.Infinity, int layerMask = DefaultRaycastLayers);
红色的两个参数我们后面将会用到,在查看RaycastHithitInfo,
http://docs.unity3d.com/Documentation/ScriptReference/RaycastHit.html
至此,我们可以实现一个简单的Picking了,创建sphere, plane, Direction Light,和一个Empty GameObject取名GameController,并新建一个脚本与其绑定。
打开GameController.cs,输入以下代码:
using UnityEngine; using System.Collections; public class GameController : MonoBehaviour { void Update () { if(Input.touchCount == 1) { Ray ray = Camera.main.ScreenPointToRay (Input.GetTouch(0).position); Debug.DrawRay (ray.origin, ray.direction * 10, Color.yellow); // ray needs a origin, and a dir if(Physics.Raycast(ray, 10)) Debug.Log("Hit something"); } } }
在移动设备上使用Unity remote,用手触摸屏幕,将会看到一道黄线,若触摸到小球Sphere或地面Plane后,可看到在Console中有Hit something信息,即射线击中了物体。
下面我们想分别选中物体,即只picking小球而忽略地面plane,查看Layer文档:
http://docs.unity3d.com/Documentation/Components/Layers.html
其中讲的很细致,关键就是要新建Tags和设定layerMask
打开Edit,选择Project Settings->Tags and Layers
在Layer 8输入Player,Layer 9输入Background
将Sphere 和 Plane的Layer 设为相应的层
修改GameController.cs,
using UnityEngine; using System.Collections; public class GameController : MonoBehaviour { void Update () { if(Input.touchCount == 1) { Ray ray = Camera.main.ScreenPointToRay (Input.GetTouch(0).position); int playersLayerMask = 1 << 8; RaycastHit hit; if(Physics.Raycast(ray, out hit, Mathf.Infinity, playersLayerMask)) { Debug.DrawLine(ray.origin, hit.point, Color.yellow); // line needs two points } } } }
此时,只有当我们触摸到Sphere时才绘制黄色射线提示,由于设置了LayerMask射线将忽略Plane。
下面我们尝试当射线击中Spheres时绘制黄色提示线,先击中Sphere后击中Plane时绘制红色提示线。
修改GameController.cs,
using UnityEngine; using System.Collections; public class GameController : MonoBehaviour { void Update () { if(Input.touchCount == 1) { Ray ray = Camera.main.ScreenPointToRay (Input.GetTouch(0).position); int playersLayerMask = 1 << 8; int backgroundLayerMask = 1 << 9; RaycastHit hit; if(Physics.Raycast(ray, out hit, Mathf.Infinity, playersLayerMask)) { Debug.DrawLine(ray.origin, hit.point, Color.yellow); // line needs two points RaycastHit groundHit; if(Physics.Raycast(ray, out groundHit, Mathf.Infinity, backgroundLayerMask)) { Debug.DrawLine(ray.origin, groundHit.point, Color.red); } } } } }
点击Play,效果如下,
相关文章推荐
- unity3d射线的原理用法以及一个利用射线实现简单拾取的小例子
- unity3d射线的原理用法以及一个利用射线实现简单拾取的小例子
- 【unity3d游戏开发之基础篇】unity3d射线的原理用法以及一个利用射线实现简单拾取的小例子
- 【unity3d游戏开发之基础篇】unity3d射线的原理用法以及一个利用射线实现简单拾取的小例子
- Unity3d射线的原理用法以及一个利用射线实现简单拾取的小例子
- 【unity3d游戏开发之基础篇】unity3d射线的原理用法以及一个利用射线实现简单拾取的小例子
- unity3d射线的原理用法以及一个利用射线实现简单拾取的小例子
- 实现一个简单的Unity3D三皮卡——3D Picking (1)
- Unity3D学习(五):实现一个简单的视觉感知
- Unity3d 一个简单的玻璃效果实现!
- 使用Unity3D的设计思想实现一个简单的C#赛车游戏场景
- Unity3D学习(三):利用NGUI实现一个简单的左右摇杆
- Unity3D 粒子系统实现一个简单的爆炸效果
- 【Unity3D技巧】一个简单的Unity-UI框架的实现
- 射线的原理用法以及一个利用射线实现简单拾取的小例子
- Unity3D实现的一个简单的展示系统
- 简单实现一个Unity3d的Timer
- 一个简单的用户登录接口asp实现
- 一个简单的菜单按钮的实现
- 利用xmlHttp实现一个简单的Ajax无刷新