Unity【入门】小项目坦克大战

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

1、开始场景

1、场景装饰

RotateObj

using UnityEngine;

public class RotateObj : MonoBehaviour
{
    public float rotateSpeed = 15;
    void Update()
    {
        transform.Rotate(Vector3.up, rotateSpeed * Time.deltaTime);
    }
}

2、开始界面

BasePanel

using UnityEngine;

public class BasePanel<T> : MonoBehaviour where T:class
{
    //两个关键的静态成员
    //私有的静态成员变量(声明) 基础Mono不能new
    private static T instance;
    //公共的静态成员属性或方法(获取)
    //public static T Instance
    //{
    //    get
    //    {
    //        return instance;
    //    }
    //}
    public static T Instance => instance;
    //instance赋值,为确保挂载的唯一性,自己定义一个规范
    private void Awake()
    {
        instance = this as T;
    }
    public virtual void ShowMe()
    {
        this.gameObject.SetActive(true);
    }
    public virtual void HideMe()
    {
        this.gameObject.SetActive(false);
    }
}

BeginPanel

using UnityEngine;
using UnityEngine.SceneManagement;
/// <summary>
/// 通过类名快速得到脚本
/// </summary>
public class BeginPanel : BasePanel<BeginPanel>
{
    // 声明公共的成员变量来关联各个控件
    public CustomGUIButton btnBegin;
    public CustomGUIButton btnSetting;
    public CustomGUIButton btnQuit;
    public CustomGUIButton btnRank;
    void Start()
    {
        //锁定鼠标在窗口内
        //Cursor.lockState = CursorLockMode.Confined;
        //监听一次按钮点击过后的内容
        btnBegin.clickEvent += () => 
        {
            SceneManager.LoadScene("GameScene");
        };
        btnSetting.clickEvent += () =>
        {
            SettingPanel.Instance.ShowMe();
            HideMe();
        };
        btnQuit.clickEvent += () =>
        {
            Application.Quit();
        };
        btnRank.clickEvent += () =>
        {
            RankPanel.Instance.ShowMe();
            Instance.HideMe();
        };
    }
}

3、设置界面

GameDataMgr

/// <summary>
/// 游戏数据管理类,是一个单例模式对象
/// </summary>
public class GameDataMgr
{
    private static GameDataMgr instance = new GameDataMgr();
    public static GameDataMgr Instance { get => instance; }
    //设置信息对象
    public MusicData musicData;
    //排行榜数据对象
    public RankList rankData;
    private GameDataMgr()
    {
        //初始化游戏数据
        musicData = PlayerPrefsDataMgr.Instance.LoadData(typeof(MusicData), "Music_Key") as MusicData;
        //第一次进入游戏的默认值
        if (!musicData.notFirst)
        {
            musicData.notFirst = true;
            musicData.isOpenBK = true;
            musicData.isOpenSound = true;
            musicData.bkValue = 1;
            musicData.soundValue = 1;
            PlayerPrefsDataMgr.Instance.SaveData(musicData, "Music_Key");
        }

        //初始化读取排行榜数据
        rankData = PlayerPrefsDataMgr.Instance.LoadData(typeof(RankList),"Rank_key") as RankList;
    }

    //提供一个添加数据到排行榜中的方法
    public void AddRankInfo(string name,int score,float time)
    {
        rankData.list.Add(new RankInfo(name,score,time));
        //排序
        rankData.list.Sort((a, b) => a.time < b.time ? -1 : 1);
        //移除第10条之后的数据
        for (int i = rankData.list.Count-1; i >= 10; i--)
        {
            rankData.list.RemoveAt(i);
        }
        //存储
        PlayerPrefsDataMgr.Instance.SaveData(rankData, "Rank_key");
    }

    public void OpenOrCloseBKMusic(bool isOpen)
    {
        musicData.isOpenBK = isOpen; //改变是否开启状态
        //控制开关
        BKMusic.Instance.ChangeOpen(isOpen);
        PlayerPrefsDataMgr.Instance.SaveData(musicData, "Music_Key"); //存储
    }
    public void OpenOrCloseSound(bool isOpen)
    {
        musicData.isOpenSound = isOpen; //改变
        PlayerPrefsDataMgr.Instance.SaveData(musicData, "Music_Key"); //存储
    }
    public void ChangeBKValue(float value)
    {
        musicData.bkValue = value;
        BKMusic.Instance.ChangeValue(value);
        PlayerPrefsDataMgr.Instance.SaveData(musicData, "Music_Key");
    }
    public void ChangeSoundValue(float value)
    {
        musicData.soundValue = value;
        PlayerPrefsDataMgr.Instance.SaveData(musicData, "Music_Key");
    }
}

SettingPanel

using UnityEngine;
using UnityEngine.SceneManagement;

public class SettingPanel : BasePanel<SettingPanel>
{
    //声明成员变量 关联控件
    public CustomGUISlider sliderMusic;
    public CustomGUISlider sliderSound;

    public CustomGUIToggle togMusic;
    public CustomGUIToggle togSound;

    public CustomGUIButton btnClose;

    void Start()
    {
        //监听对应的事件,处理逻辑
        sliderMusic.changeValue += (value) => GameDataMgr.Instance.ChangeBKValue(value);
        sliderSound.changeValue += (value) => GameDataMgr.Instance.ChangeSoundValue(value);
        togMusic.changeValue += (value) => GameDataMgr.Instance.OpenOrCloseBKMusic(value);
        togSound.changeValue += (value) => GameDataMgr.Instance.OpenOrCloseSound(value);

        btnClose.clickEvent += () =>
        {
            HideMe();
            //判断当前所在场景
            if(SceneManager.GetActiveScene().name == "BeginScene")
                //把隐藏的开始界面重新显示
                BeginPanel.Instance.ShowMe();
        };
        HideMe();
        //this.gameObject.SetActive(false);
    }
    public void UpdatePanelInfo()
    {
        //更新设置信息
        MusicData data = GameDataMgr.Instance.musicData;
        sliderMusic.nowValue = data.bkValue;
        sliderSound.nowValue = data.soundValue;
        togMusic.isSel = data.isOpenBK;
        togSound.isSel = data.isOpenSound;
    }
    public override void ShowMe()
    {
        base.ShowMe();
        UpdatePanelInfo(); //更新设置信息
    }
    public override void HideMe()
    {
        base.HideMe();
        Time.timeScale = 1;
    }
}

4、音效数据逻辑

MusicData

/// <summary>
/// 音效数据类,用于存储音乐设置相关的信息
/// </summary>
public class MusicData
{
    //背景音乐
    public bool isOpenBK;
    //音效
    public bool isOpenSound;

    public float bkValue;
    public float soundValue;

    public bool notFirst;
}

5、排行榜界面

RankPanel

using System.Collections.Generic;

public class RankPanel : BasePanel<RankPanel>
{
    //关联public的控件对象
    public CustomGUIButton btnClose;

    private List<CustomGUILable> labRank = new List<CustomGUILable>();
    private List<CustomGUILable> labPlayer = new List<CustomGUILable>();
    private List<CustomGUILable> labScore = new List<CustomGUILable>();
    private List<CustomGUILable> labTime = new List<CustomGUILable>();
    void Start()
    {
        for (int i = 1; i <= 10; i++)
        {
            //通过路径/找到子对象的子对象
            //labRank.Add(transform.Find("labRank/labRank" + i).GetComponent<CustomGUILable>());
            labPlayer.Add(transform.Find("labPlayer/labPlayer" + i).GetComponent<CustomGUILable>());
            labScore.Add(transform.Find("labScore/labScore" + i).GetComponent<CustomGUILable>());
            labTime.Add(transform.Find("labTime/labTime" + i).GetComponent<CustomGUILable>());
        }
        //print("排名" + labRank.Count);
        print("玩家" + labPlayer.Count);
        print("分数" + labScore.Count);
        print("通关时间" + labTime.Count);

        //处理事件监听逻辑
        btnClose.clickEvent += () =>
        {
            HideMe();
            BeginPanel.Instance.ShowMe();
        };
        //GameDataMgr.Instance.AddRankInfo("测试", 100, 7232);
        HideMe();
    }
    public override void ShowMe()
    {
        base.ShowMe();
        UpdatePanelInfo();
    }
    public void UpdatePanelInfo()
    {
        //处理根据排行榜数据更新面板
        //获取GameDataMgr中的排行榜列表,用于更新
        List<RankInfo> list = GameDataMgr.Instance.rankData.list;
        //根据列表更新面板数据
        for (int i = 0; i < list.Count; i++)
        {
            labPlayer[i].content.text = list[i].name;
            labScore[i].content.text = list[i].score.ToString();

            int time = (int)list[i].time;
            labTime[i].content.text = "";

            if (time / 3600 > 0)
            {
                labTime[i].content.text += time / 3600 + "时";
            }
            if (time % 3600 / 60 > 0 || labTime[i].content.text != "")
            {
                labTime[i].content.text += time % 3600 / 60 + "分";
            }
            labTime[i].content.text += time % 60 + "秒";
        }
    }
}

6、排行榜数据逻辑

RankInfo

using System.Collections.Generic;

/// <summary>
/// 排行榜单条数据
/// </summary>
public class RankInfo
{
    public string name;
    public int score;
    public float time;
    public RankInfo() { }
    public RankInfo(string name, int score, float time)
    {
        this.name = name;
        this.score = score;
        this.time = time;
    }
}
/// <summary>
/// 排行榜列表
/// </summary>
public class RankList
{
    public List<RankInfo> list;
}

7、背景音乐

BKMusic

using UnityEngine;

public class BKMusic : MonoBehaviour
{
    private static BKMusic instance;
    public static BKMusic Instance => instance;
    public AudioSource audioSource;
    void Awake()
    {
        //初始化 赋值
        instance = this;
        //得到自己依附的游戏对象上挂载的音频源脚本
        audioSource = GetComponent<AudioSource>();
        //初始化已经设置好的信息
        ChangeValue(GameDataMgr.Instance.musicData.bkValue);
        ChangeOpen(GameDataMgr.Instance.musicData.isOpenBK);
    }
    /// <summary>
    /// 改变背景音乐大小
    /// </summary>
    /// <param name="value"></param>
    public void ChangeValue(float value)
    {
        audioSource.volume = value;
    }
    /// <summary>
    /// 开启背景音乐
    /// </summary>
    /// <param name="isOpen"></param>
    public void ChangeOpen(bool isOpen)
    {
        //关闭 mute(静音)
        audioSource.mute = !isOpen;
    }
}

2、游戏场景

1、游戏界面

GamePanel

using UnityEngine;

public class GamePanel : BasePanel<GamePanel>
{
    //获取控件
    public CustomGUILable labScore;
    public CustomGUILable labTime;
    public CustomGUIButton btnQuit;
    public CustomGUIButton btnSetting;
    public CustomGUITexture texHP;
    public float hpW = 300;
    [HideInInspector]
    public int nowScore = 0; //分数记录
    [HideInInspector]
    public float nowTime = 0;
    private int time;

    void Start()
    {
        //锁定鼠标在窗口内
        Cursor.lockState = CursorLockMode.Confined;
        //监听界面上的一些控件操作
        btnQuit.clickEvent += () =>
        {
            QuitPanel.Instance.ShowMe();
            Time.timeScale = 0;
        };
        btnSetting.clickEvent += () =>
        {
            SettingPanel.Instance.ShowMe();
            Time.timeScale = 0;
        };

        //AddScore(100);
        //UpdataHP(300, 30);
    }

    void Update()
    {
        nowTime += Time.deltaTime;

        time = (int)nowTime;
        labTime.content.text = "";

        if (time / 3600 > 0)
        {
            labTime.content.text += time / 3600 + "时";
        }
        if (time % 3600 / 60 > 0 || labTime.content.text != "")
        {
            labTime.content.text += time % 3600 / 60 + "分";
        }
        labTime.content.text += time % 60 + "秒";
    }
    /// <summary>
    /// 更新得分的方法
    /// </summary>
    /// <param name="score"></param>
    public void AddScore(int score)
    {
        nowScore = score;
        //更新界面
        labScore.content.text = score.ToString();
    }
    /// <summary>
    /// 更新血条的方法
    /// </summary>
    /// <param name="maxHP"></param>
    /// <param name="HP"></param>
    public void UpdataHP(int maxHP,int HP)
    {
        texHP.guiPos.width = (float)HP/maxHP * hpW;
    }
}

2、基础场景搭建

CubeObj

using UnityEngine;

public class CubeObj : MonoBehaviour
{
    //奖励预设体关联
    public GameObject[] rewardObjects;
    //死亡特效关联
    public GameObject deadEff;
    private void OnTriggerEnter(Collider other)
    {
        //50%几率创建奖励
        int rangeInt = Random.Range(0, 100);
        if(rangeInt < 70)
        {
            //根据箱子位置随机创建一个奖励预设体
            rangeInt = Random.Range(0,rewardObjects.Length);
            Instantiate(rewardObjects[rangeInt],transform.position,transform.rotation);
        }
        //创建特效预设体
        GameObject effObj = Instantiate(deadEff, transform.position, transform.rotation);
        //控制音效
        AudioSource audioS = effObj.GetComponent<AudioSource>();
        audioS.volume = GameDataMgr.Instance.musicData.soundValue;
        audioS.mute = !GameDataMgr.Instance.musicData.isOpenSound;
        Destroy(gameObject);
    }
}

QuitPanel

using UnityEngine;
using UnityEngine.SceneManagement;

public class QuitPanel : BasePanel<QuitPanel>
{
    public CustomGUIButton btnQuit;
    public CustomGUIButton btnGoOn;
    public CustomGUIButton btnClose;
    void Start()
    {
        HideMe();

        btnQuit.clickEvent += () =>
        {
            SceneManager.LoadScene("BeginScene");
        };
        btnGoOn.clickEvent += () =>
        {
            HideMe();
        };
        btnClose.clickEvent += () =>
        {
            HideMe();
        };
    }
    public override void HideMe()
    {
        base.HideMe();
        Time.timeScale = 1.0f;
    }
}

奖励 PropReward

using UnityEngine;
public enum E_PropType
{
    Atk, Def, MaxHp, Hp,
}
public class PropReward : MonoBehaviour
{
    public E_PropType type = E_PropType.Atk;
    public int changeVaule = 2;
    public GameObject getEff;
    private void OnTriggerEnter(Collider other)
    {
        //玩家才能获取属性奖励
        if (other.CompareTag("Player"))
        {
            //得到玩家脚本
            PlayerObj player = other.GetComponent<PlayerObj>();
            switch (type)
            {
                case E_PropType.Atk:
                    player.atk += changeVaule;
                    break;
                case E_PropType.Def:
                    player.def += changeVaule;
                    break;
                case E_PropType.MaxHp:
                    player.maxHp += changeVaule;
                    GamePanel.Instance.UpdataHP(player.maxHp, player.hp);
                    break;
                case E_PropType.Hp:
                    player.hp += changeVaule;
                    if (player.hp > player.maxHp)
                        player.hp = player.maxHp;
                    GamePanel.Instance.UpdataHP(player.maxHp, player.hp);
                    break;
            }
            //创建特效
            //获得武器的特效
            GameObject eff = Instantiate(getEff, transform.position, transform.rotation);
            AudioSource audioS = eff.GetComponent<AudioSource>();
            audioS.volume = GameDataMgr.Instance.musicData.soundValue;
            audioS.mute = !GameDataMgr.Instance.musicData.isOpenSound;
            Destroy(gameObject);
        }
    }
}

武器奖励 WeaponReward

using UnityEngine;

public class WeaponReward : MonoBehaviour
{
    //随机武器
    public GameObject[] weaponObj;
    //武器特效
    public GameObject getEff;
    
    private void OnTriggerEnter(Collider other)
    {
        if (other.CompareTag("Player"))
        {
            //获取武器
            int index = Random.Range(0, weaponObj.Length);
            //得到PlayerObj脚本
            PlayerObj player = other.GetComponent<PlayerObj>();
            //切换武器
            player.ChangeWeapon(weaponObj[index]);

            //获得武器的特效
            GameObject eff = Instantiate(getEff, transform.position, transform.rotation);
            AudioSource audioS = eff.GetComponent<AudioSource>();
            audioS.volume = GameDataMgr.Instance.musicData.soundValue;
            audioS.mute = !GameDataMgr.Instance.musicData.isOpenSound;

            Destroy(gameObject);
        }
    }
}

3、坦克基类

TankBaseObj

using UnityEngine;

public abstract class TankBaseObj : MonoBehaviour
{
    public int atk;
    public int def;
    public int maxHp;
    public int hp;

    public Transform tankHead;

    public float moveSpeed = 10;
    public float roundSpeed = 100;
    public float headRoundSpeed = 100;

    //死亡特效
    public GameObject deadEff;

    public abstract void Fire();
    public virtual void Wound(TankBaseObj other)
    {
        //伤害计算
        int dmg = other.atk - this.def;
        if (dmg <= 0)
            return;
        this.hp -= dmg;
        if (this.hp <= 0)
        {
            hp = 0;
            this.Dead();
        }
            
    }
    public virtual void Dead()
    {
        Destroy(gameObject);
        if (deadEff != null)
        {
            //实例化对象(特效)的位置和角度
            GameObject effObj = Instantiate(deadEff, transform.position, transform.rotation);
            //获取该对象的音频
            AudioSource audioSource = effObj.GetComponent<AudioSource>();
            audioSource.volume = GameDataMgr.Instance.musicData.soundValue;
            audioSource.mute = !GameDataMgr.Instance.musicData.isOpenSound;
            audioSource.Play();
        }
    }
}

特效销毁 AutoDestroy

using UnityEngine;

public class AutoDestroy : MonoBehaviour
{
    public float time = 2;
    void Start()
    {
        Destroy(gameObject, time);
    }
}

子弹 BulletObj

using UnityEngine;

public class BulletObj : MonoBehaviour
{
    //移动速度
    public float moveSpeed = 50;
    //子弹所有者
    public TankBaseObj fatherObj;
    //特效对象
    public GameObject effObj;

    void Update()
    {
        transform.Translate(Vector3.forward * moveSpeed * Time.deltaTime);
    }

    private void OnTriggerEnter(Collider other)
    {
        //子弹打到Cube
        if (other.CompareTag("Cube") ||
            //Monster发出的子弹打到玩家
            other.CompareTag("Player") && fatherObj.CompareTag("Monster") ||
            //Player发出的子弹打到Monster
            other.CompareTag("Monster") && fatherObj.CompareTag("Player"))
        {
            //伤害判断
            //通过里氏判断让父类获取脚本
            TankBaseObj obj = other.GetComponent<TankBaseObj>();
            if (obj != null)
                obj.Wound(fatherObj);

            //子弹爆炸特效
            if (effObj != null)
            {
                //创建爆炸特效
                GameObject eff = Instantiate(effObj, transform.position, transform.rotation);
                //修改音效的音量
                //获取音效对象
                AudioSource audioSource = eff.GetComponent<AudioSource>();
                audioSource.volume = GameDataMgr.Instance.musicData.soundValue;
                audioSource.mute = !GameDataMgr.Instance.musicData.isOpenSound;
                Destroy(gameObject);
            }
        }
    }
    //设置子弹所有者
    public void SetFather(TankBaseObj obj)
    {
        fatherObj = obj;
    }
}

武器 WeaponObj

using UnityEngine;

public class WeaponObj : MonoBehaviour
{
    //实例化子弹对象
    public GameObject bullet;
    //发射位置
    public Transform[] shootPos;
    //武器的拥有者
    public TankBaseObj fatherObj;
    
    //设置子弹所有者
    public void SetFather(TankBaseObj obj)
    {
        fatherObj = obj;
    }
    public void Fire()
    {
        //根据位置创建子弹
        for (int i = 0; i < shootPos.Length; i++)
        {
            //创建子弹
            GameObject obj = Instantiate(bullet, shootPos[i].position, shootPos[i].rotation); ;
            //获取子弹所有者
            BulletObj bulletObj = obj.GetComponent<BulletObj>();
            bulletObj.SetFather(fatherObj);

            //补 刚体里的Constraints为轴向约束
        }
    }
}

4、主玩家相关

PlayerObj

using UnityEngine;

public class PlayerObj : TankBaseObj
{
    //当前装备的武器
    public WeaponObj nowWeapon;
    //武器安装位置
    public Transform weaponPos;

    void Update()
    {
        //控制前进后退 1.Transform 位移 2.Input 轴向输入检测
        transform.Translate(Input.GetAxis("Vertical") * Vector3.forward * moveSpeed * Time.deltaTime);
        //控制旋转 1.Transform 旋转 2.Input 轴向输入检测
        transform.Rotate(Input.GetAxis("Horizontal") * Vector3.up * roundSpeed * Time.deltaTime);
        //鼠标左右移动 控制炮台旋转
        tankHead.transform.Rotate(Input.GetAxis("Mouse X") * Vector3.up * headRoundSpeed * Time.deltaTime);
        //开火
        if (Input.GetMouseButtonDown(0))
        {
            Fire();
        }
    }
    public override void Fire()
    {
        if (nowWeapon != null)
            nowWeapon.Fire();
    }
    public override void Dead()
    {
        //base.Dead();
        Time.timeScale = 0;
        LostPanel.Instance.ShowMe();
    }
    public override void Wound(TankBaseObj other)
    {
        base.Wound(other);
        //更新血条
        GamePanel.Instance.UpdataHP(maxHp, hp);
    }
    /// <summary>
    /// 切换武器
    /// </summary>
    /// <param name="obj">Weapon</param>
    public void ChangeWeapon(GameObject weapon)
    {
        if(nowWeapon != null)
        {
            Destroy(nowWeapon.gameObject);
            nowWeapon = null;
        }
        //实例化随机到的武器       将weaponPos设置为weapon的父对象,false保持缩放大小
        GameObject weaponObj = Instantiate(weapon, weaponPos, false);
        //挂载武器脚本
        nowWeapon = weaponObj.GetComponent<WeaponObj>();
        //设置武器拥有者为Player
        nowWeapon.SetFather(this);
    }
}

摄像机跟随 CameraMove

using UnityEngine;

public class CameraMove : MonoBehaviour
{
    //摄像机目标位置
    public Transform targetPlayer;
    public float H = 17;

    private Vector3 pos;

    void LateUpdate()
    {
        if (targetPlayer == null)
            return;
        //x/z和玩家一样
        pos.x = targetPlayer.position.x;
        pos.z = targetPlayer.position.z;
        //通过外部调整摄像机高度
        pos.y = H;
        transform.position = pos;
    }
}

5、敌人相关

MonsterObj

using UnityEngine;

public class MonsterObj : TankBaseObj
{
    #region 变量
    //当前目标点
    private Transform targetPos;
    //随机用的点,外面关联
    public Transform[] randomPos;
    //敌方坦克盯着的目标
    public Transform lookAtTarget;
    //靠近一定范围自动开火
    public float fireDis = 5;
    //间隔时间
    public float fireOffsetTime = 2;
    private float nowTime = 0;

    //开火位置
    public Transform[] shootPos;
    //子弹预设体位置
    public GameObject bulletObj;
    //血条显示时间
    private float showTime;

    public Texture maxHpBK;
    public Texture hpBK;

    private Rect maxHpRect;
    private Rect hpRect;
    #endregion



    void Start()
    {
        RandomPos();

    }

    void Update()
    {
        //看向自己的目标点
        transform.LookAt(targetPos);
        //不停的往自己的面朝向移动
        transform.Translate(Vector3.forward * moveSpeed * Time.deltaTime);
        //判断距离
        if (Vector3.Distance(transform.position, targetPos.position) < 0.1f)
        {
            RandomPos();
        }

        if (lookAtTarget != null)
        {
            tankHead.LookAt(lookAtTarget);
            if (Vector3.Distance(transform.position, lookAtTarget.position) <= fireDis)
            {
                nowTime += Time.deltaTime;
                if (nowTime >= fireOffsetTime)
                {
                    Fire();
                    nowTime = 0;
                }
            }
        }
    }
    private void RandomPos()
    {
        if (randomPos == null)
            return;
        targetPos = randomPos[Random.Range(0, randomPos.Length)];
    }
    public override void Fire()
    {
        for (int i = 0; i < shootPos.Length; i++)
        {
            GameObject obj = Instantiate(bulletObj, shootPos[i].position, shootPos[i].rotation);
            BulletObj bullet = obj.GetComponent<BulletObj>();
            bullet.SetFather(this);
        }
    }
    public override void Dead()
    {
        base.Dead();
        GamePanel.Instance.AddScore(10);
    }
    //血条UI
    private void OnGUI()
    {
        if (showTime > 0)
        {
            showTime -= Time.deltaTime;
            //血条位置:先把世界位置转换成屏幕位置,再转换成GUI位置
            Vector3 screenPos = Camera.main.WorldToScreenPoint(transform.position);
            //screenPos.y -= Screen.height;
            //screenPos.y =screenPos.y - Screen.height;

            screenPos.y = Screen.height - screenPos.y;
            //绘制GUI
            maxHpRect.x = screenPos.x - 50;
            maxHpRect.y = screenPos.y - 70;

            maxHpRect.width = 100;
            maxHpRect.height = 15;
            GUI.DrawTexture(maxHpRect, maxHpBK);

            hpRect.x = screenPos.x - 50;
            hpRect.y = screenPos.y - 70;

            hpRect.width = (float)hp / maxHp * 100f;
            hpRect.height = 15;
            GUI.DrawTexture(hpRect, hpBK);
        }
    }
    public override void Wound(TankBaseObj other)
    {
        base.Wound(other);
        showTime = 2;
    }
}

MonsterTower

using UnityEngine;

public class MonsterTower : TankBaseObj
{
    //间隔开火
    //开火间隔时间
    public float fireOffsetTime = 1;
    private float nowtTime = 0;
    //子弹发射位置
    public Transform[] shootPos;
    //关联子弹预设体
    public GameObject bulletObj;

    void Update()
    {
        nowtTime += Time.deltaTime;
        if (nowtTime >= fireOffsetTime)
        {
            Fire();
            nowtTime = 0;
        }
    }
    public override void Fire()
    {
        for (int i = 0; i < shootPos.Length; i++)
        {
            //根据发射位置个数实例化子弹
            GameObject obj = Instantiate(bulletObj, shootPos[i].position, shootPos[i].rotation);
            //获取子弹脚本
            BulletObj bullet = obj.GetComponent<BulletObj>();
            //获取子弹所有者
            bullet.SetFather(this);
        }
    }
    public override void Wound(TankBaseObj other)
    {
        //base.Wound(other); 不用父类的Wound伤害计算方法
    }
}

6、通关点

EndPoint

using UnityEngine;

public class EndPoint : MonoBehaviour
{
    private void OnTriggerEnter(Collider other)
    {
        if (other.CompareTag("Player"))
        {
            //暂停游戏
            Time.timeScale = 0;
            //通过逻辑
            WinPanel.Instance.ShowMe();
        }
    }
}

3、结束界面

1、游戏胜利界面

WinPanel

using UnityEngine;
using UnityEngine.SceneManagement;

public class WinPanel : BasePanel<WinPanel>
{
    public CustomGUIInput inputInfo;
    public CustomGUIButton btnSure;

    void Start()
    {
        //取消游戏暂停
        Time.timeScale = 1;
        //监听将数据记录到排行榜中
        btnSure.clickEvent += () =>
        {
            GameDataMgr.Instance.AddRankInfo(inputInfo.content.text, 
                GamePanel.Instance.nowScore, 
                GamePanel.Instance.nowTime);
            //返回开始界面
            SceneManager.LoadScene("BeginScene");
        };
        HideMe();
    }
}

2、游戏失败界面

LosePanel

using UnityEngine;
using UnityEngine.SceneManagement;

public class LostPanel : BasePanel<LostPanel>
{
    public CustomGUIButton btnBack;
    public CustomGUIButton btnGoOn;
    void Start()
    {
        btnBack.clickEvent += () =>
        {
            Time.timeScale = 1;
            SceneManager.LoadScene("BeginScene");

        };
        btnGoOn.clickEvent += () =>
        {
            Time.timeScale = 1;
            SceneManager.LoadScene("GameScene");
        };
        HideMe();
    }
}

3、游戏打包

  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值