zoukankan      html  css  js  c++  java
  • 《杜增强讲Unity之Tanks坦克大战》4-坦克的移动和旋转

    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-游戏流程控制

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


    /// <-----------summary----------->
    /// < ---------杜增强的博客--------->
    /// < -专注于Unity游戏,VR/AR开发->
    /// <-----------summary----------->
  • 相关阅读:
    perl学习笔记之:正则表达式
    POJ 3436 ACM Computer Factory (拆点+输出解)
    POJ 3436 ACM Computer Factory (拆点+输出解)
    POJ 1637 Sightseeing tour ★混合图欧拉回路
    POJ 1637 Sightseeing tour ★混合图欧拉回路
    POJ 1149 PIGS ★(经典网络流构图)
    POJ 1149 PIGS ★(经典网络流构图)
    HDU 4571 Travel in time ★(2013 ACM/ICPC长沙邀请赛)
    HDU 4571 Travel in time ★(2013 ACM/ICPC长沙邀请赛)
    UPC 2224 Boring Counting ★(山东省第四届ACM程序设计竞赛 tag:线段树)
  • 原文地址:https://www.cnblogs.com/duzq/p/9832138.html
Copyright © 2011-2022 走看看