摄像机用法总结
如何应用左手法则决定方向,应用 Field of view 设置场景大小
首先说明左手定则的应用是在unity中物体旋转方向的确定,据一个例子:
首先我放置一个camera,一个物体,让camera能照射到物体:
此时camera的坐标和角度是如下的:
目前的我的观察角度是在 “从y轴看下去”更形象一点就是 “Y轴箭头扎眼睛的方向”,我改变camera的y轴rotate的值如下:
摄像机角度改变如下:
如图所示,摄像机是旋转方向为 顺时针,如果将y轴替换为大拇指,则旋的方向为4个手指的方向,也就是左手定则
应用Field of views改变场景大小,例子如下:
其实Field of views 就是视角,因为Unity中,也是把对象投影在一个范围内的,所以也会有视角这个设定,比如说人的视角差不多是120度,而《火影忍者》里宁次的视角差不多是360度,所以他可以看到背后的敌人。鱼的双眼视角差不多也是360度,摄像机只能模仿一个眼睛的效果,如下:
Camera 继承的类
从源码看 Camera 是继承于 Behaviour 类的,而Behaviour继承于 Component,所以Camera是组件
Camera 有哪些静态属性,用程序验证并管理所有的 Camera ,并在程序中 enabled 部分有用的 Camera (切换摄像机)
根据官方文档可查到,Camera的静态变量有以下:
* allCameras 返回所有可以使用的camera
* allCamerasCount 翻译场景中所有照相机的数量
* current 当前用于渲染的相机,只用于低级的渲染控制
* main 第一个被启用的Camera会被标记为main
* onPostRender 任何一个camera结束rendering都会触发的时间
* onPreCull 任何一个camera开始culling的时候触发的事件
* onPrerRender 任何一个camera在开始rendering之前都会触发的事件
使用程序来控制camera:
对象树如下:
控制代码如下:
using UnityEngine;
using System.Collections;
public class camera : MonoBehaviour {
public Camera maincamera;
public Camera currentcamera;
public Camera[] cameras;
// Use this for initialization
void Start () {
print ("Cameralength = " + Camera.allCamerasCount); //输出camera数量
maincamera = Camera.main; // 获取maincamera
cameras = Camera.allCameras; // 获取所有的camera
currentcamera = Camera.current; // 获取当前的camera
}
// Update is called once per frame
void Update () {
changeCamera ();
}
void changeCamera(){
// 点击1,2,3切换canmera,注意3个camera必须在同一个display下
if (Input.GetKeyUp (KeyCode.Alpha1)) {
cameras [0].enabled = true;
cameras [1].enabled = false;
cameras [2].enabled = false;
} else if (Input.GetKeyUp (KeyCode.Alpha2)) {
cameras [0].enabled = false;
cameras [1].enabled = true;
cameras [2].enabled = false;
} else if (Input.GetKeyUp(KeyCode.Alpha3)){
cameras [0].enabled = false;
cameras [1].enabled = false;
cameras [2].enabled = true;
} else if (Input.GetKeyUp (KeyCode.M)) {
//点击M后,所有camera设为false,除了主摄像机以外
cameras [0].enabled = false;
cameras [1].enabled = false;
cameras [2].enabled = false;
maincamera.enabled = true;
}
}
}
添加一个 Empty 游戏对象, 添加一个 Camera 部件(Rendering 分类下),有什么效果
添加前:
添加后:
就已经是camera了,充分证明了camera的组件性质
光源用法总结
camera聚光灯
其实就是个camera添加light组件,light设为术光
给sun对象添加光源部分
使用light组件作为光源比用glew11更简单方便
没有将 Camera,Light 设计为 GameObject ,这给开发者带来哪些好处?
可以更方便的对对象进行使用,添加,修改。
面向对象语言接口和超类有哪些异同?
- 接口是公开的,里面不能有私有的方法或变量,是用于让别人使用的,而抽象类是可以有私有方法或私有变量的
- 实现接口的一定要实现接口里定义的所有方法,而实现抽象类可以有选择地重写需要用到的方法
- 接口可以实现多重继承,而一个类只能继承一个超类
IU3dActionCompleted 能设计为超类吗?为什么? 画 UML 图说明
不能,因为一个类只能继承一个超类,所以U3dActions 不能继承 Monobehaviours的同时再继承一个IU3ActionsCompleted类
U3dAction 能设计为接口吗?为什么? 画 UML 图说明
不能设计为接口,因为接口是不能有自己的私有变量和函数实现的
修改简单工厂的代码
理清代码之后,添加一个新动作是非常容易的,只需要3步:
- 首先判断这个动作是自动还是人控制的,然后创建这个动作的类 A 继承于 U3dActionAuto 或者 U3dActionMan,这个类里面的Update方法中写上你希望动作的执行方式
- 在ActionManager中写一个和你这个新动作相匹配的 Apply…(…)
- 在start()函数里添加该动作
- 在接口函数中写上相应的动作结束的时候,应该执行的动作
添加一个新动作,MoveToTargetAction(持续追击一个目标)
在原来代码的基础上创建一个 gameObject,名字为zhui,然后zhui会以0.9的速度持续追击Cube
添加一个新动作,MoveToAB_Action (组合动作,就是将两个MoveTo动作组合成一个新动作,动作执行完,就free掉)
用新写的函数MoveToAB_Action取代之前的让cube来回移动的函数,在该函数里创建子动作并调用,用完后destroy掉。(这里不清楚要求的Free具体是什么意思,所以现在函数里面直接实现,明白的同学求指教下)
添加一个新动作,MoveToTargetAB_Action
这个和上一个唯一的不同在于是以两个对象为目标而不是两个position为目标的。其他写法如上
对象树如下:
代码如下:
using UnityEngine;
using System.Collections;
using Com.Mygame;
namespace Com.Mygame {
public class ActionManager :System.Object {
private static ActionManager _instance;
public static ActionManager GetInstance(){
if (_instance == null) {
_instance = new ActionManager();
}
return _instance;
}
public U3dAction ApplyMoveToAction(GameObject obj, Vector3 target, int speed, IU3dActionCompleted completed){
MoveToAction ac = obj.AddComponent <MoveToAction> ();
ac.setting (target, speed, completed);
return ac;
}
public U3dAction ApplyMoveToAction(GameObject obj, Vector3 target, int speed) {
return ApplyMoveToAction (obj, target, speed, null);
}
public U3dAction ApplyMoveToAction(GameObject obj, GameObject obj2,float speed){
MoveToTargetAction ac = obj.AddComponent<MoveToTargetAction> ();
ac.setting (obj2, speed);
return ac;
}
public U3dAction ApplyMoveToAB_Action(GameObject obj, Vector3 A, Vector3 B, int speed){
MoveToAB_Action ac = obj.AddComponent<MoveToAB_Action>();
ac.setting (A,B,speed,obj);
return ac;
}
public U3dAction ApplyMoveToTargetAB_Action(GameObject obj,GameObject A,GameObject B,int speed){
MoveToTargetAB_Action ac = obj.AddComponent<MoveToTargetAB_Action> ();
ac.setting (A, B, speed, obj);
return ac;
}
}
public class U3dActionException : System.Exception {}
public interface IU3dActionCompleted {
void OnActionCompleted (U3dAction action);
}
public class U3dAction : MonoBehaviour {
public void Free(){}
}
public class U3dActionAuto : U3dAction {}
public class U3dActionMan : U3dAction {}
public class MoveToAction : U3dActionAuto {
public Vector3 target;
public int speed;
private IU3dActionCompleted monitor = null;
public void setting(Vector3 target, int speed, IU3dActionCompleted monitor){
this.target = target;
this.speed = speed;
this.monitor = monitor;
}
void Update () {
float step = speed * Time.deltaTime;
transform.position = Vector3.MoveTowards(transform.position, target, step);
if (transform.position == target) { // Auto Destroy After Completed
if (monitor != null) {
monitor.OnActionCompleted(this);
}
Destroy(this);
}
}
}
public class MoveToTargetAction : U3dActionAuto {
public GameObject target;
public float speed;
public void setting(GameObject target,float speed){
this.target = target;
this.speed = speed;
}
void Update() {
float step = speed * Time.deltaTime;
transform.position = Vector3.MoveTowards (transform.position, target.transform.position, step);
if(transform.position == target.transform.position){
// if get do nothing
}
}
}
public class MoveToAB_Action : U3dActionAuto {
public Vector3 A;
public Vector3 B;
public int speed;
public MoveToAction toA;
public MoveToAction toB;
public GameObject obj;
public void setting(Vector3 A,Vector3 B,int speed,GameObject obj) {
this.A = A;
this.B = B;
this.speed = speed;
this.obj = obj;
}
void Start(){
toA = obj.AddComponent<MoveToAction> ();
toA.setting (A, speed, null);
}
void Update() {
float step = speed * Time.deltaTime;
if (obj.transform.position == A) {
Destroy (obj.GetComponent("toA"));
toB = obj.AddComponent<MoveToAction> ();
toB.setting (B,speed,null);
}
if (obj.transform.position == B) {
Destroy (obj.GetComponent("toB"));
toA = obj.AddComponent<MoveToAction> ();
toA.setting (A,speed,null);
}
}
}
}
public class MoveToTargetAB_Action : U3dActionAuto {
public GameObject A;
public GameObject B;
public int speed;
public MoveToAction toA;
public MoveToAction toB;
public GameObject obj;
public void setting(GameObject A,GameObject B,int speed,GameObject obj) {
this.A = A;
this.B = B;
this.speed = speed;
this.obj = obj;
}
void Start(){
toA = obj.AddComponent<MoveToAction> ();
toA.setting (A.transform.position, speed, null);
}
void Update() {
float step = speed * Time.deltaTime;
if (obj.transform.position == A.transform.position) {
Destroy (obj.GetComponent("toA"));
toB = obj.AddComponent<MoveToAction> ();
toB.setting (B.transform.position,speed,null);
}
if (obj.transform.position == B.transform.position) {
Destroy (obj.GetComponent("toB"));
toA = obj.AddComponent<MoveToAction> ();
toA.setting (A.transform.position,speed,null);
}
}
}
public class U3dActions : MonoBehaviour, IU3dActionCompleted {
private GameObject cube;
private GameObject x;
private GameObject y;
private GameObject zhui;
public void OnActionCompleted (U3dAction action)
{
MoveToAction ma = action as MoveToAction;
if (ma.target == x.transform.position) {
ActionManager.GetInstance ().ApplyMoveToAction (cube, y.transform.position, 1, this);
} else {
ActionManager.GetInstance ().ApplyMoveToAction (cube, x.transform.position, 1, this);
}
}
// Use this for initialization
void Start () {
cube = GameObject.Find ("Cube");
x = GameObject.Find ("xx");
y = GameObject.Find ("yy");
zhui = GameObject.Find ("zhui");
//ActionManager.GetInstance ().ApplyMoveToAction (cube, x.transform.position,1,this);
// 以下这个是添加追击的方法
ActionManager.GetInstance ().ApplyMoveToAction (zhui, cube, 0.9f);
//以下是在两个坐标之间移动的方法
//ActionManager.GetInstance ().ApplyMoveToAB_Action (cube,x.transform.position, y.transform.position, 1);
//一下是在两个对象之间移动的方法
ActionManager.GetInstance ().ApplyMoveToTargetAB_Action (cube, x, y, 1);
}
// Update is called once per frame
void Update () {
}
}
简单工厂的好处,还能再游戏中做什么?
通过工厂模式,外界可以从直接创建具体对象的局面中摆脱出来,只要负责消费就可以了。而且不比管这些对象究竟是如何创建及如何组织的,明确了各自的职责和权利,有利于整个软件体系结构的优化。
所以工厂模式,不仅可以对动作,还可以对对象,方便的创建对象和场景的简单工厂