朋友给的面试题,先试着做做
一,什么是泛型?泛型和传统类型的Boxing/Unboxing有什么区别?写一个泛型类C使其继承于Cbase。
泛型是使类型参数化实现在同一份代码上操作的多种类型,将算法从数据结构中抽象出来,使操作能够作用于不同的类型,提高程序的效率,通用性和类型安全性,进而简化整个编程模型。
区别:泛型避免了类型转化,性能更优,C#中装箱是指将值类型转换为引用类型,拆箱是指将引用类型转换为值类型,类型转化可能引起安全性问题,而且泛型解决了boxing的问题。
(⊙o⊙)…
泛型类:具有一个或多个类型变量的类
class C
创建泛型类实例时,需要为其变量赋值。C
泛型的继承 :泛型类需要保证它的所有构造类型都能够满足基类的要求,故而
public abstact class Cbase
{
public abstract void F(int i);//基类
}
public class C
{
public virtual void F(T t){ }
public override void F(int i){ }
}
泛型之间的继承原则:封闭类型不能继承开放类型。
二,OnEnable,Awake,Start执行的先后顺序:
Awake,OnEable,Start
三,正交摄像机和透视摄像机的区别,第一人称摄像机Fov变化会产生怎样的摄像机效果?
正交摄像机
Orthographic (无消失点投影)
正交视图无法看到一个物体是远离自己还是正在我们面前。为什么?因为它不会根据距离收缩。所以如果你如果你画一个固定大小的物体在视点前面,同时画一个同样大小的物体在第一个物体的远后方,你无法说那个物体是第一个。因为两个都是一样的大小,根距离无关。他们不会随着距离而收缩。通常我们在unity中制作2D UI,或是2D游戏的时候,就会把Camera的投射选择此项,例如NGUI的UICamera组件,默认的视图就是正交,还有2DTookit,也会把Main Camera的视图选择成正交,能准确表达物体在空间的位置。
透视摄像机
Perspective (有消失点投影)
透视视图和我们从眼睛看到的视图是一样的。例如,一个高个子的人站在你面前,他看上去是很高的。但是如果这个高个子站在100米以外,他甚至还没有你的拇指大。他看上去会随着距离而缩小,但是我们实际上都知道,它依然是个高个子。这种效果叫做透视。上面例子中提到的两个物体,第二个物体将会显示地更小,所以我们可以区分哪个是离我们近的物体,那个是离我们远的物体。这个在3D中经常用到,例如3D Max中几种不同的视图,而Unity的Main Camera默认也是这种视图,具有很强的空间表现力。
视角Fov是指:镜头能覆盖的范围,第一人称摄像机Fov变化后视野会随着数值变大而变宽。
四,给定屏幕一个点(x,y),如何进行对场景中的GameObject 进行射线拾取;
碰撞检测,RPG类型游戏捡装备,3D拾取技术,原理是当玩家用手指单击屏幕时生成一条由屏幕发射到游戏世界的射线,起点就是玩家手指触摸的地方。
先简单写一个移动端平台上的3d拾取代码
foreach(Touch touch in Input.touches)//对当前触控进行循环
{
Ray ray = Camera.mainScreenPointToRay(touch.position);//声明由触控点和摄像机组成的射线
RaycastHit hit;//声明一个RayCastHit型变量hit
if(Physics.Raycast(ray,out hit))//判断此物理事件,hit用来存储反馈信息
{
touchname = hit.transform.name;//获得射线触碰到物体的名称
}
}
介绍一下
RaycastHit(光线投射碰撞):用来获取从Raycast(光线投射)函数反馈回来的信息。常用变量有distance(射线起点到碰撞点的距离),collider(碰到的碰撞器),transform(碰到的变换组件)。
Ray(射线):包含origin(起点)和director(方向)两个变量,ScreenPointToRay函数创建一条射线,使用该函数时需要传递给它当前手指触摸的位置,如此便可创建一条以手指触摸为起点并射向3D世界的射线。
Physics.Raycast(光线投射):
Raycast函数用来向3D世界投射射线,返回值为bool型,碰到带有碰撞器的物体返回true,反之返回false.
借鉴书上的代码,自己不会写,先学学思想:PC端:
using UnityEngine;
using System.Collections;
public class Demo : MonoBehaviour{
public float smooth= 3f;//声明float变量,用于设置物体跟随鼠标移动的速度
Transform currentObject;//Transform 类型的变量
Vector3 mouse3DPosition;//Vector3类型变量,用于存储鼠标在世界坐标系的位置
void Update(){
if(Input.GetMouseButton(0))//判断鼠标左键是否被单击
{
Ray rays = Camera.main.
ScreenPointToRay(Input.mousePosition);//创建一条起点为光标位置的射线
Debug.DrawRay(rays.origin,rays.direction*100,Color.yellow);//将射线以黄色的细线表示出来
RaycastHit hit;//创建一个RaycastHit变量用于存储反馈信息
if(Physics.Raycast(rays,out hit))//将创建的射线投射出去并将反馈信息存储到hit 中
{
currentObject= hit.transform;//获取被射线碰到的对象transform变量
}
if(currentObject == null)//如果当前没有可被移动的对象,程序将不再执行
{
return;
}
Vector3 mp = Input.mousePosition;//存储光标在屏幕坐标的位置
mp.z= 6;//设置屏幕坐标转换到世界坐标系时世界坐标的深度
mouse3DPosition = Camera.main.ScreenToWorldPoint(mp);//将屏幕坐标转换为世界坐标
currentObject.position = Vector3.Lerp(currentObject.position,mouse3DPosition,smooth*Time.deltaTime);
//使用lerp函数将物体的位置平滑的过渡到光标所在世界坐标系的位置
}
if(Input.GetMouseButttonUp(0))//如果鼠标左键抬起,就将射线获取到的对象删除
{
currentObject = null;
}
}
}
移动端:
using UnityEngine;
using System.Collections;
public class Demo2 : MonoBehaviour
{
public float smooth =30.0f;//用于设置物体跟随手指的速度
Vector3 touch3DPosition;//Transform类型变量
Transform currentObject;//Vector3类型变量,用于存储手指触摸点在世界坐标系的位置
void Update()
{
foreach (Touch touch in Input.touches)
{
Ray ray = Camera.main.ScreenPointToRay(touch.position);//创建一条起点为手指触摸点的射线
RaycastHit hit;//创建一个RaycastHit变量用于存储反馈信息
if(Physics.Raycast(ray,out hit))//将创建的射线投射出去并将反馈信息存储到hit中
{
currentObject = hit.transform;//获取被射线碰到的对象transform变量
Debug.DrawRay(ray.origin,ray.direction * 20,Color.blue);//将投射的射线以蓝色的细线表示出来
}
if(currentObject == null)
{
return;
}
Vector3 mp = touch.position;//存储手指触摸点在屏幕坐标系的位置
mp.z = 6.0f;//设置屏幕坐标转换到世界坐标系时世界坐标的深度
touch3DPosition = Camera.main.ScreenToWorldPoint(mp);//将屏幕坐标转换为世界坐标
currentObject.position = Vector3.Lerp(currentObject.position,touch3DPosition,Time.time);//平滑过渡
if(touch.phase ==TouchPhase.Ended)
{
currentObject= null;
}
}
}
}
自己写的(⊙o⊙)…:
void Update()
{
if(Input.GetMouseButton(0))
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hitInfo;
if(Physics.Raycast(ray,out hitInfo))
{
Debug.DrawLine(ray.origin,hitInfo.point);
GameObject gameObj = hitInfo.collider.gameObject;\
Debug.Log("click object name is"+gameObj.name);
if(gameObj.tag=="food")
{
Debug.Log("pick up!");
}
}
}
}
@http://www.w3school.com.cn/index.html