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:

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

节选文档中主要描写叙述和一段样例

RayScreenPointToRay(Vector3position);

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).

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGluaWFuNzE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">

即unity新建一个project后,默认的一个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,效果例如以下,



版权声明:本文博客原创文章,博客,未经同意,不得转载。

最新文章

  1. python利用unrar实现rar文件解压缩
  2. JS 获取元素当前的样式信息
  3. 用js完成毫秒格式数据的日期格式化任务
  4. Hadoop编程1:天气数据AWK &amp; MapReduce
  5. ios上架
  6. c#_错误处理_基础
  7. Poj OpenJudge 百练 Bailian 1008 Maya Calendar
  8. Windows下安装Eric5时出现的“Sorry, please install QtHelp.”问题解决办法
  9. ZOJ 3903 Ant(公式推导)
  10. 自己编写SqlHelper
  11. mongoDB 在windows平台下安装成系统服务
  12. java.sql.ResultSetMetaData.getColumnLabel和getColumnName的区别
  13. Android 安卓实现页面相互跳转并相互传递参数
  14. GitLab搭建详细过程
  15. ReentrantLock 与 AQS 源码分析
  16. lintcode 在O(1)时间复杂度删除链表节点
  17. MySQL基本命令(待更新...)
  18. windows程序设计 获取系统文件路径
  19. 通过改变unity中物体的alpha值实现若隐若现的效果
  20. oracle函数创建及调用

热门文章

  1. executeBatch()相关操作汇总
  2. SQL Server 2008 R2 性能计数器详细列表(三)
  3. SAP ABAP 它已被释放TR(或任务),减少的变化TR(任务),删除释放TR(任务)
  4. SQL开发中容易忽视的一些小地方(六)
  5. vs2010中文简体版下载链接(含中文msdn)
  6. 机器人操作系统 除了Android还有一个ROS(转)
  7. Cocos2dx 3.0 交流篇
  8. Pro Aspnet MVC 4读书笔记(5) - Essential Tools for MVC
  9. linux&nbsp;下&nbsp;apache启动、停止、重启命令
  10. obj-c编程04:类的继承