罗老师的新著作《3D网络游戏实战第二版》已经上架啦,精益求精,内容详实易懂,大家快去购买吧。
导入模型
将资源文件(fbx模型)拖到Unity的Project面板下,会将这些文件复制到Asset文件夹中,还会自动创建materials文件夹,包含了模型的材质。
调整尺寸
可以临时创建一个1m*1m*1m的方块作为参考系。推荐使用scale factor ,在import settings 中设置scalefactor,不建议用拉伸模型的方法。游戏工程涉及文件多,需要整理工程目录。
Unity的Input类封装了键盘,鼠标,触摸屏等输入方法:
GetAxis:返回指定坐标轴的值,如Input.GetAxis("MouseX")就是返回鼠标X轴的移动速度,Horizontal,获取横轴轴向的方法,左返回-1,右返回1;
GetKey:按住指定的按键返回true,如:Input.GetKey(KeyCode.UpArrow);
GetKeyDown:按下返回true;
GetMouseButton:返回鼠标按钮,0,1,2分别表示左右中。
GetTouch:返回触摸信息
常用的Transform组件:
(local)position:(相对于父节点)世界坐标位置
(local)eulerAngles:旋转的欧拉角度
right,up,forward:x,y,z三个轴的方向
Translate:移动物体
Rotate:旋转
LookAt:旋转,对准目标
Find,FindChild:通过名字查找子物体
GetChild:获取子物体,注意是通过索引获取,如0表示第一个子物体。
DIY!
Time.deltaTime:指的是两次执行Update的时间间隔。transform的right,up,forward都是自身坐标系方向。
相机跟随(第三人称视角)
1)相机要跟着坦克移动;
2)使用鼠标控制相机的角度;
3)鼠标滚轮调整与坦克的距离。
可以在坦克加上一个cameraPoint的点,精确控制相机对准的中心点,代码如下:
if (target.transform.FindChild("cameraPoint") != null){
this.target = target.transform. FindChild("cameraPoint").gameObject;
}
else{
this.target = target;
}
用Input.GetAxis("Mouse ScrollWheel")获取鼠标滚轮的增量。向上滚减少,向下增加。用maxdistance,mindistance,zoomspeed控制镜头移动。
为了使坦克可以紧贴着地面移动,以及保证不会原地旋转,需要使用unity自带的WheelCollider实现车辆控制。下面简单介绍Unity的物理系统:
重力系统不介绍,可以通过程序添加力的作用,如下:
Rigidbody rb = gameObject.GetComponent<Rigidbody>();
Vector3 force = Vector.up * 50;
rb.AddForce(force);
当带有Rigidbody和Collider的对象碰撞时,会调用OnColliderEnter()方法。类似的还有:
OnTriggerEnter : 进入触发器
OnTriggerStay : 停留在触发器内
OnTriggerExit : 退出触发器
//Trigger 换成 Collision 也有一样的三个方法。
回到WheelCollider,这是Unity专为有轮子的车制作的碰撞器。首先要添加Rigidbody,这是碰撞的基础组件,并将Mass属性调整为300的较大值。
需要在Tank的物体底下添加PhysicalBody的空物体,下面包括四个空物体表示轮子,两个collider的空物体用于车身碰撞。两个collider添加BoxCollider组件,拖动调整碰撞体的大小和位置,用于实现障碍碰撞检测和子弹检测。
WheelCollider 的 Radius 属性调整轮子碰撞器的大小,细微的差别都会影响很大。还能模拟汽车的悬挂系统,引擎系统,轮胎摩擦特性。其他属性包括:mass,质量;radius,半径;suspensionDistance,悬挂距离;center,轮子中心;suspensionSpring,悬挂阻尼;forwardFriction,前摩擦力;sidewaysFriction,侧摩擦力。motorTorque,扭矩;brakeTorque,刹车力;steerAngle,转向角。centerOfMass,车辆重心;spring,悬挂的弹性;damper,悬挂阻尼,影响弹簧震动;targetPosition,悬挂的压缩率,0-1之间变动。extremumSlip,滑动极值点默认为1;extremumValue,极值点的力;asymptoteSlip,渐进线点默认为2;asymptoteValue:滑动力;stiffness:加在两个值上的倍数默认为1。
[System.Serializable]
public class AxleInfo
{
public WheelCollider LeftWheel;
public WheelCollider RightWheel;
public bool motor;
public bool steering;
}
串行化使得该类的成员可以在属性面板显示。
LeftWheel 和 RightWheel 分别一条轴上的两个车轮碰撞器。Motor 指的是是否将马力分配到轴上,steering 是轮子是否转向。
在 Tank 类中添加控制车轴的方法,定义两个 AxleInfo ,用一个 List 存储,需要在前面添加 using System.Collections.Generic 引用该命名空间。还需要定义 motor 表示最大马力; maxMotorTorque 表示最大制动;brakeTorque 表示最大制动力;steering 表示最大转向角;
将控制逻辑写在一个 PlayerCtrl ,可以方便实现电脑控制和玩家操作。用 rpm 判断坦克是否在前行。为了使得轮子可以转动,将轮子放在 wheels 的空物体,根据转速旋转 wheels 下的所有物体。可以给轮子包裹一个空物体,然后让空物体在轮子的中心。
履带滚动通过改变材质实现,改变贴图的偏移值 Offset.Y 即可实现。用 AudioSource 和 AudioClip 定义音频文件,用 AddComponent 添加音源组件,设置 SpatialBlend 为1,声音从 AudioSource 播放出来。
网友评论