unity官方教程TANKS,难度系数中阶。
跟着官方教程学习Unity,通过本教程你可以学会使用Unity开发游戏的基本流程。

一、环境

Unity 版本 > 5.2
Asset Store 里面搜索 Tanks!Tutorial ,下载导入

二、项目设置

为了便于开发,很多时候我们选用的窗口布局是 2by3 Layout,然后将 Project 面板拖动到 Hierarchy 面板下面,如下图所示

三、场景设置

项目设置完毕后,就进入场景设置环节

1、新建一个场景,命名为 Main
2、删除场景中的 Directional Light
3、找到 Prefabs 文件夹下的 LevelArt,将其拖入 Hierarchy 内,这个 prefab 是我们的游戏地形
4、打开菜单 Windows->Lighting->Settings,取消 Auto Generate 和 Baked GI,将 Environment Lighting Source 改为 Color,并将颜色设置为(72,62,113),点击 Generate Lighting,这一步主要是渲染设置
5、调整 Main Camera 位置为 (-43,42,-25),旋转属性为 (40,60,0),投影改为正交 Orthographic,Clear Flags 改为 Solid Color ,Background 颜色设置为(80,60,50),Clear Flags不设置也可以,这个设置主要影响的是相机移动到看不到场景内的物体时屏幕显示的天空盒还是自己设置的 Solid Color 颜色

四、坦克设置

现在要往场景里加坦克了

1、在 Models 文件夹里面找到 Tank,将其拖拽到 Hierarchy 中
2、选中 Tank,在Inspector面板将 Layer 设置为 Players,跳出对话框时选 No,this object only
3、给 Tank 添加一个 Rigidbody Component,展开 Constraints 选项,勾选 Freeze Position Y 和 Freeze Rotation X Z,因为地面位于 XZ 平面,所以限定坦克不能在 Y 方向移动并且只能沿 Y 轴转动
4、给 Tank 添加一个 Box Collider Component,将其中心 Center 调整为(0,0.85,0),尺寸 Size 调整为(1.5,1.7,1.6)
5、给 Tank 添加两个 Audio Source Component,将第一个 Audio Source 的 AudioClip 属性填充为 Engine Idle(坦克不动时的音频),并勾选 Loop,将第二个 Audio Source 的 Play On Awake 取消
6、选中 Project 面板的 Prefabs 文件夹,将 Tank 拖入到该文件夹,至此我们就创建好了坦克 Prefab
7、将 Prefabs 文件夹中的 DustTrail 拖到 Hierarchy 面板中的 Tank 物体上,使其成为 Tank 的子物体,并Crtl + D(windows)复制一个,然后重命名为 LeftDustTrail 和 RightDustTrail,这是特效 - 坦克运动过程地面扬起的土
8、调整 LeftDustTrail 的 position 为(-0.5,0,-0.75),RightDustTrail 的position 为(0.5,0,-0.75)

以上过程便制作好了游戏主角 Tank,下面就要编程控制它运动了

1、找到 ScriptsTank 文件夹下的 TankMovement.cs,将其拖入到 Tank 物体上,打开 TankMovement.cs

public class TankMovement : MonoBehaviour
{public int m_PlayerNumber = 1;         public float m_Speed = 12f;            public float m_TurnSpeed = 180f;       public AudioSource m_MovementAudio;    public AudioClip m_EngineIdling;       public AudioClip m_EngineDriving;      public float m_PitchRange = 0.2f;/*private string m_MovementAxisName;     private string m_TurnAxisName;         private Rigidbody m_Rigidbody;         private float m_MovementInputValue;    private float m_TurnInputValue;        private float m_OriginalPitch;         private void Awake(){m_Rigidbody = GetComponent<Rigidbody>();}private void OnEnable (){m_Rigidbody.isKinematic = false;m_MovementInputValue = 0f;m_TurnInputValue = 0f;}private void OnDisable (){m_Rigidbody.isKinematic = true;}private void Start(){m_MovementAxisName = "Vertical" + m_PlayerNumber;m_TurnAxisName = "Horizontal" + m_PlayerNumber;m_OriginalPitch = m_MovementAudio.pitch;}*/private void Update(){// Store the player's input and make sure the audio for the engine is playing.}private void EngineAudio(){// Play the correct audio clip based on whether or not the tank is moving and what audio is currently playing.}private void FixedUpdate(){// Move and turn the tank.}private void Move(){// Adjust the position of the tank based on the player's input.}private void Turn(){// Adjust the rotation of the tank based on the player's input.}
}

里面已经有一些代码了,下面我们就对其扩充来控制坦克移动
Unity控制物体移动的方法主要有两种:
①非刚体(Update)
obj.transform.position = obj.transform.position+移动向量*Time.deltaTime;
obj.transform.Translate(移动向量*Time.deltaTime);
②刚体(FixedUpdate)
GetComponent<Rigidbody>().velocity
GetComponent<Rigidbody>().AddForce
GetComponent<Rigidbody>().MovePosition

由于我们的坦克是刚体,且移动被限制在了 XZ 平面,此时最好的方式是采用 MovePosition
获取用户输入

    private void Start(){//在菜单Edit->Project Settings->Input设置,默认玩家1左右移动按键是 a 和 d,前后按键是 w 和 sm_MovementAxisName = "Vertical" + m_PlayerNumber;m_TurnAxisName = "Horizontal" + m_PlayerNumber;}private void Update(){//获取用户通过按键 w 和 s 的输入量m_MovementInputValue = Input.GetAxis(m_MovementAxisName);//获取用户通过按键 a 和 d 的输入量m_TurnInputValue = Input.GetAxis(m_TurnAxisName);}

移动和转动

    private void Move(){Vector3 movement = transform.forward * m_MovementInputValue * m_Speed * Time.deltaTime;m_Rigidbody.MovePosition(m_Rigidbody.position + movement);}private void Turn(){float turn = m_TurnInputValue * m_TurnSpeed * Time.deltaTime;// 沿y轴转动Quaternion turnRotation = Quaternion.Euler(0f, turn, 0f);m_Rigidbody.MoveRotation(m_Rigidbody.rotation * turnRotation);}

音效控制

    private void EngineAudio(){// 坦克是静止的if (Mathf.Abs(m_MovementInputValue) < 0.1f && Mathf.Abs(m_TurnInputValue) < 0.1f){// 若此时播放的是坦克运动时的音效if (m_MovementAudio.clip == m_EngineDriving){m_MovementAudio.clip = m_EngineIdling;m_MovementAudio.pitch = Random.Range(m_OriginalPitch - m_PitchRange, m_OriginalPitch + m_PitchRange);//控制音频播放速度m_MovementAudio.Play();}}else{if (m_MovementAudio.clip == m_EngineIdling){m_MovementAudio.clip = m_EngineDriving;m_MovementAudio.pitch = Random.Range(m_OriginalPitch - m_PitchRange, m_OriginalPitch + m_PitchRange);//控制音频播放速度m_MovementAudio.Play();}}}

TankMovement.cs 完整代码

using UnityEngine;public class TankMovement : MonoBehaviour
{public int m_PlayerNumber = 1;              // Used to identify which tank belongs to which player.  This is set by this tank's manager.public float m_Speed = 12f;                 // How fast the tank moves forward and back.public float m_TurnSpeed = 180f;            // How fast the tank turns in degrees per second.public AudioSource m_MovementAudio;         // Reference to the audio source used to play engine sounds. NB: different to the shooting audio source.public AudioClip m_EngineIdling;            // Audio to play when the tank isn't moving.public AudioClip m_EngineDriving;           // Audio to play when the tank is moving.public float m_PitchRange = 0.2f;           // The amount by which the pitch of the engine noises can vary.private string m_MovementAxisName;          // The name of the input axis for moving forward and back.private string m_TurnAxisName;              // The name of the input axis for turning.private Rigidbody m_Rigidbody;              // Reference used to move the tank.private float m_MovementInputValue;         // The current value of the movement input.private float m_TurnInputValue;             // The current value of the turn input.private float m_OriginalPitch;              // The pitch of the audio source at the start of the scene.private void Awake(){m_Rigidbody = GetComponent<Rigidbody>();}private void OnEnable(){// When the tank is turned on, make sure it's not kinematic.m_Rigidbody.isKinematic = false;// Also reset the input values.m_MovementInputValue = 0f;m_TurnInputValue = 0f;}private void OnDisable(){// When the tank is turned off, set it to kinematic so it stops moving.m_Rigidbody.isKinematic = true;}private void Start(){// The axes names are based on player number.m_MovementAxisName = "Vertical" + m_PlayerNumber;m_TurnAxisName = "Horizontal" + m_PlayerNumber;// Store the original pitch of the audio source.m_OriginalPitch = m_MovementAudio.pitch;}private void Update(){// Store the value of both input axes.m_MovementInputValue = Input.GetAxis(m_MovementAxisName);m_TurnInputValue = Input.GetAxis(m_TurnAxisName);EngineAudio();}private void EngineAudio(){// If there is no input (the tank is stationary)...if (Mathf.Abs(m_MovementInputValue) < 0.1f && Mathf.Abs(m_TurnInputValue) < 0.1f){// ... and if the audio source is currently playing the driving clip...if (m_MovementAudio.clip == m_EngineDriving){// ... change the clip to idling and play it.m_MovementAudio.clip = m_EngineIdling;m_MovementAudio.pitch = Random.Range(m_OriginalPitch - m_PitchRange, m_OriginalPitch + m_PitchRange);m_MovementAudio.Play();}}else{// Otherwise if the tank is moving and if the idling clip is currently playing...if (m_MovementAudio.clip == m_EngineIdling){// ... change the clip to driving and play.m_MovementAudio.clip = m_EngineDriving;m_MovementAudio.pitch = Random.Range(m_OriginalPitch - m_PitchRange, m_OriginalPitch + m_PitchRange);m_MovementAudio.Play();}}}private void FixedUpdate(){// Adjust the rigidbodies position and orientation in FixedUpdate.Move();Turn();}private void Move(){// Create a vector in the direction the tank is facing with a magnitude based on the input, speed and the time between frames.Vector3 movement = transform.forward * m_MovementInputValue * m_Speed * Time.deltaTime;// Apply this movement to the rigidbody's position.m_Rigidbody.MovePosition(m_Rigidbody.position + movement);}private void Turn(){// Determine the number of degrees to be turned based on the input, speed and time between frames.float turn = m_TurnInputValue * m_TurnSpeed * Time.deltaTime;// Make this into a rotation in the y axis.Quaternion turnRotation = Quaternion.Euler(0f, turn, 0f);// Apply this rotation to the rigidbody's rotation.m_Rigidbody.MoveRotation(m_Rigidbody.rotation * turnRotation);}
}

2、在将 TankMovement.cs 拖入到 Tank 上时,选择 Tank 的第一个 Audio Source Component 拖入到TankMovement 的 Movement Audio上,并选择 Engine Idling 为 EngineIdle 音频,Engine Drving 为 EngineDrving 音频,至此点击 Apply,将我们后面对 Tank 的修改保存到 Tank prefab 中

3、保存场景,点击 Play 试玩一下

通过今天的教程,你可以学会

  • 场景设置,基本的物体操作
  • 编程控制物体移动

下期教程继续。。。

unity官方教程-TANKS(一)相关推荐

  1. Unity官方教程Ruby大冒险的自学笔记

    Unity官方教程Ruby大冒险的自学笔记 一. //正确例子: void Update(){//获取运动矢量moveX = Input.GetAxisRaw("Horizontal&quo ...

  2. 噩梦射手 安装包资源包提供下载 Unity官方教程 Survival Shooter 资源已经失效了!? Unity3D休闲射击类游戏《Survival Shooter》完整源码

    Unity官方教程 (Survival Shooter)  资源已经失效了! 可能是版本太老了 中文名叫噩梦射手? 找了半天找了这个版本 的 放到这里吧 [这个游戏主角是必死的,就看能坚持多久啦] 网 ...

  3. Unity官方教程与使用方法介绍

    Unity官方教程与使用方法介绍

  4. Unity官方教程滚球游戏实现(Roll A Ball)带工程源码

    记学习unity之后做出的第一款游戏   第一次使用Unity,在学成C#基础之后,迫不及待的照着教程做出了这个游戏,第一课最主要学习的东西就是Unity API的使用及场景中各个界面面板的主要功能, ...

  5. [Unity教程]Unity官方教程资源一览及其说明

    在Unity 安装的时候,会提示安装的 组件,里面就有 教程 和 标准 工程.详见相关文章1 如果没有安装教程 ,可以 在 Unity 的 AssetStore 里面搜索 publisher:Unit ...

  6. unity官方教程 太空射击---问题填坑 之 计分以及游戏胜利

    (本文仅供自己参考,文中代码可能有误,毕竟手打没有VS的帮助,请仅供理解,切莫复制粘贴)原来的代码还是不理解为什么,但现在有了新的方法,前排提醒,一下方法会与官方教程出现巨大误差,请理解后使用 首先我 ...

  7. Unity 3D官方教程——Tanks!学习记录

    1.游戏界面基础设置 先在官方资源商店导入Tank!的所有资源(怎样导入已在Survival Shooter中说明),新建_Scenes文件夹,将新场景命名为Main并保存. 删除Hierarchy下 ...

  8. Unity官方教程Roll-a-ball (一)

    这是一个官方的教程,附上地址http://unity3d.com/cn/learn/tutorials/projects/roll-a-ball/set-up,因为是youtube的,怕有些人看不了, ...

  9. Unity官方教程—space shooter练习日记之脚色移动

    从官方下载下来的资源,代码通过自主视频获得,还是得感谢下58 首先是传统的虚拟轴的使用        float moveHorizontal = Input.GetAxis("Horizo ...

最新文章

  1. 用简单的C语言实现多任务轮流切换(模拟操作系统线程机制)【转】
  2. Error in hist.default(data) : ‘x‘ must be numeric
  3. leetcode算法题--最长回文子序列★★
  4. 小米自动化运维平台演进设计思路
  5. AgilePoint模型驱动BPM(业务流程管理)介绍
  6. access在sql中横向求和_access在sql中横向求和_求和还用Sum函数就out了,快捷键Alt+=一秒搞定,操作简单更高效......
  7. hdu 1251 统计难题(求前缀出现了多少次)
  8. 计算机组装与维护配置清单作业,计算机组装与维护 作业汇.doc
  9. Android继承AppCompatActivity实现全屏设置
  10. 实现 iOS UICollectionView的事件透传
  11. iphone保修期多久_小心!教你如何鉴别 iPhone 翻新机,黑机千万别买!
  12. yolo v4模型训练过程(超详细)
  13. 使用 Python 学习和破解古典密码
  14. 爬虫课第一次报错总结
  15. 计算机主板设置语言,技嘉主板bios设置中文对照的方法步骤
  16. Open3D Intrinsic shape signatures (ISS) 固有形状特征码
  17. 中国酒店周刊 | 上海万信福朋喜来登、包头茂业万豪、武汉江夏万枫酒店开业...
  18. 用Custom Element来实现UI组件
  19. 武汉理工大学博士生导师计算机,博士学位论文预答辩公告-武汉理工大学计算机学院.DOC...
  20. 处理器_深度学习及 KPU 基础知识

热门文章

  1. mysql 查询 汇总_Mysql-Sql查询汇总
  2. antd table动态表头_解决react使用antd table组件固定表头后,表头和表体列不对齐以及配置fixed固定左右侧后行高度不对齐...
  3. url上接收到 el表达式 不渲染_一文摸透从输入URL到页面渲染的过程
  4. iOS核心动画 Core Animation2-CABasicAnimation
  5. 算法(伪代码)的书写
  6. IScroll5中文API整理,用法与参考
  7. 通过border来实现各种三角符号
  8. 老子《道德经》第三十五章
  9. 重温Observer模式--热水器·改(转载)
  10. 研发阶段模拟接口数据