实现一个简单的Unity3D三皮卡——3D Picking (1)
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,效果例如以下,
版权声明:本文博客原创文章,博客,未经同意,不得转载。
实现一个简单的Unity3D三皮卡——3D Picking (1)的更多相关文章
- 一个简单的CSS3+js 实现3D BOX
<!doctype html><html><head> <meta charset="UTF-8"> <title>Do ...
- 使用Unity3D的设计思想实现一个简单的C#赛车游戏场景
最近看了看一个C#游戏开发的公开课,在该公开课中使用面向对象思想与Unity3D游戏开发思想结合的方式,对一个简单的赛车游戏场景进行了实现.原本在C#中很方便地就可以完成的一个小场景,使用Unity3 ...
- PureMVC和Unity3D的UGUI制作一个简单的员工管理系统实例
前言: 1.关于PureMVC: MVC框架在很多项目当中拥有广泛的应用,很多时候做项目前人开坑开了一半就消失了,后人为了填补各种的坑就遭殃的不得了.嘛,程序猿大家都不喜欢像文案策划一样组织文字写东西 ...
- Linux内核设计第三周——构造一个简单的Linux系统
Linux内核设计第三周 ——构造一个简单的Linux系统 一.知识点总结 计算机三个法宝: 存储程序计算机 函数调用堆栈 中断 操作系统两把宝剑: 中断上下文的切换 进程上下文的切换 linux内核 ...
- 《Linux内核分析》第三周 构建一个简单的Linux系统MenuOS
[刘蔚然 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000] WEEK THREE ...
- Linux内核分析第三周学习总结:构造一个简单的Linux系统MenuOS
韩玉琪 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.Linux内 ...
- 一步一步写一个简单通用的makefile(三)
上一篇一步一步写一个简单通用的makefile(二) 里面的makefile 实现对通用的代码进行编译,这一章我将会对上一次的makefile 进行进一步的优化. 优化后的makefile: #Hel ...
- [.NET] 一步步打造一个简单的 MVC 电商网站 - BooksStore(三)
一步步打造一个简单的 MVC 电商网站 - BooksStore(三) 本系列的 GitHub地址:https://github.com/liqingwen2015/Wen.BooksStore &l ...
- Extjs6(三)——用extjs6.0写一个简单页面
本文基于ext-6.0.0 一.关于border布局 在用ext做项目的过程中,最常用到的一种布局就是border布局,现在要写的这个简单页面也是运用border布局来做.border布局将页面分为五 ...
随机推荐
- 【C疯狂的教材】(四)C语言分支语句
1.程序的结构 程序默认从上到下顺序运行(顺序结构) 程序的结构:顺序结构.分支结构.循环结构 2.if分支语句 程序运行的过程中能够有多个选择 格式: if(表达式){ 语句块; } ...... ...
- 杭州电 1052 Tian Ji -- The Horse Racing(贪婪)
http://acm.hdu.edu.cn/showproblem.php? pid=1052 Tian Ji -- The Horse Racing Time Limit: 2000/1000 MS ...
- Eclipse—怎样为Eclipse开发工具中创建的JavaWebproject创建Servlet
在博客<在Eclipse中怎样创建JavaWebproject>中图文并茂的说明了Eclipse中创建JavaWebproject的方法,本篇博客将告诉大家怎样为Eclipse开发工具中创 ...
- hdoj 1506&&1505(City Game) dp
// l表示从l[i]到i连续大于a[i]的最远左区间.r表示从i到r[i]连续大于a[i]的最远又区间 DP 找出 a[i] 的最远左区间和最远右区间与自己连着的比自己大的数的长度 , 然后用这个长 ...
- 【Android先进】我们为什么要创建Activity基类Activity什么是一般的基类方法
今天,它可以被视为只是基本完成了其首个商业项目,在发展过程中,风格,然而随着工作经验的积累.最终開始慢慢的了解到抽象思想在面向对象编程中的重要性,这一篇简单的介绍一下我的一点收获. 首先,在如今的项目 ...
- jaxb和dozer简介
一.jaxb是什么 JAXB是Java Architecture for XML Binding的缩写.可以将一个Java对象转变成为XML格式,反之亦然. 我们把对象与关系数据库之间 ...
- zoj3791(An Easy Game) DP
意甲冠军:给定两个01弦s1,s2.每一个变化s1在m字 - 位.要求k制作步骤之后s1变s2有多少种方法. 解法:DP,关键是状态的设计.考虑还是唯一性和可传递性.dp[i][j]表示第i步后有j个 ...
- Crazy Rows
Problem You are given an N x N matrix with 0 and 1 values. You can swap any two adjacent rows of the ...
- ASP.NET MVC+EF框架+EasyUI实现权限管理系列(6)- EF上下文实例管理
原文:ASP.NET MVC+EF框架+EasyUI实现权限管理系列(6)- EF上下文实例管理 ASP.NET MVC+EF框架+EasyUI实现权限管系列 (开篇) (1):框架搭建 ( ...
- jquery.validate1.13
jquery.validate新的写法(jquery.validate1.13.js) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 ...