上一教程中咱們完成了場景設置和坦克設置,今天接着上一教程繼續
傳送門:unity官方教程-TANKS(一)react
在咱們設置好了坦克預置後,接下來就是相機設置了編程
一、在Hierarchy面板中建立一個空物體,重命名爲CameraRig,選中該物體後在Inspector面板重置它的位置屬性,點擊圖中位置,而後將Rotation屬性設置爲(40,60,0)segmentfault
二、在Hierarchy面板中將Main Camera拖動到CameraRig上使其成爲CameraRig的子物體,設置Main Camera的Position屬性爲(0,0,-65),Rotation屬性爲(0,0,0)
三、爲了使相機跟隨坦克移動,須要編程實現(代碼爲Scripts/Camera/CameraControll.cs),由於是兩臺坦克對戰,相機須要照顧到兩臺坦克,即找到兩臺坦克的中間位置,將相機移動到那個位置app
private void FindAveragePosition() { Vector3 averagePos = new Vector3(); int numTargets = 0; //找到兩臺坦克的位置 for (int i = 0; i < m_Targets.Length; i++) { // 坦克 if (!m_Targets[i].gameObject.activeSelf) continue; // 兩臺坦克位置相加 averagePos += m_Targets[i].position; numTargets++; } //求坦克平均位置 if (numTargets > 0) averagePos /= numTargets; // 保持y軸位置不變 averagePos.y = transform.position.y; m_DesiredPosition = averagePos; }
四、在兩臺坦克距離變遠或變近時,只移動相機位置是不夠的,同時須要將相機拉近或拉遠以防止坦克跑出鏡頭,這一步是經過調整相機的Size屬性實現ide
private float FindRequiredSize() { // 世界座標系轉爲相機座標系 Vector3 desiredLocalPos = transform.InverseTransformPoint(m_DesiredPosition); float size = 0f; //找到兩臺坦克中較遠的那個,爲了使它能進入相機鏡頭 for (int i = 0; i < m_Targets.Length; i++) { if (!m_Targets[i].gameObject.activeSelf) continue; // 將坦克位置從世界座標系轉爲相機座標系 Vector3 targetLocalPos = transform.InverseTransformPoint(m_Targets[i].position); //計算坦克與相機的位置差 Vector3 desiredPosToTarget = targetLocalPos - desiredLocalPos; // 根據位置差找出合適的Size size = Mathf.Max(size, Mathf.Abs(desiredPosToTarget.y)); size = Mathf.Max(size, Mathf.Abs(desiredPosToTarget.x) / m_Camera.aspect); } // 添加適當的距離,不然坦克將出如今屏幕邊緣 size += m_ScreenEdgeBuffer; size = Mathf.Max(size, m_MinSize); return size; }
效果如圖,綠色表明坦克的生命值,該效果是經過UI實現的,跟着步驟走就能夠實現出效果,但對於每一步驟爲何這麼作則須要本身實驗看看了ui
一、在Hierarchy中建立一個UI->Slider,選擇EventSystem,將Standalone Input Module的Horizontal Axis屬性改成HorizontalUI,Vertical Axis屬性改成VerticalUI
二、選擇Canvas,將Canvas Scaler組件的Reference Pixels per Unit改成1,將Canvas組件的Render Mode改成World Space
三、將Canvas物體拖拽到Tank上,選擇Canvas,修改其Position屬性爲(0,0.1,0),Width屬性爲3.5,Height屬性爲3.5,Rotation屬性爲(90,0,0),保存場景
四、展開Canvas的全部子物體,刪掉HandleSlideArea,將其它子物體所有選中,點擊圖示位置,按住Alt鍵,同時點擊右下角的選項this
五、選擇Slider物體,取消Interactable,修改Transition爲none,調整Max Value和Value爲100,重命名Slider爲HealthSlider
六、選中Background,將Image組件的Image Source屬性修改成Health Wheel,修改Color屬性的Alpha值爲80
七、選中Fill物體,將Image組件的Image Source屬性修改成Health Wheel,修改Color屬性的Alpha值爲150,Image Type屬性爲Filled,Fill Origin屬性爲Left,取消Clockwise
八、在Scripts/UI文件夾找到UIDireactionControl.cs腳本,拖拽到HealthSlider物體上
九、選中Tank物體,點擊Inspector面板的Apply,將修改運用到預置spa
一、找到Prefabs文件夾下的TankExplosion,拖拽到Hierarchy中,給其添加一個AudioSource組件,AudioClip屬性選擇爲TankExplosion,取消Play On Awake
二、選中TankExplosion,點擊Inspector面板中的Apply更新預置
三、從Hierarchy中刪除TankExplosion3d
一、找到Scripts/Tank/TankHealth.cs腳本,替換爲如下內容code
using UnityEngine; using UnityEngine.UI; public class TankHealth : MonoBehaviour { public float m_StartingHealth = 100f; // The amount of health each tank starts with. public Slider m_Slider; // The slider to represent how much health the tank currently has. public Image m_FillImage; // The image component of the slider. public Color m_FullHealthColor = Color.green; // The color the health bar will be when on full health. public Color m_ZeroHealthColor = Color.red; // The color the health bar will be when on no health. public GameObject m_ExplosionPrefab; // A prefab that will be instantiated in Awake, then used whenever the tank dies. private AudioSource m_ExplosionAudio; // The audio source to play when the tank explodes. private ParticleSystem m_ExplosionParticles; // The particle system the will play when the tank is destroyed. private float m_CurrentHealth; // How much health the tank currently has. private bool m_Dead; // Has the tank been reduced beyond zero health yet? private void Awake() { // Instantiate the explosion prefab and get a reference to the particle system on it. m_ExplosionParticles = Instantiate(m_ExplosionPrefab).GetComponent<ParticleSystem>(); // Get a reference to the audio source on the instantiated prefab. m_ExplosionAudio = m_ExplosionParticles.GetComponent<AudioSource>(); // Disable the prefab so it can be activated when it's required. m_ExplosionParticles.gameObject.SetActive(false); } private void OnEnable() { // When the tank is enabled, reset the tank's health and whether or not it's dead. m_CurrentHealth = m_StartingHealth; m_Dead = false; // Update the health slider's value and color. SetHealthUI(); } public void TakeDamage(float amount) { // Reduce current health by the amount of damage done. m_CurrentHealth -= amount; // Change the UI elements appropriately. SetHealthUI(); // If the current health is at or below zero and it has not yet been registered, call OnDeath. if (m_CurrentHealth <= 0f && !m_Dead) { OnDeath(); } } private void SetHealthUI() { // Set the slider's value appropriately. m_Slider.value = m_CurrentHealth; // Interpolate the color of the bar between the choosen colours based on the current percentage of the starting health. m_FillImage.color = Color.Lerp(m_ZeroHealthColor, m_FullHealthColor, m_CurrentHealth / m_StartingHealth); } private void OnDeath() { // Set the flag so that this function is only called once. m_Dead = true; // Move the instantiated explosion prefab to the tank's position and turn it on. m_ExplosionParticles.transform.position = transform.position; m_ExplosionParticles.gameObject.SetActive(true); // Play the particle system of the tank exploding. m_ExplosionParticles.Play(); // Play the tank explosion sound effect. m_ExplosionAudio.Play(); // Turn the tank off. gameObject.SetActive(false); } }
二、將腳本拖拽到Tank物體上,而後拖拽HealthSlider到TankHealth的Slider屬性,Fill物體到FillImage屬性,TankExplosion到ExplosionPrefab屬性
三、選中Tank物體,點擊Inspector面板的Apply,將修改應用到預置,保存場景
以上就是今天的主要內容了,下期教程繼續。。。