《Unity In Action》读书笔记(一)

Unity最大的优点:可视化的工作流和跨平台的支持。Unity基于component的设计,使得一个component能被重复的使用。

Unity的缺点有:查找功能不够强大,有时候在项目中查找脚本比较麻烦;不支持链接到第三方库,要使用时必须手动拷贝到工程中来;prefab是Unity独有的重要功能,但是编辑prefab又不太方便。这些都希望在以后的版本中得到改进。

Unity开发的产品横跨三大平台(主机、PC、手机),比较著名的有:炉石传说、王者荣耀、神庙逃亡、捣蛋猪(愤怒的小鸟)、高尔夫俱乐部等。

Unity推荐的官方开发语言有C#和JavaScript,这里的JavaScript与标准版有所不同。

所有的Unity脚本都要继承MonoBehaviour,它提供了Start()和Update()方法以供重载。前者是在脚本关联的对象被激活时(也就是对象所在层级被加载时)调用。

构建一个FPS游戏场景需要:创建场景和人物,放置光源,将camera与人物绑定,处理移动脚本。

以大拇指为x轴,食指y轴,中指z轴,可将三维坐标系分为:左手系和右手系。Unity使用的是左手系,OpenGL用的是右手系。左手系和右手系区别在于:左手系的z轴由近及远,右手系的z轴由远及近。

Unity的对象层级结构是树状的,对象与对象之间呈父子关系。当没有合适的根对象时我们可以创建空的根对象。这里指的对象都是GameObject,它实际上是一系列component的容器,装载的component实际上决定了GameObject的作用。

Unity支持三种类型的光源:点光源(point)、聚光灯(spot)、平行光(directional)。分别类似于灯泡、手电筒、阳光。point和spot可以指定光照范围,它们比directional带来更多的内存消耗。离point越近照得越亮。

创建的Cube对象会自带如下基础component:Transform,Mesh Filter(几何形状),Box Collider(处理碰撞),Mesh Renderer(负责网格的渲染)。

Capsule默认自带capsule collider,这里移除并替换成character controller,为了更好地模拟人的动作。

将camera绑定在角色身上,设置位置为(0, 0.5, 0),让其跟着角色移动。

Rotate()方法默认使用本地坐标系,若需使用全局坐标系需额外注明:Rotate(0, speed, 0, Space.World)

下面是视角随鼠标旋转的代码:

// x轴上的变化对应的是y轴上的旋转
float rotationY = transform.localEulerAngles.y + Input.GetAxis("Mouse X") * sensitivityHor;
_rotationX -= Input.GetAxis("Mouse Y") * sensitivityVert;
// 对于x轴上的旋转,应控制范围
_rotationX = Mathf.Clamp(_rotationX, minimumVert, maximumVert);
// 将新的向量赋值给欧拉角
transform.localEulerAngles = new Vector3(_rotationX, rotationY, 0);

localRotation使用的是四元数,localEulerAngles使用的是欧拉角,两者可以互相转换。四元数的优点是:避免万向节锁,提供平滑插值,表达效率高。

Rigidbody中的freezeRotation属性可以禁用物理模拟引起的转动。

下面是位置随键盘输入移动的代码:

void Start() {
    // 要做碰撞必须使用CharacterController
    _charController = GetComponent<CharacterController>();
}
void Update() {
    float deltaX = Input.GetAxis("Horizontal") * speed;
    float deltaZ = Input.GetAxis("Vertical") * speed;
    Vector3 movement = new Vector3(deltaX, 0, deltaZ);
    // 斜线运动时不能超过最大速度
    movement = Vector3.ClampMagnitude(movement, speed);
    // 避免飞起来
    movement.y = gravity;
    // 考虑避免不同帧数的影响
    movement *= Time.deltaTime;
    // 从本地坐标系转成全局坐标系(若是用Translate()方法则是用本地坐标系,但是没有碰撞)
    movement = transform.TransformDirection(movement);
    _charController.Move(movement);
}

可以通过RequireComponent和AddComponentMenu声明来标注component依赖关系,使得component之间能够相互调用。

猜你喜欢

转载自blog.csdn.net/needmorecode/article/details/79935468
今日推荐