unity官方教程TANKS,難度係數中階。
跟着官方教程學習Unity,經過本教程你能夠學會使用Unity開發遊戲的基本流程。編程
Unity 版本 > 5.2
Asset Store 裏面搜索 Tanks!Tutorial ,下載導入windows
爲了便於開發,不少時候咱們選用的窗口布局是 2by3 Layout,而後將 Project 面板拖動到 Hierarchy 面板下面,以下圖所示dom
項目設置完畢後,就進入場景設置環節ide
一、新建一個場景,命名爲 Main
二、刪除場景中的 Directional Light
三、找到 Prefabs 文件夾下的 LevelArt,將其拖入 Hierarchy 內,這個 prefab 是咱們的遊戲地形
四、打開菜單 Windows->Lighting->Settings,取消 Auto Generate 和 Baked GI,將 Environment Lighting Source 改成 Color,並將顏色設置爲(72,62,113),點擊 Generate Lighting,這一步主要是渲染設置
五、調整 Main Camera 位置爲 (-43,42,-25),旋轉屬性爲 (40,60,0),投影改成正交 Orthographic,Clear Flags 改成 Solid Color ,Background 顏色設置爲(80,60,50),Clear Flags不設置也能夠,這個設置主要影響的是相機移動到看不到場景內的物體時屏幕顯示的天空盒仍是本身設置的 Solid Color 顏色oop
如今要往場景里加坦克了佈局
一、在 Models 文件夾裏面找到 Tank,將其拖拽到 Hierarchy 中
二、選中 Tank,在Inspector面板將 Layer 設置爲 Players,跳出對話框時選 No,this object only
三、給 Tank 添加一個 Rigidbody Component,展開 Constraints 選項,勾選 Freeze Position Y 和 Freeze Rotation X Z,由於地面位於 XZ 平面,因此限定坦克不能在 Y 方向移動而且只能沿 Y 軸轉動
四、給 Tank 添加一個 Box Collider Component,將其中心 Center 調整爲(0,0.85,0),尺寸 Size 調整爲(1.5,1.7,1.6)
五、給 Tank 添加兩個 Audio Source Component,將第一個 Audio Source 的 AudioClip 屬性填充爲 Engine Idle(坦克不動時的音頻),並勾選 Loop,將第二個 Audio Source 的 Play On Awake 取消
六、選中 Project 面板的 Prefabs 文件夾,將 Tank 拖入到該文件夾,至此咱們就建立好了坦克 Prefab
七、將 Prefabs 文件夾中的 DustTrail 拖到 Hierarchy 面板中的 Tank 物體上,使其成爲 Tank 的子物體,並Crtl + D(windows)複製一個,而後重命名爲 LeftDustTrail 和 RightDustTrail,這是特效 - 坦克運動過程地面揚起的土
八、調整 LeftDustTrail 的 position 爲(-0.5,0,-0.75),RightDustTrail 的position 爲(0.5,0,-0.75)學習
以上過程便製做好了遊戲主角 Tank,下面就要編程控制它運動了this
一、找到 ScriptsTank 文件夾下的 TankMovement.cs,將其拖入到 Tank 物體上,打開 TankMovement.csspa
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>().MovePositioncode
因爲咱們的坦克是剛體,且移動被限制在了 XZ 平面,此時最好的方式是採用 MovePosition
獲取用戶輸入
private void Start() { //在菜單Edit->Project Settings->Input設置,默認玩家1左右移動按鍵是 a 和 d,先後按鍵是 w 和 s m_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); } }
二、在將 TankMovement.cs 拖入到 Tank 上時,選擇 Tank 的第一個 Audio Source Component 拖入到TankMovement 的 Movement Audio上,並選擇 Engine Idling 爲 EngineIdle 音頻,Engine Drving 爲 EngineDrving 音頻,至此點擊 Apply,將咱們後面對 Tank 的修改保存到 Tank prefab 中
三、保存場景,點擊 Play 試玩一下
經過今天的教程,你能夠學會
下期教程繼續。。。