伪工厂模式制造敌人

实现效果

1.敌人方实现

敌人代码


using UnityEngine;
using UnityEngine.UI;public  class EnemyBasics : MonoBehaviour
{public int EnemySpeed { get; internal set; }public int EnemyAttackDistance { get; internal set; }public int EnemyChaseDistance { get; internal set; }/*    //初级怪物,可以慢速追击
public abstract void  SlowEnemy(GameObject player, float distance, Text gameOverText, Image gameOverImage);
//中级怪物。可以快速追击
public abstract void MiddelEnemy(GameObject player, float distance, Text gameOverText, Image gameOverImage);
//高级怪物,可以发射子弹
public abstract void HighEnemy(GameObject player, float distance, Text gameOverText, Image gameOverImage);*/public  void UpdateEnemy(GameObject player, float distance, Text gameOverText, Image gameOverImage){//如果距离小于10cmEnemyChaseDistance,追踪玩家角色if (distance < EnemyChaseDistance){transform.LookAt(player.transform);//向玩家角色移动transform.Translate(Vector3.forward * EnemySpeed * Time.deltaTime);}//如果距离玩家角色小于2cmEnemyAttackDistanceif (distance < EnemyAttackDistance){gameOverText.text = "玩家角色死亡,游戏结束";gameOverImage.gameObject.SetActive(true);Time.timeScale = 0;}}}

using UnityEngine;
using UnityEngine.UI;public class EnemyFactory : MonoBehaviour
{[SerializeField] private GameObject slowEnemyPrefab;[SerializeField] private GameObject middleEnemyPrefab;[SerializeField] private GameObject highEnemyPrefab;public void CreateEnemy(int type, Vector3 position){GameObject enemy = null;switch (type){case 1:enemy = Instantiate(slowEnemyPrefab, position, Quaternion.identity);enemy.tag = "SlowEnemy";// enemy.AddComponent<EnemyBasics>();enemy.GetComponent<EnemyBasics>().EnemySpeed = 1;enemy.GetComponent<EnemyBasics>().EnemyAttackDistance = 1;enemy.GetComponent<EnemyBasics>().EnemyChaseDistance = 8;break;case 2:enemy = Instantiate(middleEnemyPrefab, position, Quaternion.identity);enemy.tag = "MiddleEnemy";//enemy.AddComponent<EnemyBasics>();enemy.GetComponent<EnemyBasics>().EnemySpeed = 3;enemy.GetComponent<EnemyBasics>().EnemyAttackDistance = 1;enemy.GetComponent<EnemyBasics>().EnemyChaseDistance = 12;// enemy.AddComponent<EnemyBasics>();break;case 3:enemy = Instantiate(highEnemyPrefab, position, Quaternion.identity);enemy.tag = "HighEnemy";// enemy.AddComponent<EnemyBasics>();enemy.GetComponent<EnemyBasics>().EnemySpeed = 5;enemy.GetComponent<EnemyBasics>().EnemyAttackDistance = 1;enemy.GetComponent<EnemyBasics>().EnemyChaseDistance = 20;//enemy.AddComponent<EnemyBasics>();break;}if (enemy != null){enemy.layer = LayerMask.NameToLayer("Enemy");}}}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;public class EnemyControl : MonoBehaviour
{private GameObject player;[SerializeField] private Text gameOverText;[SerializeField] private Image gameOverImage;private EnemyFactory enemyFactory;void Start(){player = GameObject.FindWithTag("Player");enemyFactory = GetComponent<EnemyFactory>();// 创建敌人实例enemyFactory.CreateEnemy(1, new Vector3(0, 1, 0));Debug.Log("初级敌人创建成功");enemyFactory.CreateEnemy(2, new Vector3(10, 1, 0));Debug.Log("中级敌人创建成功");enemyFactory.CreateEnemy(3, new Vector3(20, 1, 0));Debug.Log("高级敌人创建成功");}void Update(){if (player == null){Debug.LogError("Player object is not assigned.");return;}GameObject[] slowEnemys = GameObject.FindGameObjectsWithTag("SlowEnemy");GameObject[] middleEnemys = GameObject.FindGameObjectsWithTag("MiddleEnemy");GameObject[] highEnemys = GameObject.FindGameObjectsWithTag("HighEnemy");HandleEnemies(slowEnemys);HandleEnemies(middleEnemys);HandleEnemies(highEnemys);}private void HandleEnemies(GameObject[] enemies){foreach (GameObject enemy in enemies){if (enemy != null ){float distance = Vector3.Distance(player.transform.position, enemy.transform.position);Debug.Log(enemy.tag+"   "+ distance);enemy.GetComponent<EnemyBasics>().UpdateEnemy(player, distance, gameOverText, gameOverImage);}}}/*  private void HandleEnemies(GameObject[] enemies){foreach (GameObject enemy in enemies){if (enemy != null){EnemyBasics enemyBasics = enemy.GetComponent<EnemyBasics>();if (enemyBasics != null){float distance = Vector3.Distance(player.transform.position, enemy.transform.position);Debug.Log($"{enemy.tag} - Distance: {distance}");try{enemyBasics.UpdateEnemy(player, distance, gameOverText, gameOverImage);}catch (System.Exception ex){Debug.LogError($"Error in UpdateEnemy for {enemy.name}: {ex.Message}");}}else{Debug.LogError($"EnemyBasics component missing on {enemy.name}");}}else{Debug.LogWarning("Encountered a null enemy in the array.");}}}*/
}

挂载实现

预制体一览

2.我方实现

玩家控制代码

using UnityEngine;public class PlayerController : MonoBehaviour
{float CD = 2;[SerializeField] private GameObject BombPre;void Update(){//获取水平虚拟轴float horizontal = Input.GetAxis("Horizontal");//获取垂直虚拟轴float vertical = Input.GetAxis("Vertical");//创建一个向量,该向量为用户按下按键对应的向量//这里让horizontal控制x轴移动,vertical控制z轴移动Vector3 dir = new Vector3(vertical,  0, -horizontal);//如果向量不为0,证明玩家一定按了方向键if (dir != Vector3.zero){//玩家转向dir向量的方向transform.rotation = Quaternion.LookRotation(dir);//Update是按帧刷新的,如果参数不乘以Time.deltaTime,代表的含义为每帧移动2m//所以这里做一个转换,让2乘以帧时间间隔Time.deltaTi//即可转换单位,从每帧移动2m变为每秒移动2m//转换单位还可以同步不同设备的速度,//因为不同的设备可能有不同的帧率,所以如果不转换单位//那么可能看到不同设备下的移动速度是不同的transform.Translate(Vector3.forward * 7 * Time.deltaTime);}CD += Time.deltaTime;//如果按下U键if (Input.GetKeyDown(KeyCode.U)){Debug.Log("检测到玩家按下U键,放下炸弹");//2s的CDif (CD > 0.2f){//重置CDCD = 0;//释放炸弹Instantiate(BombPre, transform.position, transform.rotation);}}}
}

挂载

摄像机代码(或者直接把摄像机变成玩家的子物体,就不用写代码了)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class CameraControllerr : MonoBehaviour
{//保存向量private Vector3 vecter3;private Transform player;void Start(){//两种方法找Player// player = GameObject.Find("Player").transform;player = GameObject.FindGameObjectWithTag("Player").transform;vecter3 =player.transform.position-transform.position;}// Update is called once per framevoid Update(){transform.position = player.transform.position - vecter3;}
}

挂载

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

初识 C++ ( 1 )

引言&#xff1a;大家都说c是c的升级语言。我不懂这句话的含义后来看过解释才懂。 一、面向过程语言和面向对象语言 我们都知道C语言是面向过程语言&#xff0c;而C是面向对象语言&#xff0c;说C和C的区别&#xff0c;也就是在比较面向过程和面向对象的区别。 1.面向过程和面向…

WebGL系列教程九(动画)

目录 1 前言2 绘制立方体并进行纹理映射3 动画思路4 开始绘制4.1 在顶点着色器中声明旋转矩阵4.2 获取旋转矩阵变量并进行赋值4.3 计算角度4.4 每一帧都去绘制4.5 效果4.6 完整代码 5 总结 1 前言 上一篇我们讲了WebGL中的基础语法&#xff0c;现在我们已经讲过了三维物体的绘制…

TDengine 与 SCADA 强强联合:提升工业数据管理的效率与精准

随着时序数据库&#xff08;Time Series Database&#xff09;的日益普及&#xff0c;越来越多的工业自动化控制&#xff08;工控&#xff09;人员开始认识到其强大能力。然而&#xff0c;时序数据库在传统实时数据库应用领域&#xff0c;特别是在过程监控层的推广仍面临挑战&a…

【数据结构】排序算法---冒泡排序

文章目录 1. 定义2. 算法步骤3. 动图演示4. 性质5. 算法分析6. 代码实现C语言PythonJavaCGo 结语 1. 定义 冒泡排序&#xff08;英语&#xff1a;Bubble sort&#xff09;是一种简单的排序算法。它重复地走访过要排序的数列&#xff0c;一次比较两个元素&#xff0c;如果它们的…

Android 13 固定systemUI的状态栏为黑底白字,不能被系统应用或者三方应用修改

目录 一.背景 二.思路 三.代码流程 1.colos.xml自定义颜色 2.设置状态栏的背景颜色 3.对View进行操作 ①.对Clock(状态栏左侧的数字时钟)进行操作 ②.对电池(BatteryMeterView)进行操作 4.锁屏状态栏 5.patch汇总 一.背景 客户需求将状态栏固定成黑底白字,并且不能让系…

ipython里如何用?快速查阅帮助

1、&#xff1f;用于查询函数帮助文档&#xff0c;??用于查询带源码的帮助文档 ?用于搜索内容&#xff0c;*作为通配符。

C++调用C# DLL之踩坑记录

C是非托管代码&#xff0c;C#则是托管代码&#xff0c;无法直接调用 CLR的介绍见CLR简介 MSDN提到了两种非托管-托管的交互技术&#xff1a;CLR Interop和COM Interop 后者要将C# 类库注册为COM组件&#xff0c;本文只探讨CLR&#xff0c;要通过C CLR写中间层代码 方式一&…

IDEA 通义灵码 插件使用体验

目录 前言 主要功能 演示代码 解释代码 生成单元测试 生成代码注释 生成优化建议 代码片段补全 总结 前言 自从 AI 技术开始大规模应用&#xff0c;老板就想让下面的牛马借助 AI 工具来提高编码效率&#xff0c;由于团队都没有在实际编码中深度使用过 AI 工具&#x…

Miracast/WifiDisplay开发相关的深入调研分析-android投屏实战开发

Miracast/WifiDisplay概念介绍 Miracast Miracast是由Wi-Fi联盟于2012年所制定&#xff0c;以Wi-Fi直连&#xff08;Wi-Fi Direct&#xff09;为基础的无线显示标准。支持此标准的消费性电子产品&#xff08;又称3C设备&#xff09;可透过无线方式分享视频画面&#xff0c;例如…

VirtualBox 克隆已有的虚拟机

【前提】已经存在一个CentOS 7 虚拟机 【需求】克隆出来一个虚拟机,用于本机 【操作】 1.右击已有的虚拟机 -> 选择克隆 2.给新虚拟机起个名称 以及 生成新的MAC地址 3.克隆 4.修改网络和主机名称 # 修改网络编辑以下2个文件 vi /etc/sysconfig/network-scripts/ifcfg-enp…

Java之内部类

目录 实例内部类 静态内部类 局部内部类 匿名内部类 下面将讲解实例内部类&#xff0c;静态内部类&#xff0c;局部内部类和匿名内部类。 实例内部类 实例内部类&#xff08;也称为非静态内部类&#xff09;依赖于外部类的实例。这意味着&#xff0c;要创建实例内部类的实…

Kubernetes从零到精通(12-Ingress、Gateway API)

Ingress和Gateway API都是Kubernetes中用于管理外部访问集群服务的机制&#xff0c;但它们有不同的设计理念和适用场景。它们的基本原理是通过配置规则&#xff0c;将来自外部的网络流量路由到Kubernetes集群内部的服务上。 Ingress/Gateway API和Service Ingress/Gateway API…

Qt窗口——QToolBar

文章目录 工具栏创建工具栏设置toolTip工具栏配合菜单栏工具栏浮动状态 工具栏 QToolBar工具栏是应用程序中集成各种功能实现快捷键使用的一个区域。 可以有多个&#xff0c;也可以没有。 创建工具栏 #include "mainwindow.h" #include "ui_mainwindow.h&qu…

ARM 工业边缘计算机与 C# 编程的完美融合

在工业领域&#xff0c;随着智能化和数字化的不断推进&#xff0c;ARM 工业边缘计算机凭借其出色的性能和低功耗等优势&#xff0c;逐渐成为众多应用场景的重要支撑。而 C# 编程语言的强大功能和广泛适用性&#xff0c;使其在与 ARM 工业边缘计算机的结合中展现出了巨大的潜力。…

壹嘉情,中国与世界经济文化交流的新桥梁

壹嘉情正在全球华商领域迅速崛起。作为意大利华商总会的中国分部&#xff0c;壹嘉情承载着推动两岸及全球华商深度合作、实现资源共享和互利共赢的使命。它的成立标志着意大利华商总会在全球战略布局上的重要一步&#xff0c;同时也昭示了全球化浪潮中&#xff0c;华人企业正加…

LNMP的简单安装(ubuntu)

LNMP介绍 LNMP 是一种常见的开源软件组合&#xff0c;用于搭建高效的网站服务器环境。LNMP 代表以下四个组件&#xff1a; Linux&#xff1a;操作系统。Linux 是一种稳定、可靠、安全的开源操作系统&#xff0c;常用于服务器环境&#xff0c;特别是在企业级部署中。它负责底层…

小程序——生命周期

文章目录 运行机制更新机制生命周期介绍应用级别生命周期页面级别生命周期组件生命周期生命周期两个细节补充说明总结 运行机制 用一张图简要概述一下小程序的运行机制 冷启动与热启动&#xff1a; 小程序启动可以分为两种情况&#xff0c;一种是冷启动&#xff0c;一种是热…

js 深入理解生成器

目录 概述1 . 生成器基础2. 与普通函数的区别3. 通过 yield 中断执行3.1 yield 是干嘛的&#xff1f;3.2 yield 和 return 的区别3.3 每个生成器对象作用域都是独立的3.4 yeild 的使用位置3.5 生成器对象作为可迭代对象3.6 使用 yield 实现输入和输出3.6.1 yield实现输入3.6.1 …

【JVM安装MySQL】

环境 > VMware Workstation Pro > CentOS 7 >Navicat Premium Lite > MobaXterm添加 MySQL Yum 仓库 根据操作系统在下载界面选取对应yum库进行下载 wget https://dev.mysql.com/get/mysql80-community-release-el7-9.noarch.rpm在文件下载界面安装 rpm -ivh mysq…

<<编码>> 第 14 章 反馈与触发器(3)--锁存器与触发器 示例电路

电平触发 D 型触发器 info::操作说明 鼠标单击逻辑输入切换 0|1 状态 因复位和置位不应同时处在高电平, 因此在输入处加入一个非门反向, 然后复位和置位输入合并为 数据(Data) 输入 注: 当保持位为 0 时, 数据输入无效 primary::在线交互操作链接 https://cc.xiaogd.net/?star…