【Unity3D游戏魔坦之争】游戏结束流程封装实现【七】

news2024/12/27 11:29:23

在这里插入图片描述


👨‍💻个人主页:@元宇宙-秩沅

👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅!

👨‍💻 本文由 秩沅 原创

👨‍💻 收录于专栏unityUI专题篇
在这里插入图片描述



文章目录

    • 🎶前言
    • 🎶(==A==)关键逻辑梳理
    • 🎶(==B==)需求分析
    • 🎶(==C==)行为实现——血条
    • 🎶(==D==)场景搭建——敌方阵营
    • 🎶(==E==)场景搭建——通关面板
    • 🎶(==F==)行为实现——通关点触发
    • 🎶(==G==)场景搭建——结束面板


🎶前言

在这里插入图片描述


🅰️


🎶(A关键逻辑梳理


在这里插入图片描述


🎶(B需求分析


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


🎶(C行为实现——血条


在这里插入图片描述


😶‍🌫️:步骤实现

  • 1.坐标三个转化
  • 2.GUI的原点和屏幕的原点
  • 3.结构体的特点回顾——涉及Rect_结构体类型
  • 4.血条的显隐
  • 5.倒计时的两个方法
  • 6.近大远小血条的缩放——待

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

血条核心代码

 //GUI生命函数
    private void OnGUI()
    {
        if(showTime >=0) //血条倒计时展示
        {
            //简单的倒计时
            showTime -= Time.deltaTime;
            //世界坐标转屏幕坐标
            SreecPosition = Camera.main.WorldToScreenPoint(transform.position);

            //屏幕坐标转GUI坐标_____GUI的原点在左上角,屏幕坐标原点在左下角
            SreecPosition.y = Screen.height - SreecPosition.y;

            //底图Rect位置参数赋值
            GUIPosition1.x = SreecPosition.x - 50;
            GUIPosition1.y = SreecPosition.y - 70;
            GUIPosition1.width = 100;
            GUIPosition1.height = 15;

            //血条图Rect位置参数赋值
            GUIPosition2.x = SreecPosition.x - 50;
            GUIPosition2.y = SreecPosition.y - 70;

            //血条长度和血量同步
            GUIPosition2.width = 100*(nowBlood/maxBlood);
            GUIPosition2.height = 15;

            //绘制底图    
            GUI.DrawTexture(GUIPosition1, underTexture);
           
            //绘制血条       
            GUI.DrawTexture(GUIPosition2, topTexture);

        }
       
    }

更新敌方坦克

______-在这里插入图片描述

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//-------------------------------------
//—————————————————————————————————————
//___________项目:      
//___________功能:敌方坦克逻辑封装
//___________创建者:秩沅_______________
//_____________________________________
//-------------------------------------
public class EnemyTank:TankFather 
{
    //随机移动点的位置数组
    public  Transform[] randomPosition;
    //目标位置
    private Transform target;
    //目标坦克
    public Transform Player;
    //检测范围
    public float distance = 10f;
    //子弹发射参数
    public AudioSource shootMusic;   //发射音效
    public GameObject shootball;     //发射的子弹类型
    public float shootSpeed = 1000f; //子弹的速度 
    public Transform[] shootTransform; //发射的组件信息
    public bool shootSwitch = false;  
    private float endTime = 3f;      //子弹发射间隔的时间
    //血条的参数
    public Texture underTexture;
    public Texture topTexture;
    private Vector3 SreecPosition;
    private Rect GUIPosition1;
    private Rect GUIPosition2;
    public float showTime = 0;

    private void Start()
    {
        //属性初始化赋值
        
        maxBlood = 500;
        nowBlood = 500;
        attack = 30;
        HeadSpeed = 50;
        //射击音效关闭
        shootMusic.enabled = false;
        moveSpeed = 10f;
        //先随机整一个目标点
        RandomPosition();

    }
    private void Update()
    {    
        transform.LookAt(target);

        //始终超自己的正方向移动
        transform.Translate(Vector3.forward * moveSpeed * Time.deltaTime);  //当距离差不多相等时,再随机目标点
        if(Vector3.Distance(transform .position ,target .position)< 0.5f)
        {
            RandomPosition();
        }
            
        //范围检测
        if (Vector3 .Distance(transform .position ,Player.position )<= distance && Player !=null )
        {
            //炮口瞄准玩家
            Head.transform.LookAt(Player);
            //倒计时发射子弹
            endTime = Mathf.MoveTowards(endTime, 0, 0.1f);
            if (endTime <= 0)
            {
                Fire();
                endTime = 3f;
            }        
        }
     
    }

    //随机指向一个移动点
    public void RandomPosition()
    {
        if (randomPosition.Length != 0)

            target = randomPosition[Random.Range(0, randomPosition.Length)];
    }
    //触发检测
    private void OnTriggerEnter(Collider other)
    {
       
        if (other.gameObject.tag == "bullet" )
        {
            //添加子弹挂载的目标坦克,方便获取该子弹的攻击力,与受伤逻辑相结合
            BulletMove ball = other.gameObject.GetComponent<BulletMove>();
            TankFather ballTank = ball.Tank.GetComponent<TankFather>();

            //当子弹不是自己打的到自己身上的时候
            if (ballTank.tag != gameObject.tag)
            {
                //扣血
                Heart(ballTank);
            }

        }
    }

    public override void Fire()
    {
        //开启射击音效
        shootMusic.enabled = true;
        shootMusic.Play();
        for (int i = 0; i < shootTransform.Length ; i++)
        {
            GameObject ball = Instantiate(shootball, shootTransform[i].position, shootTransform[i].rotation);
            BulletMove movScript = ball.GetComponent<BulletMove>();
            Rigidbody shootBall = ball.GetComponent<Rigidbody>();
            shootBall.AddForce(shootTransform[i].transform.forward * shootSpeed);
            movScript.Tank = gameObject;  //声明子弹是由谁打出去的
        }
     
    }
    
    //死亡行为重写
    public override void Death()
    {
        base.Death();
        GamePlane.SingleInstance.AddScore(10);
    }

    //受伤行为重写
    public override void Heart(TankFather other)
    {
        base.Heart(other);
        showTime = 3; //血条倒计时展示
    }

    //GUI生命函数
    private void OnGUI()
    {
        if(showTime >=0) //血条倒计时展示
        {
            //简单的倒计时
            showTime -= Time.deltaTime;
            //世界坐标转屏幕坐标
            SreecPosition = Camera.main.WorldToScreenPoint(transform.position);

            //屏幕坐标转GUI坐标_____GUI的原点在左上角,屏幕坐标原点在左下角
            SreecPosition.y = Screen.height - SreecPosition.y;

            //底图Rect位置参数赋值
            GUIPosition1.x = SreecPosition.x - 50;
            GUIPosition1.y = SreecPosition.y - 70;
            GUIPosition1.width = 100;
            GUIPosition1.height = 15;

            //血条图Rect位置参数赋值
            GUIPosition2.x = SreecPosition.x - 50;
            GUIPosition2.y = SreecPosition.y - 70;

            //血条长度和血量同步
            GUIPosition2.width = 100*(nowBlood/maxBlood);
            GUIPosition2.height = 15;

            //绘制底图    
            GUI.DrawTexture(GUIPosition1, underTexture);
           
            //绘制血条       
            GUI.DrawTexture(GUIPosition2, topTexture);

        }
       
    }
}

更新炮台

在这里插入图片描述

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//-------------------------------------
//—————————————————————————————————————
//___________项目:      
//___________功能:敌方坦克逻辑封装
//___________创建者:秩沅_______________
//_____________________________________
//-------------------------------------
public class EnemyTank:TankFather 
{
    //随机移动点的位置数组
    public  Transform[] randomPosition;
    //目标位置
    private Transform target;
    //目标坦克
    public Transform Player;
    //检测范围
    public float distance = 10f;
    //子弹发射参数
    public AudioSource shootMusic;   //发射音效
    public GameObject shootball;     //发射的子弹类型
    public float shootSpeed = 1000f; //子弹的速度 
    public Transform[] shootTransform; //发射的组件信息
    public bool shootSwitch = false;  
    private float endTime = 3f;      //子弹发射间隔的时间
    //血条的参数
    public Texture underTexture;
    public Texture topTexture;
    private Vector3 SreecPosition;
    private Rect GUIPosition1;
    private Rect GUIPosition2;
    public float showTime = 0;

    private void Start()
    {
        //属性初始化赋值
        
        maxBlood = 500;
        nowBlood = 500;
        attack = 30;
        HeadSpeed = 50;
        //射击音效关闭
        shootMusic.enabled = false;
        moveSpeed = 10f;
        //先随机整一个目标点
        RandomPosition();

    }
    private void Update()
    {    
        transform.LookAt(target);

        //始终超自己的正方向移动
        transform.Translate(Vector3.forward * moveSpeed * Time.deltaTime);  //当距离差不多相等时,再随机目标点
        if(Vector3.Distance(transform .position ,target .position)< 0.5f)
        {
            RandomPosition();
        }
            
        //范围检测
        if (Vector3 .Distance(transform .position ,Player.position )<= distance && Player !=null )
        {
            //炮口瞄准玩家
            Head.transform.LookAt(Player);
            //倒计时发射子弹
            endTime = Mathf.MoveTowards(endTime, 0, 0.1f);
            if (endTime <= 0)
            {
                Fire();
                endTime = 3f;
            }        
        }
     
    }

    //随机指向一个移动点
    public void RandomPosition()
    {
        if (randomPosition.Length != 0)

            target = randomPosition[Random.Range(0, randomPosition.Length)];
    }
    //触发检测
    private void OnTriggerEnter(Collider other)
    {
       
        if (other.gameObject.tag == "bullet" )
        {
            //添加子弹挂载的目标坦克,方便获取该子弹的攻击力,与受伤逻辑相结合
            BulletMove ball = other.gameObject.GetComponent<BulletMove>();
            TankFather ballTank = ball.Tank.GetComponent<TankFather>();

            //当子弹不是自己打的到自己身上的时候
            if (ballTank.tag != gameObject.tag)
            {
                //扣血
                Heart(ballTank);
            }

        }
    }

    public override void Fire()
    {
        //开启射击音效
        shootMusic.enabled = true;
        shootMusic.Play();
        for (int i = 0; i < shootTransform.Length ; i++)
        {
            GameObject ball = Instantiate(shootball, shootTransform[i].position, shootTransform[i].rotation);
            BulletMove movScript = ball.GetComponent<BulletMove>();
            Rigidbody shootBall = ball.GetComponent<Rigidbody>();
            shootBall.AddForce(shootTransform[i].transform.forward * shootSpeed);
            movScript.Tank = gameObject;  //声明子弹是由谁打出去的
        }
     
    }
    
    //死亡行为重写
    public override void Death()
    {
        base.Death();
        GamePlane.SingleInstance.AddScore(10);
    }

    //受伤行为重写
    public override void Heart(TankFather other)
    {
        base.Heart(other);
        showTime = 3; //血条倒计时展示
    }

    //GUI生命函数
    private void OnGUI()
    {
        if(showTime >=0) //血条倒计时展示
        {
            //简单的倒计时
            showTime -= Time.deltaTime;
            //世界坐标转屏幕坐标
            SreecPosition = Camera.main.WorldToScreenPoint(transform.position);

            //屏幕坐标转GUI坐标_____GUI的原点在左上角,屏幕坐标原点在左下角
            SreecPosition.y = Screen.height - SreecPosition.y;

            //底图Rect位置参数赋值
            GUIPosition1.x = SreecPosition.x - 50;
            GUIPosition1.y = SreecPosition.y - 70;
            GUIPosition1.width = 100;
            GUIPosition1.height = 15;

            //血条图Rect位置参数赋值
            GUIPosition2.x = SreecPosition.x - 50;
            GUIPosition2.y = SreecPosition.y - 70;

            //血条长度和血量同步
            GUIPosition2.width = 100*(nowBlood/maxBlood);
            GUIPosition2.height = 15;

            //绘制底图    
            GUI.DrawTexture(GUIPosition1, underTexture);
           
            //绘制血条       
            GUI.DrawTexture(GUIPosition2, topTexture);

        }
       
    }
}


🎶(D场景搭建——敌方阵营


在这里插入图片描述


🎶(E场景搭建——通关面板


_____________在这里插入图片描述

在这里插入图片描述
😶‍🌫️:步骤实现:

  • 1.面板制作
  • 2.数据显示和存储
  • 3.循环开始

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
//-------------------------------------
//—————————————————————————————————————
//___________项目:      
//___________功能:通关面板逻辑相关
//___________创建者:秩沅_______________
//_____________________________________
//-------------------------------------
public class VictorPlane : BeginFather<VictorPlane>
{
    public Button Require;  //确认按钮
    public InputFram name;  //输入的昵称
    public Label Score;     //显示的分数
    public Label LTime;      //显示的时间
    private int time;

 
    private void Start()
    {
        //添加按钮事件
        Require.triggerEvent += () => {

            //点击按钮后跳到主场景
            SceneManager.LoadScene("BeginScreen");
            //将数据存储
            SaveGameData.DataContorl.SaveRankData(name.ContorlContent.text, Convert.ToInt32(Score.ContorlContent.text), time);
        };
        //默认隐藏
        Hidden();
    }
    private void Update()
    {
        //将光标显示出来
        Cursor.visible = true;
        //分数显示
        Score.ContorlContent.text = GamePlane.SingleInstance.laScore.ContorlContent.text;
        //时间显示
        LTime.ContorlContent.text = GamePlane.SingleInstance.laTime.ContorlContent.text;
        //时间
        time = GamePlane.SingleInstance.time;
    }

}


🎶(F行为实现——通关点触发


在这里插入图片描述

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//-------------------------------------
//—————————————————————————————————————
//___________项目:      
//___________功能:  通关触发
//___________创建者:秩沅_______________
//_____________________________________
//-------------------------------------
public class over : MonoBehaviour
{
    private void OnTriggerEnter(Collider other)
    {
        if(other.CompareTag ("Player") )
        {
            Time.timeScale = 0;
           VictorPlane.SingleInstance.Show();
            
        }
    }
}

🎶(G场景搭建——结束面板


在这里插入图片描述

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
//-------------------------------------
//—————————————————————————————————————
//___________项目:       ______________
//___________功能: 死亡显示面板
//___________创建者:秩沅_______________
//_____________________________________
//-------------------------------------
public class DiedPlane : BeginFather<DiedPlane >
{
    public Button back;
    private void Start()
    {
        back.triggerEvent += () =>
        {
            //点击按钮后跳到主场景
            SceneManager.LoadScene("BeginScreen");
        };
        Hidden();       
    }
}


相关文章


⭐【2023unity游戏制作-mango的冒险】-6.关卡设计

⭐【2023unity游戏制作-mango的冒险】-5.攻击系统的简单实现

⭐【2023unity游戏制作-mango的冒险】-4.场景二的镜头和法球特效跟随

⭐【2023unity游戏制作-mango的冒险】-3.基础动作和动画API实现

⭐【2023unity游戏制作-mango的冒险】-2.始画面API制作

⭐【2023unity游戏制作-mango的冒险】-1.场景搭建

⭐“狂飙”游戏制作—游戏分类图鉴(网易游学)

⭐本站最全-unity常用API大全(万字详解),不信你不收藏



你们的点赞👍 收藏⭐ 留言📝 关注✅是我持续创作,输出优质内容的最大动力!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/954041.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

虹科分享 | 温度边缘效应对冻干成品含水量的影响(下)——优化和总结

上一篇文章中介绍到借助虹科Ellab的温度记录仪观察到由于冻干机壁面温度的影响&#xff0c;形成的边缘效应导致同一隔板的不同区域冻干饼块的干燥程度不均匀&#xff0c;含水量不同。 06 初次试验结果&#xff1a; 二次干燥中的产品温度显示&#xff1a; 放置在搁板中间的产品…

Linux内核源码分析 (A)常见内核面试题

Linux内核源码分析 (A)常见内核面试题 文章目录 Linux内核源码分析 (A)常见内核面试题调用 schedule() 进行进程切换的方式有几种CFS调度器vruntime的计算方式 网站收集面试题集合1 调用 schedule() 进行进程切换的方式有几种 系统调用 do_fork()&#xff1a;copy_process()定…

供热管网安全运行监测,提升供热管网安全性能

城市管网是城市的“生命线”之一&#xff0c;是城市赖以生存和发展的基础&#xff0c;在城市基础设施高质量发展中发挥着重要作用。供热管网作为城市生命线中连接供热管线与热用户的桥梁&#xff0c;担负着向企业和居民用户直接供热的重要职责。随着城市热力需求的急剧增加&…

【SpringBoot】Swagger和knife4j的使用

文章目录 前言1.什么是Swagger和Knife4j2.Swagger和Knife4j怎么用2.1 引入依赖2.2 设置配置类2.3 启动验证 3.完结撒花 前言 springboot笔记集合: springboot笔记合计 没用的废话理论不多说&#xff0c;会用就完了 1.什么是Swagger和Knife4j Swagger是一种开源的API描述语言…

ranger无法同步用户问题解决

1.首先就是定位日志,日志目录 cd /var/log/ranger/usersync 定位到问题报错如下: LdapDeltaUserGroupBuilder.getUsers() failed with exception:java.naming.AuthticationExceptiom :[LDAP:error code 49 - Invalid Credentials]:remaing name ‘ouPeople,dc*.dccom’ 解决办法…

frida动态调试入门01——定位关键代码

说明 frida是一款Python工具可以方便对内存进行hook修改代码逻辑在移动端安全和逆向过程中常用到。 实战 嘟嘟牛登录页面hook 使用到的工具 1&#xff0c;jadx-gui 2&#xff0c;frida 定位关键代码 使用jadx-gui 进行模糊搜索&#xff0c;例如搜索encyrpt之类的加密关键…

Python Qt(八)Treeview

源代码&#xff1a; # -*- coding: utf-8 -*-# Form implementation generated from reading ui file qt_treeview.ui # # Created by: PyQt5 UI code generator 5.15.9 # # WARNING: Any manual changes made to this file will be lost when pyuic5 is # run again. Do not…

vnc与windows之间的复制粘贴

【原创】VNC怎么和宿主机共享粘贴板 假设目标主机是linux&#xff0c;终端主机是windows&#xff08;就是在windows上使用VNC登陆linux&#xff09; 在linux中执行 vncconfig -nowin& 在linux选中文字后&#xff0c;无需其他按键&#xff0c;直接在windows中可以黏贴。 …

2023-8-31 Dijkstra求最短路(二)

题目链接&#xff1a;Dijkstra求最短路 II #include <iostream> #include <cstring> #include <algorithm> #include <vector> #include <queue>using namespace std;typedef pair<int, int> PII;const int N 150010;int n, m; int h[N…

利用GeoServer进行跨图层空间查询

Cross-layer filtering 跨层过滤提供了从层A中查找与层B中的特征具有特定关系的特征的能力。例如&#xff0c;这可以用于查找距离指定商店给定距离内的所有公交车站&#xff0c;或者查找指定城区内的所有咖啡店。 querylayer模块添加了实现跨层过滤的过滤功能。这些功能通过查…

十一、装饰器模式

一、什么是装饰器模式 装饰器&#xff08;Decorator&#xff09;模式的定义&#xff1a;指在不改变现有对象结构的情况下&#xff0c;动态地给该对象增加一些职责&#xff08;即增加其额外功能&#xff09;的模式&#xff0c;它属于对象结构型模式。 装饰器模式主要包含以下角色…

你的家乡清晰可见,全国卫星影像100%覆盖!

向上数三代&#xff0c;祖辈皆农民&#xff01; 无论是坐在高楼大厦里的白领&#xff0c;各种机构的公职人员&#xff0c;还是奔跑在大街小巷的外卖小哥&#xff0c;他们的根几乎皆在农村&#xff0c;当然应该也包括你和我&#xff01; 如何通过高清卫星影像看家乡的变化&…

企业如何充分借助大数据下精准营销?

技术的发展和智能终端的普及移动互联网用户的大规模增长使移动互联网快速发展&#xff0c;使中国移动互联网软件进入移动互联网时代越来越多地涉及到改变生活大家习惯。移动互联网时代的到来也意味着大数据时代的到来。精准营销数据方法&#xff0c;移动互联网和大数据的兴起不…

java八股文面试[多线程]——AQS 详细介绍

线程同步除了Synchronized Volatile ReentranLock 之外&#xff0c;还有其他一些用来进行同步的机制。 AQS 简单介绍 AQS 的全称为&#xff08;AbstractQueuedSynchronizer&#xff09;&#xff0c;这个类在 java.util.concurrent.locks 包下面。 AQS 是一个用来构建锁和同步器…

git submodule 子模块的基本使用

背景 浏览开源库的时候经常会看到如下子模块的引用情况。 子模块通常是项目比较复杂&#xff0c;需要对项目进行拆分&#xff0c;而项目又有引用关系时会使用。通常拆分项目后&#xff0c;我只需要关注自己的项目更改&#xff0c;不需要关注引用的项目都做了哪些更改。 通常…

为什么删除Windows 11上的Bloatware可以帮助加快你的电脑速度

如果你感觉你的电脑迟钝&#xff0c;彻底清除软件会有所帮助&#xff0c;而且这个过程对Windows用户来说越来越容易。 微软正在使删除以前难以删除的其他预装Windows应用程序成为可能。专家表示&#xff0c;这项新功能可能会改变用户的游戏规则。 科技公司Infatica的主管Vlad…

23款奔驰GLS400升级柏林之声音响系统,体验不一样的感觉

Burmester 环绕立体声音响系统–为每位乘员打造令人印象深刻的音质13个高性能扬声器、总功率为590瓦的9声道数字信号处理器(DSP)放大器以及放大器/扬声器系统专为车辆配置&#xff0c;打造出一流的Burmester之音。必要时还可进一步提升令人印象深刻的听觉体验。声音环绕功能能够…

如何在Windows本地快速搭建SFTP文件服务器,并通过端口映射实现公网远程访问

文章目录 1. 搭建SFTP服务器1.1 下载 freesshd服务器软件1.3 启动SFTP服务1.4 添加用户1.5 保存所有配置 2 安装SFTP客户端FileZilla测试2.1 配置一个本地SFTP站点2.2 内网连接测试成功 3 使用cpolar内网穿透3.1 创建SFTP隧道3.2 查看在线隧道列表 4. 使用SFTP客户端&#xff0…

对于uts namespace共享的测试

前言 单单以下列命令运行虽然是root&#xff0c;还不行&#xff0c;我们需要加--privileged&#xff0c;不然会报 hostname: you must be root to change the host name docker run -it --utshost ubuntu:latest /bin/bash 如果加上--privileged后 docker run -it --priv…

0727开发问题小结分享

Hi&#xff0c;我是阿昌&#xff0c;今天记录分析下关于0727开发问题小结分享的内容。 总结汇总了一些在开发问题&#xff0c;或者需要开发注意点&#xff1b; 一、内容概览 ● 问题驱动思维 ● 数据库 ● javaee & 框架 ● 服务治理 ● 三方服务 & 迁移操作 二、问…