4 坦克移动和旋转

本节课的目标是实现同时wsad和上下左右控制两个坦克分别移动和旋转

4.1 本节代码预览

 
image

将上节课场景s2另存为s3.

4.2 添加车轮扬沙效果

从Prefabs里面找到DustTrail,拖放到Tank里面

 
image

单击DustTrail,改为LeftDustTrail,设置坐标为(-0.5,0,-0.75)

在Hierarchy里面使用快捷键Ctrl+D,复制LeftDustTrail,改为RightDustTrail,

设置坐标为(0.5,0,-0.75)

4.3 添加脚本

首先在Project面板中选中wm/Scripts文件夹,右键弹出新建菜单,选择

Create->C# Script

 
image

将默认脚本名称改为TankMove,注意大小写.

 
image

实现坦克移动和旋转有很多方法,这里介绍两种:使用transform和rigidbody.

4.4 使用transform移动和旋转(TankMove.cs)

TankMove.cs代码如下:

 
image

Transform有Translate()方法实现位置的移动,Rotate()方法实现旋转.

首先我们声明两个速度变量moveSpeed 和 turenSpeed

public float moveSpeed = 5; // 移动速度

public float turnSpeed = 90; // 旋转速度

在Update() 里面循环执行移动和旋转

void Update () {

    transform.Translate (Vector3.forward * moveSpeed * Time.deltaTime);// 移动

    transform.Rotate (transform.up * turnSpeed * Time.deltaTime);// 旋转

}

完整代码:

using UnityEngine;

using System.Collections;

public class TankMove : MonoBehaviour {

public float moveSpeed = 5; // 移动速度

public float turnSpeed = 90; // 旋转速度

// Update is called once per frame

void Update () {       

    transform.Translate (Vector3.forward * moveSpeed * Time.deltaTime);// 移动

    transform.Rotate (transform.up * turnSpeed * Time.deltaTime);// 旋转

}

}

为坦克挂载TankMove脚本

 
image

运行游戏,就能看到坦克在原地绕圈.

 
image

4.5 使用rigidbody移动和旋转(TankMoveRB.cs)

 
image

刚体有MovePosition方法可以实现刚体的移动,MoveRotation可以实现刚体的旋转.

最终代码如下:

using UnityEngine;

using System.Collections;

public class TankMoveRB : MonoBehaviour {

public float moveSpeed = 5; // 移动速度

public float turnSpeed = 90; // 旋转速度( 每秒90度)

private Rigidbody rb ; // 刚体组件

// Use this for initialization

void Start () {

    rb = GetComponent<Rigidbody> (); // 获取刚体组件

}

// Update is called once per frame

void FixedUpdate () {

    Vector3 movement = transform.forward * moveSpeed * Time.deltaTime;

    rb.MovePosition (transform.position + movement); // 移动到新坐标

    Quaternion turn = Quaternion.Euler (0, turnSpeed * Time.deltaTime, 0);

    rb.MoveRotation (rb.rotation * turn); // 旋转到新角度

}

}

4.6 添加键盘控制

使用菜单打开Input设置

 
image
 
image

a/d对应Horizontal1,ws对应Vertical1

 
image

在Update里面获取水平和垂直变量

private float moveInputValue = 0; // 移动输入变量

private float turnInputValue = 0; // 旋转输入变量

void Update(){

    moveInputValue = Input.GetAxis ("Vertical1");

    turnInputValue = Input.GetAxis ("Horizontal");   

}

然后将这两个变量当成参数乘到移动速度和旋转速度里面

Vector3 movement = transform.forward * moveSpeed * Time.deltaTime * moveInputValue ;

    rb.MovePosition (transform.position + movement); // 移动到新坐标

    Quaternion turn = Quaternion.Euler (0, turnSpeed * Time.deltaTime * turnInputValue , 0);

    rb.MoveRotation (rb.rotation * turn); // 旋转到新角度

TankMoveByKeyboad.cs全部代码:

using UnityEngine;

using System.Collections;

public class TankMoveByKeyboard : MonoBehaviour {

public float turnSpeed = 180; // 旋转速度( 每秒180度)

public float moveSpeed = 15; // 移动速度

private float moveInputValue = 0; // 移动输入变量

private float turnInputValue = 0; // 旋转输入变量

private Rigidbody rb ; // 刚体组件

// Use this for initialization

void Start () {

    rb = GetComponent<Rigidbody> (); // 获取刚体组件

}

// Update is called once per frame

void Update(){

    moveInputValue = Input.GetAxis ("Vertical1");

    turnInputValue = Input.GetAxis ("Horizontal1");   

}

// Update is called once per frame

void FixedUpdate () {

    Vector3 movement = transform.forward * moveSpeed * Time.deltaTime * moveInputValue ;

    rb.MovePosition (transform.position + movement); // 移动到新坐标

    Quaternion turn = Quaternion.Euler (0, turnSpeed * Time.deltaTime * turnInputValue , 0);

    rb.MoveRotation (rb.rotation * turn); // 旋转到新角度

}

}

4.7 区分坦克

将坦克的挂载TankMoveByKeyboard脚本,去掉其他脚本.

 
image

点击Prefab最右边的Apply保存预设体.

然后从wm/prefabs中拖放Tank到Hierarchy里面

改为Tank2,设置坐标为(5,0,0)

 
image

这时候我们有了两个Tank,点击运行.

然后我们会发现这时候两个Tank是一起运动和旋转的.

 
image

而我们最终实现的效果应该是两个坦克分别控制的,这时候我们再来看一下Input的设置

 
image

里面专门为两个坦克设置了不同的Axis,以1和2作为区分,那么问题来了,如何利用这一点呢?

这时候我们就要想到我们现在的脚本里是写死了Axis的,现在只需要能随意更改1或者2就可以了.

 
image

所以这时候我们就需要声明一个变量id来区别到底是哪个坦克.

 
image

这样我们就把两个坦克区分开了.

下面是TankMoveByKeyboard2.cs的完整代码:

using UnityEngine;

using System.Collections;

public class TankMoveByKeyboard2 : MonoBehaviour {

public float turnSpeed = 180; // 旋转速度( 每秒180度)

public float moveSpeed = 15; // 移动速度

private Rigidbody rb ; // 刚体组件

private float moveInputValue = 0; // 移动输入变量

private float turnInputValue = 0; // 旋转输入变量

public int id = 1; // tank id

// Use this for initialization

void Start () {

    rb = GetComponent<Rigidbody> (); // 获取刚体组件

}

void Update(){

    moveInputValue = Input.GetAxis ("Vertical" + id);

    turnInputValue = Input.GetAxis ("Horizontal" + id);   

}

// Update is called once per frame

void FixedUpdate () {

    Vector3 movement = transform.forward * moveSpeed * Time.deltaTime * moveInputValue ;

    rb.MovePosition (transform.position + movement); // 移动到新坐标

    Quaternion turn = Quaternion.Euler (0, turnSpeed * Time.deltaTime * turnInputValue , 0);

    rb.MoveRotation (rb.rotation * turn); // 旋转到新角度

}

}

将Tank上挂载的脚步更改为TankMoveByKeyboard2 ,Apply prefab.

Tank id设置为1,Tank2id设置为2

 
image
 
image

这时候我们就实现了两个坦克的分别控制

本节内容到此结束,希望通过本节内容大家可以加深对于变量的理解和应用.

---------------------------我是目录分割线---------------------------

《杜增强讲Unity之Tanks坦克大战》1-准备工作

《杜增强讲Unity之Tanks坦克大战》2-场景设置

《杜增强讲Unity之Tanks坦克大战》3-添加坦克

《杜增强讲Unity之Tanks坦克大战》4-坦克的移动和旋转

《杜增强讲Unity之Tanks坦克大战》5-子弹

《杜增强讲Unity之Tanks坦克大战》6-发射子弹

《杜增强讲Unity之Tanks坦克大战》7-坦克血条

《杜增强讲Unity之Tanks坦克大战》8-子弹碰撞处理

《杜增强讲Unity之Tanks坦克大战》9-发射子弹时蓄力

《杜增强讲Unity之Tanks坦克大战》10-相机控制

《杜增强讲Unity之Tanks坦克大战》11-游戏流程控制

---------------------------我是目录分割线---------------------------

《杜增强讲Unity之Tanks坦克大战》4-坦克的移动和旋转的更多相关文章

  1. 《杜增强讲Unity之Tanks坦克大战》10-相机控制

    10 相机控制 本节主要学习如何控制相机自动调整位置和焦距,使两个坦克一直同时在视野内.   image 在Hierarchy点击右键   image 点击 Create Empty,生成空对象,改名 ...

  2. 《杜增强讲Unity之Tanks坦克大战》11-游戏流程控制

    11 游戏流程控制 使用协程来控制游戏流程 11.1 添加MessageText 首先添加一个Text来显示文字   image 设置GameMgr   image 11.2 游戏整体流程 下面Gam ...

  3. 《杜增强讲Unity之Tanks坦克大战》9-发射子弹时蓄力

    9 发射子弹时蓄力 实现效果如下   image 按下开火键(坦克1为空格键)重置力为最小力,一直按着的时候蓄力,抬起的时候发射.如果按着的时候蓄力到最大,则自动发射,此时在抬起则不会重复发射. 首先 ...

  4. 《杜增强讲Unity之Tanks坦克大战》1-准备工作

    0.案例介绍 0.1开始界面   点击Play Now 进入游戏界面   左边的坦克使用ws控制前后移动,ad键左右旋转,空格键开火   右边的坦克使用方向键上下控制前后移动,方向键左右键实现左右旋转 ...

  5. 《杜增强讲Unity之Tanks坦克大战》2-场景设置

    2  场景设置 2.1 本节效果预览   2.2 项目目录设置 点击Project面板的Create按钮,在根目录下面新建wm文件夹   Wm文件夹用于存放我们自己生成的Prefab和脚本等其他资源, ...

  6. 《杜增强讲Unity之Tanks坦克大战》3-添加坦克

    3 添加坦克 3.1 本节效果预览   3.2 另存新场景 首先打开上次的场景s1,另存为s2,放到同一个文件夹下面.   3.3 添加坦克模型 在Model文件夹下面找到Tank模型   将Tank ...

  7. 《杜增强讲Unity之Tanks坦克大战》5-子弹

    5 子弹 本节的任务是创建子弹的Prefab   image 首先从Model/Shell找到子弹的模型,拖入Hierarchy中,添加刚体组件,所有属性默认值. 添加Capsule Collider ...

  8. 《杜增强讲Unity之Tanks坦克大战》6-发射子弹

    6 发射子弹 本节完成发射子弹的功能,最终代码如下:   image 首先,发射子弹得确定发射的位置和方向,还有发射的初始速度.具体的发射速度和按下发射按键的时间长短有关,这个关于子弹的蓄力我们在第九 ...

  9. 《杜增强讲Unity之Tanks坦克大战》7-坦克血条

    7 坦克血条 点击菜单GameObject->UI->Slider创建Slider   选中EventSystem,设置Horizontal Axis为HorzontalUI,Vertic ...

随机推荐

  1. [WPF]DropShadowEffect导致Image模糊问题

    实现鼠标在图片上时,图片外侧有发光效果,如上图 可使用触发器修改Image控件的Effect属性 <Style.Triggers> <Trigger Property="I ...

  2. Eclipse中Tomcat的配置

    1.Window-Preferences-Server-Runtime Environments 2.点击Add,选择相应的Tomcat版本,我的是7.0的所以我选择这个.并勾选Create a ne ...

  3. MySQL基础之 存储引擎

    MyISAM存储引擎 缺点:不支持事务,不支持外键.只支持表级锁. 优点:访问速度快,多用于select.insert语句的高负载操作.仅仅支持全文索引. MyISAM缓存在内存的是索引,不是数据.而 ...

  4. (二十)ArcGIS JS 加载WMTS服务(超图示例)

    前言 在前一篇中说到我们可以通过加载WMS服务解决用ArcGIS API加载超图发布的服务,但是WMS服务在加载效率上是低于切片服务的,加上超图的IServer,无力吐槽,所以,在加载速度的要求下,切 ...

  5. BZOJ4923:[Lydsy1706月赛]K小值查询(Splay)

    Description 维护一个长度为n的正整数序列a_1,a_2,...,a_n,支持以下两种操作: 1 k,将序列a从小到大排序,输出a_k的值. 2 k,将所有严格大于k的数a_i减去k. In ...

  6. Scala学习之路 (四)Scala的数组、映射、元组、集合

    一.数组 1.定长数组和变长数组 import scala.collection.mutable.ArrayBuffer object TestScala { def main(args: Array ...

  7. 服务器 三 MQTT服务器手机开发

    目的: 实现手机4G网络控制单片机,需要搭建服务器,手机或者各种控制端远程控制. 本教程 1  MQTT服务器硬件模块 2 MQTT服务器电脑搭建 2.1自己搭建 2.2租阿里云服务器 2 MQTT服 ...

  8. Docker技术入门与实战 第二版-学习笔记-10-Docker Machine 项目-2-driver

    1>使用的driver 1〉generic 使用带有SSH的现有VM/主机创建机器. 如果你使用的是机器不直接支持的provider,或者希望导入现有主机以允许Docker Machine进行管 ...

  9. pycharm同步

    只有专业版的才能同步服务器 按照这个来:https://zhuanlan.zhihu.com/p/35067462 3.然后配置映射信息 local path是自己的工程的本地目录路径, Deploy ...

  10. OpenCV——距离变换与分水岭算法的(图像分割)

    C++: void distanceTransform(InputArray src, OutputArray dst, int distanceType, int maskSize) 参数详解: I ...