Unity丧尸围城Demo总结

1.BasePanel和UIManager
子类面板继承BasePanel,UIManager实现动态创建面板,展示面板,隐藏面板,得到面板
(1)单例类
(2)canvas设置为预制体,将新创建的面板设置为该子类
(3)面板和预制体名字一致

 abstract class BasePanel : MonoBehaviour
{private CanvasGroup canvasGroup;private float alphaSpeed = 10;public bool IsShow = false;private UnityAction hideCallback = null;protected virtual void Awake(){canvasGroup = this.GetComponent<CanvasGroup>();if (canvasGroup == null)canvasGroup = this.gameObject.AddComponent<CanvasGroup>();}protected virtual void Start(){Init();}/// <summary>/// 注册控件的方法 让所有的子面板都去注册一些方法 子类必须实现父类中的抽象方法/// </summary>public abstract void Init();public virtual void ShowMe(){canvasGroup.alpha = 0;IsShow = true;}public virtual void HideMe(UnityAction action){canvasGroup.alpha = 1;IsShow = false;hideCallback = action;}// Update is called once per frameprotected virtual void Update(){//透明度不为1 就一直加 这样可以保证不会反复进入这个方法//渐入if(IsShow && canvasGroup.alpha != 1){canvasGroup.alpha += alphaSpeed * Time.deltaTime;if(canvasGroup.alpha >= 1)canvasGroup.alpha = 1;}//渐出else if (!IsShow && canvasGroup.alpha != 0){canvasGroup.alpha -= alphaSpeed * Time.deltaTime;if (canvasGroup.alpha <= 0){canvasGroup.alpha = 0;hideCallback?.Invoke();}}}
}
public class UIManager
{//不继承mono 所以可以newprivate static UIManager instance = new UIManager();public static UIManager Instance => instance;private Transform canvasTrans;//在构造函数中对canvas进行初始化public UIManager(){GameObject canvasObj = GameObject.Instantiate(Resources.Load<GameObject>("UI/Canvas"));canvasTrans = canvasObj.transform;GameObject.DontDestroyOnLoad(canvasObj);}//字典管理已经显示过的面板 当需要隐藏时就移除该面板private Dictionary<string, BasePanel> panelDic = new Dictionary<string, BasePanel>();//显示面板//泛型约束:是BasePanel类或者BasePanel子类都可以public T ShowPanel<T>() where T : BasePanel{//要保证泛型T的类型 和 面板预制体名字一致string panelName = typeof(T).Name;//判断字典中是否显示过该面板//显示过就返回该面板if (panelDic.ContainsKey(panelName)){return (T)panelDic[panelName];}//字典没有 那就根据面板名字 实例化对象GameObject panelObj = GameObject.Instantiate(Resources.Load<GameObject>("UI/" + panelName));//设置父对象为canvas的transformpanelObj.transform.SetParent(canvasTrans, false);//得到面板中的对应脚本T panel = panelObj.GetComponent<T>();//存储面板中的脚本在字典中,方便获取和隐藏panelDic.Add(panelName, panel);//显示逻辑panel.ShowMe();return panel;}/// <summary>/// 隐藏面板/// </summary>/// <typeparam name="T">面板类名</typeparam>/// <param name="isFade">是否淡出完毕过后才删除面板,true为是</param>public void HidePanel<T>(bool isFade = true) where T : BasePanel{string panelName = typeof(T).Name;if (panelDic.ContainsKey(panelName)){if (isFade){//面板淡出过后删除panelDic[panelName].HideMe(() =>{//删除对象 并删除字典中存储的脚本GameObject.Destroy(panelDic[panelName].gameObject);panelDic.Remove(panelName);});}else{//删除对象 并删除字典中存储的脚本GameObject.Destroy(panelDic[panelName].gameObject);panelDic.Remove(panelName);}}}//得到面板public T GetPanel<T>() where T : BasePanel{string panelName = typeof(T).Name;if (panelDic.ContainsKey(panelName)){return (T)panelDic[panelName];}return null;}
}

2.摄像机跟随人物
(1)首先要设置看向的人物,摄像机的偏移(偏移多少),看向人物的偏移(头还是脚),移动速度和旋转速度

public class CameraMove : MonoBehaviour
{//摄像机看向的目标public Transform target;//摄像机相对目标位置的偏移值public Vector3 offsetPos;//看向位置的y的偏移值(看向人的脚还是头)public float bodyHeight;//移动和旋转速度public float moveSpeed;public float rotationSpeed;//目标位置private Vector3 targetPos;//目标旋转四元数private Quaternion targetRot;private void Update(){if (target == null) return;//根据目标对象 计算 摄像机当前的位置和角度//位置的计算//向后偏移z坐标targetPos = target.position + target.forward * offsetPos.z;//向上偏移y坐标targetPos += target.up * offsetPos.y;//左右偏移x坐标targetPos += target.right * offsetPos.x;//通过插值运算 让摄像机不断的向目标点靠拢this.transform.position = Vector3.Lerp(this.transform.position, targetPos, moveSpeed + Time.deltaTime);//旋转//人物位置 + 向上偏移 = 人物身体的点 - 摄像机的点 = 向量//得到最终要看向哪个点的四元数targetRot = Quaternion.LookRotation(target.position + Vector3.up * bodyHeight - this.transform.position);//让摄像机不断的向这个角度靠拢this.transform.rotation = Quaternion.Slerp(this.transform.rotation, targetRot, rotationSpeed * Time.deltaTime);}public void SetTarget(Transform player){this.target = player;}
}

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

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

相关文章

方法的用法

一.简介 目前为止我给出的所有的案例都是将代码放在main方法中&#xff0c;就会产生一些问题&#xff1a; 代码冗长&#xff0c;不利于维护变量过多&#xff0c;想不出那么多的变量名没有重用性 那么该如何解决呢&#xff1f; 我们可以编写功能性的代码块&#xff0c;来被ma…

华为DCN之:SDN和NFV

1. SDN概述 1.1 SDN的起源 SDN&#xff08;Software Defined Network&#xff09;即软件定义网络。是由斯坦福大学Clean Slate研究组提出的一种新型网络创新架构。其核心理念通过将网络设备控制平面与数据平面分离&#xff0c;从而实现了网络控制平面的集中控制&#xff0c;为…

【STM32 RTC实时时钟如何配置!超详细的解析和超简单的配置,附上寄存器操作】

STM32 里面RTC模块和时钟配置系统(RCC_BDCR寄存器)处于后备区域&#xff0c;即在系统复位或从待机模式唤醒后&#xff0c;RTC的设置和时间维持不变。因为系统对后备寄存器和RTC相关寄存器有写保护&#xff0c;所以如果想要对后备寄存器和RTC进行访问&#xff0c;则需要通过操作…

PHP校园论坛-计算机毕业设计源码08586

摘 要 本项目旨在基于PHP技术设计与实现一个校园论坛系统&#xff0c;以提供一个功能丰富、用户友好的交流平台。该论坛系统将包括用户注册与登录、帖子发布与回复、个人信息管理等基本功能&#xff0c;并结合社交化特点&#xff0c;增强用户之间的互动性。通过利用PHP语言及其…

14-15 为什么我们现在对阅读如此难以接受

写出来感觉很奇怪&#xff0c;但最近我感觉自己失去了阅读能力。长篇文本对我来说尤其具有挑战性。句子很难读完。更别提章节了。章节有很多段落&#xff0c;而段落又由许多句子组成。 啊。 即使在极少数情况下&#xff0c;我读完了一章&#xff0c;下一页上已经有另一章等着…

什么是自动气象站呢

自动气象站&#xff0c;作为现代气象观测的重要工具&#xff0c;已经深入到我们生活的各个领域&#xff0c;从气象预报到农业生产&#xff0c;再到环境保护&#xff0c;自动气象站都发挥着不可或缺的作用。 自动气象站&#xff0c;顾名思义&#xff0c;是一种能够自动收集、处理…

153. 寻找旋转排序数组中的最小值(中等)

153. 寻找旋转排序数组中的最小值 1. 题目描述2.详细题解3.代码实现3.1 Python3.2 Java 1. 题目描述 题目中转&#xff1a;153. 寻找旋转排序数组中的最小值 2.详细题解 如果不考虑 O ( l o g n ) O(log n) O(logn)的时间复杂度&#xff0c;直接 O ( n ) O(n) O(n)时间复杂…

基于Spring Boot的先进时尚室内管理系统

1 项目介绍 1.1 研究背景 随着21世纪信息技术革命的到来&#xff0c;互联网的普及与发展对人类社会的演变产生了深远影响&#xff0c;跨越了物质生活的丰盈边界&#xff0c;更深层次地滋养了人类的精神文化生活。在过去&#xff0c;囿于地理位置和技术条件的限制&#xff0c;…

【网络】网络基础(一)

网络基础&#xff08;一&#xff09; 文章目录 一、计算机网络背景1.1网络发展1.2认识“协议” 二、网络协议初识2.1OSI七层模型2.2OSI五层模型 三、网络传输基本流程3.1局域网通信3.2网络传输流程不跨子网的网络传输跨子网的网络传输 3.3网络中的地址管理IP地址MAC地址 一、计…

使用conda安装第三方包报错CondaSSLError

使用conda安装第三方包报错CondaSSLError 1. 报错信息2. 解决方法 1. 报错信息 错误描述&#xff1a;刚刚下载的 anaconda 在使用 conda 安装 pytorch 时报错&#xff08;CondaSSLError: OpenSSL appears to be unavailable on this machine. OpenSSL is required to download …

LeetCode题练习与总结:二叉树的后序遍历--145

一、题目描述 给你一棵二叉树的根节点 root &#xff0c;返回其节点值的 后序遍历 。 示例 1&#xff1a; 输入&#xff1a;root [1,null,2,3] 输出&#xff1a;[3,2,1]示例 2&#xff1a; 输入&#xff1a;root [] 输出&#xff1a;[]示例 3&#xff1a; 输入&#xff1a…

2002-2022年各省老年人口抚养比(人口抽样调查)数据

2002-2022年各省老年人口抚养比(人口抽样调查)数据 1、时间&#xff1a;2002-2022年 2、指标&#xff1a;老年人口抚养比 3、来源&#xff1a;国家统计局、统计年鉴 4、范围&#xff1a;31省&#xff0c; 5、缺失情况&#xff1a;无缺失&#xff0c;其中2010年的值取2009、…

Swift 中强大的 Key Paths(键路径)机制趣谈(下)

概览 在上一篇博文 Swift 中强大的 Key Paths(键路径)机制趣谈(上)中,我们介绍了 Swift 语言中键路径机制的基础知识,并举了若干例子讨论了它的一些用武之地。 而在本文中我们将再接再厉,继续有趣的键路径大冒险,为 KeyPaths 画上一个圆满的句号。 在本篇博文中,您将…

JavaScript之深入对象,详细讲讲构造函数与常见内置构造函数

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;我是前端菜鸟的自我修养&#xff01;今天给大家详细讲讲构造函数与常见内置构造函数&#xff0c;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;原创不易&#xff0c;如果能帮助到带大家&#xff0c;欢迎…

笔记:Git学习之应用场景和使用经验

目标&#xff1a;整理Git工具的应用场景和使用经验 一、开发环境 Git是代码版本控制工具&#xff1b;Github是代码托管平台。 工具组合&#xff1a;VSCode Git 需要安装的软件&#xff1a;vscode、Git 其中vscode需要安装的插件&#xff1a;GitLens、Git History 二、应用…

Unity编辑器工具---版本控制与自动化打包工具

Unity - 特殊文件夹【作用与是否会被打包到build中】 Unity编辑器工具—版本控制与自动化打包工具&#xff1a; 面板显示&#xff1a;工具包含一个面板&#xff0c;用于展示软件的不同版本信息。版本信息&#xff1a;面板上显示主版本号、当前版本号和子版本号。版本控制功能…

单目行车测距摄像系统(单目测距-行车)

单目行车测距摄像系统是一种利用单个摄像头实现车辆行驶中前方障碍物距离测量的技术。该系统通过计算机视觉算法&#xff0c;能够实时分析摄像头捕捉的图像&#xff0c;精确计算出车辆与前方物体之间的距离&#xff0c;对于自动驾驶、高级驾驶辅助系统&#xff08;ADAS&#xf…

【探索Linux】P.36(传输层 —— TCP协议段格式)

阅读导航 引言一、TCP段的基本格式二、控制位详细介绍三、16位接收窗口大小⭕窗口大小的作用⭕窗口大小的限制⭕窗口缩放选项⭕窗口大小的更新⭕窗口大小与拥塞控制 四、紧急指针温馨提示 引言 在上一篇文章中&#xff0c;我们深入探讨了一种无连接的UDP协议&#xff0c;它以其…

《新华日报》理论版报刊简介及投稿邮箱

《新华日报》理论版报刊简介及投稿邮箱 《新华日报》是中国共产党在抗日战争时期和解放战争初期创办的大型机关报&#xff0c;1949 年 4 月在南京复刊&#xff0c;1952 年成为中国共产党江苏省委机关报&#xff0c;现为中共江苏省委直属事业单位。 该报纸的理论版&#xff08;…

记录前端发现问题之 mock接口无返回数据导致所有后续接口调用报错:网络异常

1. 背景 就更新了代码&#xff0c;发现新涉及的页面&#xff0c;切换tab 之后会报错网络异常&#xff0c;再次切换其他没涉及的功能页面&#xff0c;继续报错网络异常 测试环境&#xff1a;纯前端代码&#xff0c;后端是前端mock的数据&#xff0c;仅供demo 2. 问题报错 手动…