1. 案例简述

这个案例实现一个简单的坦克对战游戏,两个玩家在一个地图上PK。

2. 控制坦克移动

与案例一中小球的移动方式不同,坦克在横向上不能是平移,因此横向按键控制的应该是坦克旋转。

public float speed = 5;//前进速度
public float angularSpeed = 5;//旋转速度
private Rigidbody rd; void Start () {
rd = this.GetComponent<Rigidbody> ();
} void FixedUpdate(){
float v = Input.GetAxis ("VerticalPlayer" + number);//自定义虚拟轴
rd.velocity = transform.forward * v * speed;//根据情况需要在刚体组件Constraints冻结相应position或rotation float h = Input.GetAxis ("HorizontalPlayer" + number);
rd.angularVelocity = transform.up * h * angularSpeed;
}

(1)与Update()不同,Update()方法是游戏每渲染一帧调用一次,调用的频率会受机器影响,而FixedUpdate()是每隔一定时间间隔调用一次,调用的频率不受机器影响。因此,为了得到更逼真的物理效果,在模拟物理运动时,一般选择在FixedUpdate()中。

(2)由于游戏中有两个玩家,asdw和方向键需要控制两个不同角色,因此需要自定义虚拟轴,位置是:Edit->Project Setting->Input。

(3)根据实际情况,需要在刚体组件中的Constraints进行相应的Freeze操作。

3. 控制子弹发射

public class TankAttack : MonoBehaviour {

	public GameObject shellPrefab;//子弹的预设
public KeyCode fireKey = KeyCode.Space;//发射子弹的按键
public float shellSpeed = 15;//子弹射出速度
private Transform firePosition;//发射子弹的位置 void Start () {
firePosition = transform.Find ("FirePosition");
} void Update () {
if (Input.GetKeyDown(fireKey)) {
GameObject go = GameObject.Instantiate (shellPrefab, firePosition.position, firePosition.rotation) as GameObject;//生成子弹
go.GetComponent<Rigidbody> ().velocity = go.transform.forward * shellSpeed;//发射子弹
}
}
}

生成子弹的位置是坦克炮筒处,因此在该处新建一个空对象,调整其旋转角度,这个对象的transform即可作为生成子弹的transform。

public class Shell : MonoBehaviour {

	public GameObject shellExplosionPrefab;

	...

	void OnCollisionEnter(Collision collision){
GameObject.Instantiate (shellExplosionPrefab, transform.position, transform.rotation);
GameObject.Destroy (this.gameObject);//若传入参数为this,则值销毁当前脚本而非游戏对象
}
}

对子弹进行碰撞检测(触发检测也可以,区别在于爆炸前有无撞击效果),当子弹击中物体时即在当前位置生成爆炸特效,同时销毁子弹对象。

public class DestroyForTime : MonoBehaviour {

	public float time;//在检视面板传入该特效的播放时长

	void Start () {
Destroy (this.gameObject, time);//播放完毕后销毁
}
}

给爆炸特效增加脚本,当特效播放完毕后销毁对象。

4. 子弹击中坦克产生伤害

在子弹击中坦克后,主要处理在坦克的生命值上,因此在子弹的碰撞检测中发送消息,而后在坦克中进行处理。

if (collision.collider.tag == "Tank") {
collision.collider.SendMessage ("TakeDamage");//若击中坦克,则发送消息
}

给坦克增加一个单独的脚本进行生命值的控制:

public class TankHealth : MonoBehaviour {

	public GameObject tankExposionPrefab;
public int health = 100; void TakeDamage(){
health -= Random.Range (10, 20);
if (health <= 0) {
GameObject.Instantiate (tankExposionPrefab, this.transform.position, this.transform.rotation);
GameObject.Destroy (this.gameObject);
}
}
}

5. 双主角的情况下控制相机跟随、视野缩放

public class FollowTarget : MonoBehaviour {

	public Transform player1;
public Transform player2; private Camera camera;
private Vector3 offset; void Start () {
camera = this.GetComponent<Camera> ();
offset = transform.position - (player1.position + player2.position) / 2;
} void Update () {
transform.position = (player1.position + player2.position) / 2 + offset;
float distance = Vector3.Distance (player1.position, player2.position);
float size = distance;
camera.orthographicSize = size;//让正交相机视野实时改变
}
}

(1)双角色的相机跟随本质上与单角色没太大区别,只是将视点定在两个角色的中心点,通过中心点计算相机的偏移量,实时更新相机的position。

(2)视野的缩放则是利用了正交相机的size与两个角色之间的距离之比进行更改,案例中两角色之间初始距离为10,相机size为10,因此比例为1,所以直接让size = distance。

6. 控制声音播放

AudioSource.PlayClipAtPoint (tankExposionAudio, this.transform.position);

第一种方法,播放获得的AudioClip对象,第一个参数为AudioClip对象,第二个参数为播放位置。

第二种方法,为游戏对象添加一个AudioSource组件,在脚本中通过GetComponent()方法获得该组件,调用其play()方法进行播放。

案例下载 密码:z79o

最新文章

  1. vue.js第六课
  2. TextView 选择文字
  3. [深入浅出Windows 10]模拟实现微信的彩蛋动画
  4. C#控制管理VisualSVN Server 分类: C# 2014-05-29 15:51 796人阅读 评论(0) 收藏
  5. abstract 和 interfaces 的用法注意事项
  6. 初识 css3中counter属性
  7. tomcat work 目录
  8. vector如何进行局部排序
  9. 利用H5新特性判断文件大小
  10. Microsoft Windows 2003 SP2 - &#39;ERRATICGOPHER&#39; SMB Remote Code Execution
  11. Web browser发展演变
  12. js-闪烁的文字
  13. java springboot activemq 邮件短信微服务,解决国际化服务的国内外兼容性问题,含各服务商调研情况
  14. P1330 封锁阳光大学
  15. AngularJs指令配置参数scope详解
  16. 卸载重装ArcGIS Enterprise 注意事项
  17. python 获取当前时间戳
  18. 关于文章cisco漏洞4786
  19. 安装zabbix3.4的过程(一)
  20. Openstack入门篇(十四)之horizon服务的部署与测试

热门文章

  1. 小甲鱼OD学习第6讲
  2. PHP执行Session与前端JS之间的关系
  3. 利用ajax获取网页表单数据,并存储到数据库之一(使用JDBC)
  4. linux磁盘及分区详解
  5. 解决react-router4在browserhistory路由下的nginx的白屏或者404问题
  6. angular4升级angular5问题记录之No NgModule metadata found for &#39;AppModule&#39;
  7. Maven项目热部署,修改代码后不用重启tomcat服务器
  8. 报错信息 The jsp:param action must not be used outside the jsp:include, jsp:forward, or jsp:params elements 的原因及解决办法
  9. Linux 格式化和挂载数据盘
  10. filter-api文档