U3D游戏开发按钮相关

有一天一个小伙伴跟我说,对于按钮相关网络某些教程并不全面,我大致看了,几乎差不多,接下来就大致补充一点代码相关的知识点了,还有我日常开发常用的一些按钮相关代码知识。

目录

1.UGUI的普通按钮相关

2.UGUI的异型按钮相关

3.NGUI按钮相关(需要下载导入NGUI)

4.UI基础框架相关(UGUI)

5.UGUI框架的使用--制作一个简易的提示管理器


(打码比较快,如果有小错误请指正,可能是误写,感谢!)

1.UGUI的普通按钮相关

代码控制相关的按钮参数

Button btn=this.GetComponent<Button>();
//按钮相关的参数可以被点出来使用
btn.interactable=true;

通过点击事件拖拽脚本检测按钮,在脚本中写上代码,然后把按钮事件拖拽到相应的按钮之下

public void ClickBtn()
{
//中间写上按钮逻辑
}

通过代码直接添加(通过代码添加的方式是我最经常使用的,你可以在场景中直接拖拽代码,也可以脚本控制查找对应的按钮)

1.拖拽结合lambda表达式的形式

//直接拖拽按钮
public Button btnClose;
//一般在Start函数之中添加
btnClose.onClick.AddListener(()=>
{
//结合lambda表达式的代码逻辑
});

2.拖拽

//以下代码在Start函数之中写入
btn.onClick.AddListener(ClickBtn);

//以下写入按钮逻辑
private void ClickBtn()
{
//写入按钮点击逻辑
}

3.代码识别

代码识别就可以直接使用private,然后代码查找按钮,按钮不能是未被显示的

GameObject.Find("btnClose");

其他的如上图所示。

4.按钮代码移出委托

btn.onClick.RemoveListener(ClickBtn);
//移出全部的
btn.onClick.RemoveAllListener();

2.UGUI的异型按钮相关

异形按钮就不是方方正正的按钮,是各种各样形状的。

方法一:拼凑法

通过多个透明图片拼凑出一个异形按钮用于射线检测。

方式二:代码相关

第一步:修改图片参数,开启Read/Write Enabled开关

第二步:通过代码修改图片的相应阙值(当alpha值小于该值就不会被射线检测了)

img.alphaHitTestMinimumThreshold=0.1f;(外部关联image)

3.NGUI按钮相关(需要下载导入NGUI)

制作NGUI按钮,一个Sprite(需要文字的话就再添加一个label子对象),为其添加Button脚本,添加碰撞器。

代码获取对象

public UIButton btn;
btn.onClick.Add(new EventDelegate(Click1));
//使用lambda表达式做处理
btn.onClick.Add(new EventDelegate(()=>
{
//中间写上逻辑
}));

4.UI基础框架相关(UGUI)

1.基本的面板框架,可以实现面板预设体的淡入淡出

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

/// <summary>
/// 面板基类
/// </summary>
public class BasePanel : MonoBehaviour
{
    //整体控制淡入淡出的画布组件
    private CanvasGroup canvasGroup;
    //淡入淡出的速度
    public float alphaSpeed = 8;
    //是否一开始要显示
    private bool isShow;
    private Dictionary<string,List<UIBehaviour>> controlDic= new Dictionary<string,List<UIBehaviour>>();
    // Start is called before the first frame update
    protected virtual void Awake()
    {
        FindChildrenControl<Button>();
        FindChildrenControl<Text>();
        FindChildrenControl<Image>();
        FindChildrenControl<Toggle>();
        FindChildrenControl<Slider>();
        FindChildrenControl<ScrollRect>();
        FindChildrenControl<InputField>();

        canvasGroup = this.GetComponent<CanvasGroup>();
        if (canvasGroup == null)
            canvasGroup = this.gameObject.AddComponent<CanvasGroup>();
    }

    /// <summary>
    /// 显示自己
    /// </summary>
    public virtual void ShowMe(object[] o = null)
    {
        isShow = true;
        canvasGroup.alpha = 0;
    }

    /// <summary>
    /// 隐藏自己
    /// </summary>
    public virtual void HideMe()
    {
        isShow = false;
        canvasGroup.alpha = 1;
    }

    /// <summary>
    /// 按钮点击
    /// </summary>
    /// <param name="btnName"></param>
    protected virtual void OnClick(string btnName)
    {

    }

    /// <summary>
    /// 勾选框触发
    /// </summary>
    /// <param name="toggleName"></param>
    /// <param name="value"></param>
    protected virtual void OnValueChanged(string toggleName,bool value)
    {

    }

    // Update is called once per frame
    public virtual void Update()
    {
        if ((canvasGroup == null))
        {
            return;
        }
        //淡入
        if (isShow && canvasGroup.alpha != 1)
        {
            canvasGroup.alpha += alphaSpeed * Time.deltaTime;
            if (canvasGroup.alpha >= 1)
                canvasGroup.alpha = 1;
        }
        //淡出
        else if (!isShow)
        {
            canvasGroup.alpha -= alphaSpeed * Time.deltaTime;
            if (canvasGroup.alpha <= 0)
            {
                canvasGroup.alpha = 0;
                //  hideCallBack?.Invoke();
            }
        }
    }

    /// <summary>
    /// 得到对应名字的对应控件脚本
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="controlName"></param>
    /// <returns></returns>
    protected T GetControl<T>(string controlName)where T:UIBehaviour
    {
        if(controlDic.ContainsKey(controlName))
        {
            for(int i = 0; i < controlDic[controlName].Count;++i)
            {
                if (controlDic[controlName][i] is T)
                    return controlDic[controlName][i] as T;
            }
        }
        return null;
    }
  
    private void FindChildrenControl<T>() where T:UIBehaviour
    {
        T[] controls= this.GetComponentsInChildren<T>();
        for(int i=0;i<controls.Length;++i)
        {
            string objName = controls[i].gameObject.name;
            if (controlDic.ContainsKey(objName))
                controlDic[objName].Add(controls[i]);
            else
                controlDic.Add(objName, new List<UIBehaviour>() { controls[i] });
            //如果是按钮控件
            if (controls[i] is Button)
            {
                (controls[i] as Button).onClick.AddListener(() =>
                {
                    OnClick(objName);
                });
            }
            //如果是单选框或者多选框
            else if (controls[i] is Toggle)
            {
                (controls[i] as Toggle).onValueChanged.AddListener((value) =>
                {
                    OnValueChanged(objName, value);
                });
            }
        }
    }
}

2.UIManager

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;

/// <summary>
/// UI层级
/// </summary>
public enum E_UI_Layer
{
    Bot,
    Mid,
    Top,
    System,
}

/// <summary>
/// UI管理器
/// 1.管理所有显示的面板
/// 2.提供给外部 显示和隐藏等等接口
/// </summary>
public class UIManager : BaseManager<UIManager>
{
    public Dictionary<string, BasePanel> panelDic = new Dictionary<string, BasePanel>();

    private Transform bot;
    private Transform mid;
    private Transform top;
    private Transform system;

    //记录我们UI的Canvas父对象 方便以后外部可能会使用它
    public RectTransform canvas;

    public UIManager()
    {
        //创建Canvas 让其过场景的时候 不被移除
        GameObject obj = ResMgr.GetInstance().Load<GameObject>("UI/Canvas");
        canvas = obj.transform as RectTransform;
        GameObject.DontDestroyOnLoad(obj);

        //找到各层
        bot = canvas.Find("Bot");
        mid = canvas.Find("Mid");
        top = canvas.Find("Top");
        system = canvas.Find("System");

        //创建EventSystem 让其过场景的时候 不被移除
        obj = ResMgr.GetInstance().Load<GameObject>("UI/EventSystem");
        GameObject.DontDestroyOnLoad(obj);
    }

    /// <summary>
    /// 通过层级枚举 得到对应层级的父对象
    /// </summary>
    /// <param name="layer"></param>
    /// <returns></returns>
    public Transform GetLayerFather(E_UI_Layer layer)
    {
        switch(layer)
        {
            case E_UI_Layer.Bot:
                return this.bot;
            case E_UI_Layer.Mid:
                return this.mid;
            case E_UI_Layer.Top:
                return this.top;
            case E_UI_Layer.System:
                return this.system;
        }
        return null;
    }

    /// <summary>
    /// 显示面板
    /// </summary>
    /// <typeparam name="T">面板脚本类型</typeparam>
    /// <param name="panelName">面板名</param>
    /// <param name="layer">显示在哪一层</param>
    /// <param name="callBack">当面板预设体创建成功后 你想做的事</param>
    public void ShowPanel<T>(string panelName, E_UI_Layer layer = E_UI_Layer.Mid, UnityAction<T> callBack = null) where T:BasePanel
    {
        if (panelDic.ContainsKey(panelName))
        {
            panelDic[panelName].ShowMe();
            // 处理面板创建完成后的逻辑
            if (callBack != null)
                callBack(panelDic[panelName] as T);
            //避免面板重复加载 如果存在该面板 即直接显示 调用回调函数后  直接return 不再处理后面的异步加载逻辑
            return;
        }

        ResMgr.GetInstance().LoadAsync<GameObject>("UI/" + panelName, (obj) =>
        {
            //把他作为 Canvas的子对象
            //并且 要设置它的相对位置
            //找到父对象 你到底显示在哪一层
            Transform father = bot;
            switch(layer)
            {
                case E_UI_Layer.Mid:
                    father = mid;
                    break;
                case E_UI_Layer.Top:
                    father = top;
                    break;
                case E_UI_Layer.System:
                    father = system;
                    break;
            }
            //设置父对象  设置相对位置和大小
            obj.transform.SetParent(father);

            obj.transform.localPosition = Vector3.zero;
            obj.transform.localScale = Vector3.one;

            (obj.transform as RectTransform).offsetMax = Vector2.zero;
            (obj.transform as RectTransform).offsetMin = Vector2.zero;

            //得到预设体身上的面板脚本
            T panel = obj.GetComponent<T>();
            // 处理面板创建完成后的逻辑
            if (callBack != null)
                callBack(panel);

            panel.ShowMe();
            if (!panelDic.ContainsKey(panelName))
            {
               //把面板存起来
               panelDic.Add(panelName, panel);
            }
            
        });
    }

    /// <summary>
    /// 隐藏面板
    /// </summary>
    /// <param name="panelName"></param>
    public void HidePanel(string panelName)
    {
        if(panelDic.ContainsKey(panelName))
        {
            panelDic[panelName].HideMe();
            GameObject.Destroy(panelDic[panelName].gameObject);
            panelDic.Remove(panelName);
        }
    }

    /// <summary>
    /// 得到某一个已经显示的面板 方便外部使用
    /// </summary>
    public T GetPanel<T>(string name) where T:BasePanel
    {
        if (panelDic.ContainsKey(name))
            return panelDic[name] as T;
        return null;
    }

    /// <summary>
    /// 给控件添加自定义事件监听
    /// </summary>
    /// <param name="control">控件对象</param>
    /// <param name="type">事件类型</param>
    /// <param name="callBack">事件的响应函数</param>
    public static void AddCustomEventListener(UIBehaviour control, EventTriggerType type, UnityAction<BaseEventData> callBack)
    {
        EventTrigger trigger = control.GetComponent<EventTrigger>();
        if (trigger == null)
            trigger = control.gameObject.AddComponent<EventTrigger>();

        EventTrigger.Entry entry = new EventTrigger.Entry();
        entry.eventID = type;
        entry.callback.AddListener(callBack);

        trigger.triggers.Add(entry);
    }

}

3.单例模式基类:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// 单例模式基类
/// </summary>
public class BaseManager<T> where T:new()
{
    private static T instance;
    public static T GetInstance()
    {
        if (instance == null)
            instance = new T();
        return instance;
    }
}

5.UGUI框架的使用--制作一个简易的提示管理器

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Threading;

public class TipMgr : BaseManager<TipMgr>
{
    public TipMgr()
    {
        
    }
    /// <summary>
    /// 用于提供给外界修改标签具体内容以及触发条件的方法
    /// </summary>
    /// <param name="ifShowChoose">是否存在选项</param>
    /// <param name="testContent">标签的显示信息</param>
    /// <param name="tipState">标签状态</param>
    public void ChangeTest(bool ifShowChoose, string testContent,TipState tipState)
    {
        ProtectHide("BigTip","TipPanel");
        UIManager.GetInstance().ShowPanel<TipPanel>("TipPanel",E_UI_Layer.System, (panel) =>
        {
            panel.ChangeTest(ifShowChoose,testContent,tipState);
        });
    }
    /// <summary>
    /// 提供给外界轻松触发气泡并且修改单条气泡内容的方法
    /// </summary>
    /// <param name="testContent">气泡内容</param>
    /// <param name="transPos">气泡触发位置</param>
    public void ChangeBubbleTest(string testContent, Transform transPos)
    {
        ProtectHide("TipPao","BubbleTip");
        UIManager.GetInstance().ShowPanel<BubbleTip>("BubbleTip",E_UI_Layer.Mid, (item) =>
        {
            item.ChangeBubble(testContent,transPos);
        });
    }
    /// <summary>
    /// 提供给外界轻松触发多条气泡内容修改的方法
    /// </summary>
    /// <param name="transPos"></param>
    /// <param name="testContent"></param>
    public void AddChangeBubbleTest( Transform transPos,params string[] testContent)
    {
        ProtectHide("TipPao","BubbleTip");
       
        UIManager.GetInstance().ShowPanel<BubbleTip>("BubbleTip",E_UI_Layer.Mid, (item) =>
        { 
            item.AddChangeBubble(transPos,testContent);
        });
    }
    /// <summary>
    /// 提供给外界用于修改提示内容的方法
    /// </summary>
    /// <param name="TipName"></param>
    public void ChangeTipPic(string TipName)
    {
        ProtectHide("TipPic","PicTipPanel");
        UIManager.GetInstance().ShowPanel<PicTipPanel>("PicTipPanel",E_UI_Layer.Mid, (panel) =>
        {
            panel.picName = TipName;
        });
    }
   
    public void ProtectHide(string panelTag,string panelName)
    {
        if(GameObject.FindGameObjectWithTag(panelTag))
            UIManager.GetInstance().HidePanel(panelName);
    }

}

(里面的名字是我随便起的,请不要介意,你可以自行修改,因为打小比赛几乎只有我个人写程序所以就随意起名了)

对于提示面板:

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.InputSystem;

public enum TipState
{
    None,//默认,无提示
    CompassInteraction,//罗盘交互提示
    SmallHoles,//小洞附近提示
    Clock,//钟表附近,找到齿轮
}
public class TipPanel : BasePanel
{
    public bool IsShowChoose = true;
    public TipState TipStates = TipState.None;
   
   /// <summary>
   /// 用于修改提示内容
   /// </summary>
   /// <param name="isShowChoose">是否存在提示选项</param>
   /// <param name="txtTip">修改提示内容</param>
   /// <param name="tipState">提示触发的状态</param>
    public void ChangeTest(bool isShowChoose, string txtTip,TipState tipState)
    {
        if (!isShowChoose)
        {
            GetControl<Button>("BtnYes").gameObject.SetActive(false);
            GetControl<Button>("BtnNo").gameObject.SetActive(false);
            IsShowChoose = false;
            Invoke("HideMe",5f);
        }
        GetControl<Text>("txtTip").text = txtTip;
        TipStates = tipState;
       
    }

    private void Start()
    {
        if (IsShowChoose)
        {
            //点击是
            GetControl<Button>("BtnYes").onClick.AddListener(() =>
            {
                switch (TipStates)
                {
                    case TipState.None:
                        break;
                    case TipState.CompassInteraction:
                        //播放献祭动画
                        break;
                }
                //隐藏自己
                UIManager.GetInstance().HidePanel("TipPanel");
            });
            //点击不
            GetControl<Button>("BtnNo").onClick.AddListener(() =>
            {
                switch (TipStates)
                {
                    case TipState.None:
                        break;
                    case TipState.CompassInteraction:
                        TipMgr.GetInstance().ChangeBubbleTest("我知道,你是我最正确的选择",PlayerController.GetInstance().transformPos.transform);
                        break;
                      
                }
                //隐藏自己
                UIManager.GetInstance().HidePanel("TipPanel");
            });
        }
      
    }
}

对于小气泡组件:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using UnityEngine;
using UnityEngine.UI;


/// <summary>
/// 人物对话气泡
/// </summary>
public class BubbleTip : BasePanel
{
    [SerializeField] public string[] content;
    [SerializeField]private int _num = 1;
    
     /// <summary>
    /// 提供给外界用于修改单个气泡内容的方法
    /// </summary>
    /// <param name="testBubble">气泡内容</param>
    /// <param name="bubbletransform">气泡位置</param>
    public void ChangeBubble(string testBubble,Transform bubbletransform)
    {
        transform.position = Camera.main.WorldToScreenPoint(bubbletransform.position);
        GetControl<Text>("txtBubble").text = testBubble;
        Invoke("HideMe",2);
    }
    /// <summary>
    /// 提供给外界用于修改多个气泡内容的方法
    /// </summary>
    /// <param name="bubbletransform">气泡出现的位置</param>
    /// <param name="testContent">多条内容</param>
    public void AddChangeBubble(Transform bubbletransform,params string[] testContent)
    {
        this.transform.position = Camera.main.WorldToScreenPoint(bubbletransform.position);
        content = testContent;
        GetControl<Text>("txtBubble").text = testContent[0];
        
        Invoke("InvokeP",2);
       
        Invoke("HideMe",(testContent.Length+1)*2);
    }

    public void InvokeP()
    {
        GetControl<Text>("txtBubble").text = content[_num ];
        _num += 1;
        if (_num<content.Length)
            Invoke("InvokeP",2);
    }
    public override void HideMe()
    {
        base.HideMe();
        _num = 0;
    }
}

以上使用了Json管理器,源码未提供。以上UI部分是比赛的项目源码所以夹杂一些东西。通过了多次测试,几乎没有问题,可以放心使用。气泡位置不是实时更新所以不会跟随,如果你有需要可以大致修改一下代码。代码主要介绍UGUI的框架使用,源码也不完整因为需求被砍了一大半。

以上就是UI按钮代码相关的常见代码了,喜欢就请点赞收藏。感谢!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Python项目实战,用Python实现2048游戏

目录 写在前言项目介绍项目思路环境搭建项目实现初始化Python类初始化游戏窗口定义游戏棋盘和方块移动和合并游戏主循环 进一步探索 写在前言 hello&#xff0c;大家好&#xff0c;我是一点&#xff0c;专注于Python编程&#xff0c;如果你也对感Python感兴趣&#xff0c;欢迎…

基于JSP的酒店客房管理系统(三)

目录 第四章 系统各模块的实现 4.1客房管理系统首页的实现 4.1.1 客房管理系统首页概述 4.2客房管理系统前台的实现 4.2.1 客房管理系统前台概述 4.2.2 客房管理系统前台实现过程 4.2.3 预定客房信息及客房信息的查询 4.3客房管理系统后台的实现 4.3.1 客房管理系统后…

搜索算法系列之四(斐波那契)

以下算法被验证过&#xff0c;如有什么问题或有补充的欢迎留言。 前言 斐波那契数列&#xff0c;又称黄金分割数列&#xff0c;是由意大利数学家&#xff08;Leonardo Fibonacci&#xff09;在1202年提出的。这个数列的递推关系是F(0)1&#xff0c;F(1)1&#xff0c;F(n)F(n-…

最近惊爆谷歌裁员

Python团队还没解散完&#xff0c;谷歌又对Flutter、Dart动手了。 什么原因呢&#xff0c;猜测啊。 谷歌裁员Python的具体原因可能是因为公司在进行技术栈的调整和优化。Python作为一种脚本语言&#xff0c;在某些情况下可能无法提供足够的性能或者扩展性&#xff0c;尤其是在…

【6D位姿估计】数据集汇总 BOP

前言 BOP是6D位姿估计基准&#xff0c;汇总整理了多个数据集&#xff0c;还举行挑战赛&#xff0c;相关报告被CVPR2024接受和认可。 它提供3D物体模型和RGB-D图像&#xff0c;其中标注信息包括6D位姿、2D边界框和2D蒙版等。 包含数据集&#xff1a;LM 、LM-O 、T-LESS 、IT…

android系统serviceManger源码解析

一&#xff0c;serviceManger时序图 本文涉及到的源码文件&#xff1a; /frameworks/native/cmds/servicemanager/main.cpp /frameworks/native/libs/binder/ProcessState.cpp /frameworks/native/cmds/servicemanager/ServiceManager.cpp /frameworks/native/libs/binder/IP…

练习题(2024/5/6)

1路径总和 II 给你二叉树的根节点 root 和一个整数目标和 targetSum &#xff0c;找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。 叶子节点 是指没有子节点的节点。 示例 1&#xff1a; 输入&#xff1a;root [5,4,8,11,null,13,4,7,2,null,null,5,1], target…

【数据结构】C++语言实现栈(详细解读)

c语言中的小小白-CSDN博客c语言中的小小白关注算法,c,c语言,贪心算法,链表,mysql,动态规划,后端,线性回归,数据结构,排序算法领域.https://blog.csdn.net/bhbcdxb123?spm1001.2014.3001.5343 给大家分享一句我很喜欢我话&#xff1a; 知不足而奋进&#xff0c;望远山而前行&am…

【携程笔试题汇总】[全网首发] 2024-05-06-携程春招笔试题-三语言题解(CPP/Python/Java)

&#x1f36d; 大家好这里是清隆学长 &#xff0c;一枚热爱算法的程序员 ✨ 本系列打算持续跟新携程近期的春秋招笔试题汇总&#xff5e; &#x1f4bb; ACM银牌&#x1f948;| 多次AK大厂笔试 &#xff5c; 编程一对一辅导 &#x1f44f; 感谢大家的订阅➕ 和 喜欢&#x1f49…

【网心云邀请码:KpyV3Dk7】轻松赚油费,新用户专享福利来袭!绑定设备连续在线7 天必得高额奖励

&#x1f4e2; 各位朋友们&#xff0c;好消息来啦&#xff01;现在注册网心云&#xff0c;通过我们的专属邀请码&#xff1a;KpyV3Dk7 &#xff0c;即可享受多重新手福利&#xff0c;让您的闲置设备为您赚钱&#xff01; &#x1f4b8; 立即加入&#xff0c;您将获得&#xff1…

代码本地化

目的 代码本地化&#xff08;Localization&#xff09;是指将软件应用程序中的文本、图形、声音和其他内容翻译成特定语言的过程&#xff0c;同时确保这些内容在目标文化中适当地呈现。本地化不仅仅是对文本进行翻译&#xff0c;还包括对日期、时间、数字、货币、排序顺序、文本…

生成一个好故事!StoryDiffusion:一致自注意力和语义运动预测器必不可少(南开字节)

文章链接&#xff1a;https://arxiv.org/pdf/2405.01434 主页&#xff1a;https://storydiffusion.github.io/ 对于最近基于扩散的生成模型来说&#xff0c;在一系列生成的图像中保持一致的内容&#xff0c;尤其是那些包含主题和复杂细节的图像&#xff0c;是一个重大挑战。本…

C/C++ BM32 合并二叉树

文章目录 前言题目解决方案一1.1 思路阐述1.2 源码 解决方案二2.1 思路阐述2.2 源码 总结 前言 树的题目大概率是要用到递归的&#xff0c;将一个树的问题拆分成子树的问题&#xff0c;不断拆分。 这题也用到了递归的思想。 题目 已知两颗二叉树&#xff0c;将它们合并成一颗…

腾讯地图商业授权说明一篇文章讲清楚如何操作

最近在使用腾讯地图&#xff0c;发现我要上架应用商店APP需要我有地图的授权书。 认真研究了一下原来腾讯地图现在要收费了&#xff0c;如果你打算以商业目的使用它&#xff0c;比如对第三方用户收费或者进行项目投标等&#xff0c;就需要先获取腾讯位置服务的商业授权许可。申…

网络演进技术演进:裸纤专线、SDH、MSTP+、OTN、PTN、IP-RAN

前言 文章主要介绍常见名词以及其在各自领域实现的功能价值。 01 裸纤 裸光纤&#xff08;裸光纤&#xff09;由运营商提供&#xff0c;是无中继的光纤线路&#xff0c;仅通过配线架连接。相比传统光纤&#xff0c;裸光纤提供纯粹的物理传输路径&#xff0c;无需额外网…

win2012磁盘空间不足,c盘正常,d盘无法写入,如何解决?

&#x1f3c6;本文收录于「Bug调优」专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收藏&&…

人工智能概述与入门基础简述

人工智能&#xff08;AI&#xff09;是计算机科学的一个分支&#xff0c;它致力于创建能够执行通常需要人类智能的任务的机器。这篇科普文章将全面介绍人工智能的基本概念、发展历程、主要技术、实际应用以及如何入门这一领域。 一、人工智能的定义与发展历程 人工智能的概念…

vue2实现生成二维码和复制保存图片功能(复制的同时会给图片加文字)

<template><divstyle"display: flex;justify-content: center;align-items: center;width: 100vw;height: 100vh;"><div><!-- 生成二维码按钮和输入二维码的输入框 --><input v-model"url" placeholder"输入链接" ty…

第四篇:记忆的迷宫:探索计算机存储结构的奥秘与创新

记忆的迷宫&#xff1a;探索计算机存储结构的奥秘与创新 1 引言 1.1 计算机存储系统的发展与重要性 在现代计算技术中&#xff0c;存储系统承担着非常关键的角色&#xff0c;它不仅负责信息的持久保存&#xff0c;同时确保高效的数据访问速度&#xff0c;影响着整体系统性能的…

[redis] redis为什么快

1. Redis与Memcached的区别 两者都是非关系型内存键值数据库&#xff0c;现在公司一般都是用 Redis 来实现缓存&#xff0c;而且 Redis 自身也越来越强大了&#xff01;Redis 与 Memcached 主要有以下不同&#xff1a; (1) memcached所有的值均是简单的字符串&#xff0c;red…