上一教程中我们完成了场景设置和坦克设置,今天接着上一教程继续
传送门:unity官方教程-TANKS(一)

在我们设置好了坦克预置后,接下来就是相机设置了

一、相机配置

1、在Hierarchy面板中创建一个空物体,重命名为CameraRig,选中该物体后在Inspector面板重置它的位置属性,点击图中位置,然后将Rotation属性设置为(40,60,0)

clipboard.png

2、在Hierarchy面板中将Main Camera拖动到CameraRig上使其成为CameraRig的子物体,设置Main Camera的Position属性为(0,0,-65),Rotation属性为(0,0,0)
3、为了使相机跟随坦克移动,需要编程实现(代码为Scripts/Camera/CameraControll.cs),因为是两台坦克对战,相机需要照顾到两台坦克,即找到两台坦克的中间位置,将相机移动到那个位置

clipboard.png

    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;
    }

4、在两台坦克距离变远或变近时,只移动相机位置是不够的,同时需要将相机拉近或拉远以防止坦克跑出镜头,这一步是通过调整相机的Size属性实现

    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;
    }

二、坦克生命值

clipboard.png

效果如图,绿色代表坦克的生命值,该效果是通过UI实现的,跟着步骤走就可以实现出效果,但对于每一步骤为什么这么做则需要自己实验看看了

1、在Hierarchy中创建一个UI->Slider,选择EventSystem,将Standalone Input Module的Horizontal Axis属性改为HorizontalUI,Vertical Axis属性改为VerticalUI
2、选择Canvas,将Canvas Scaler组件的Reference Pixels per Unit改为1,将Canvas组件的Render Mode改为World Space
3、将Canvas物体拖拽到Tank上,选择Canvas,修改其Position属性为(0,0.1,0),Width属性为3.5,Height属性为3.5,Rotation属性为(90,0,0),保存场景
4、展开Canvas的所有子物体,删掉HandleSlideArea,将其它子物体全部选中,点击图示位置,按住Alt键,同时点击右下角的选项

clipboard.png

5、选择Slider物体,取消Interactable,修改Transition为none,调整Max Value和Value为100,重命名Slider为HealthSlider
6、选中Background,将Image组件的Image Source属性修改为Health Wheel,修改Color属性的Alpha值为80
7、选中Fill物体,将Image组件的Image Source属性修改为Health Wheel,修改Color属性的Alpha值为150,Image Type属性为Filled,Fill Origin属性为Left,取消Clockwise
8、在Scripts/UI文件夹找到UIDireactionControl.cs脚本,拖拽到HealthSlider物体上
9、选中Tank物体,点击Inspector面板的Apply,将修改运用到预置

三、爆炸特效

1、找到Prefabs文件夹下的TankExplosion,拖拽到Hierarchy中,给其添加一个AudioSource组件,AudioClip属性选择为TankExplosion,取消Play On Awake
2、选中TankExplosion,点击Inspector面板中的Apply更新预置
3、从Hierarchy中删除TankExplosion

四、坦克生命值脚本控制

1、找到Scripts/Tank/TankHealth.cs脚本,替换为以下内容

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);
    }
}

2、将脚本拖拽到Tank物体上,然后拖拽HealthSlider到TankHealth的Slider属性,Fill物体到FillImage属性,TankExplosion到ExplosionPrefab属性
3、选中Tank物体,点击Inspector面板的Apply,将修改应用到预置,保存场景

以上就是今天的主要内容了,下期教程继续。。。


爱种地的码农
28 声望8 粉丝