Unity 2D项目初始化实战:从零搭建可维护游戏骨架

news2026/5/22 7:30:44
1. 这不是“又一个Unity入门教程”而是我带三个实习生从零做出第一个可玩Demo的真实路径你搜“Unity 2D 教程”首页全是“5分钟创建角色”“10行代码实现跳跃”——画面很炫但关掉视频后你连项目文件夹里该删哪个.meta、该留哪个.asmdef都拿不准。我带过二十多个刚毕业的Unity新人90%卡在同一个地方不是不会写C#而是根本不知道一个真正能跑起来的2D游戏项目骨架长什么样。它不靠“拖拽预制体”堆出来而是一套有呼吸感的结构SpriteRenderer怎么和Tilemap共存而不打架Rigidbody2D的Mass设成0.1还是1.0会直接影响平台跳跃的手感反馈甚至Canvas的Render Mode选Screen Space - Overlay还是World Space直接决定UI按钮点不点得中。这篇不是教你怎么写“void Start()”而是还原我去年夏天在工位上用一支红笔在A4纸上画出的那张图左边是美术给的PSD分层中间是Unity里对应的Sprite Atlas命名规则右边是脚本里引用资源的三种安全写法。它解决的是“为什么我照着B站视频做一换自己美术资源就报NullReferenceException”的问题。适合两类人一是刚装完Unity Hub、连Package Manager在哪都没找到的新手二是做过几个小Demo但总被策划问“这个功能能不能加个缓动”就卡住的初级程序员。接下来所有内容都来自我们团队内部那份没对外公开的《2D项目启动检查清单》连Asset Store插件的License校验步骤都写进去了。2. 项目初始化阶段比写第一行代码更重要的三件事2.1 创建项目时必须关闭的两个默认选项Unity 2021.3 LTS当前团队主力版本新建2D项目时默认勾选“Use Package Manager for Unity Services”和“Enable Preview Packages”。这两个开关看似无害实则埋着深坑。前者会在ProjectSettings/Editor中自动生成Services窗口一旦你后续接入第三方分析SDK它的自动注入机制会和你手动配置的初始化顺序冲突导致Analytics.StartSession()调用失败却无任何报错日志后者则会让Package Manager悄悄下载beta版的2D Animation包而该包与正式版Sprite Shape Pro存在API签名不兼容——我们曾因此返工三天只因美术导出的骨骼动画在预览窗口正常打包后全变黑块。正确操作是新建项目对话框里取消勾选这两项点击Create后立刻打开Edit → Preferences → External Tools把External Script Editor设为Visual Studio非VS Code再重启Unity。这步看似多余实则规避了后续70%的脚本编译错误——VS能正确识别Unity生成的Assembly-CSharp.csproj中的条件编译符号如UNITY_2021_3_OR_NEWER而VS Code需要额外配置omnisharp.json新手极易遗漏。2.2 Project Settings里的五个关键参数调整很多教程跳过Project Settings直接教脚本但这里藏着影响2D游戏手感的底层开关。我逐个说明调整逻辑和实测数据设置路径默认值推荐值调整原因实测影响Edit → Project Settings → Player → Other Settings → Color SpaceGammaLinearGamma空间下SpriteRenderer的Color乘法计算不遵循物理光照模型导致UI遮罩与场景光影叠加时出现色阶断层在血条UI覆盖角色时Linear空间下过渡平滑Gamma空间下可见明显色带Edit → Project Settings → Editor → Asset PipelineVersion 1Version 2Version 1使用旧式meta文件管理当美术频繁替换PSD时Version 1会残留旧Sprite引用引发MissingReferenceException切换Version 2后美术每次保存PSDUnity自动重建Sprite Atlas无须手动ReimportEdit → Project Settings → Physics 2D → Default Contact Offset0.010.005此值决定Collider2D检测碰撞的“缓冲距离”过大导致角色在斜坡上滑动时穿模过小则平台边缘跳跃判定失效设为0.005后角色在30度斜坡上行走稳定性提升40%Jump测试通过率从68%升至92%Edit → Project Settings → Quality → Default Quality LevelVery HighHighVery High启用MSAA 8x对2D像素风游戏纯属浪费GPU资源且在Android低端机上强制降级为Bilinear反而导致纹理模糊High档位下iOS A11芯片设备帧率稳定在58-60fpsVery High档位波动达42-53fpsEdit → Project Settings → Graphics → Tier SettingsAutoTier 1Auto模式下Unity根据设备自动选择渲染管线但2D项目无需URP/HDRP强行启用会增加Draw Call强制Tier 1后Android中端机Draw Call从127降至89内存占用减少18MB提示修改Physics 2D的Default Contact Offset后必须重启Unity编辑器才能生效仅点击Apply无效。这是Unity 2021.3的已知bug官方文档未提及。2.3 文件夹结构设计拒绝“Assets/Scripts/Player/PlayerController.cs”式命名新手常犯的错误是把脚本按“谁用”分类Player/Enemy/UI而非按“做什么”分层。我们团队采用三层架构Core层存放所有不依赖具体游戏逻辑的通用组件。例如ObjectPoolT对象池基类、EventBus事件总线、TweenManager补间动画管理器。这些脚本放在Assets/Core/下命名不带项目名前缀。Game层实现具体游戏机制。Assets/Game/Player/下只有PlayerMovement.cs处理移动输入与Rigidbody2D交互、PlayerCombat.cs处理攻击判定与伤害计算绝不出现PlayerController.cs这种大杂烩。每个脚本只做一件事且文件名与类名严格一致。Data层存放ScriptableObject数据资产。Assets/Data/Characters/PlayerStats.asset定义角色属性Assets/Data/Levels/Level01.asset存储关卡布局。所有数据资产必须在Inspector中设置为ReadOnly右键→Set ReadOnly防止运行时意外修改。这种结构带来的实际好处当策划要求“给敌人添加眩晕状态”时你只需在Game/Enemy/下新增EnemyStun.cs无需改动任何已有脚本当美术更换角色贴图时只需更新Data/Characters/PlayerStats.asset中的Sprite字段所有引用自动刷新。3. Sprite管理实战从PSD到可拖拽预制体的完整链路3.1 美术交付规范为什么必须要求PSD分层命名带序号我们给美术的交付清单第一条就是“所有角色动作图层必须按00_Idle,01_Run,02_JumpUp,03_JumpDown格式命名”。这不是为了好看而是Unity Sprite Editor自动切片的硬性需求。当你在Inspector中选中PSD点击Sprite Mode → Multiple再点Sprite EditorUnity会按图层名称的数字前缀排序切片。如果美术命名为Idle,Run,JumpUnity会按字母序排列为Idle,Jump,Run导致动画序列错乱。更致命的是当美术后续添加新动作04_Attack时自动切片会将其插入到03_JumpDown之后而旧版动画控制器仍按原顺序读取造成攻击帧播放成跳跃帧。实操验证我用同一份PSD做了两组测试。A组按规范命名B组用中文命名。在Animation窗口中创建新动画剪辑时A组自动识别出4个Sprite序列B组仅识别出1个整个PSD被当做一个Sprite。这意味着B组方案下程序员必须手动在Sprite Editor中逐帧切割——平均耗时17分钟/角色而A组全程自动耗时23秒。3.2 Sprite Atlas构建避免“一张图集打天下”的陷阱新手常把所有角色、UI、特效塞进一个Atlas美其名曰“减少Draw Call”。但实测发现当Atlas尺寸超过2048x2048时Android设备会出现纹理采样偏移——角色移动时边缘闪烁白边。我们的解决方案是按用途分辨率双维度拆分UI_HD.atlas存放所有1080p UI元素压缩格式设为ETC2Android/ASTCiOS开启Read/Write EnabledUI动态换肤需要Characters_LD.atlas存放低精度角色贴图用于小地图缩略图压缩格式设为ETC1关闭Read/WriteVFX_Sprites.atlas存放粒子特效Sprite压缩格式设为RGBA 16 bit禁用Mip Maps特效不需要远距离模糊关键技巧在Atlas Inspector中将Padding设为4非默认2。这是因为Unity的Sprite Packer在合并贴图时若相邻Sprite间距小于4像素会因GPU纹理采样插值产生颜色渗透。我们曾因此修复一个持续半年的BUGBoss战时血条UI右侧总有一条1像素宽的红色残影根源就是UI Atlas与角色Atlas共用同一份Padding设置。3.3 预制体Prefab创建规范为什么禁止直接拖拽Scene视图中的GameObject直接拖拽Scene中物体生成Prefab会继承当前Scene的Transform值Position/Rotation/Scale导致Prefab实例化时位置错乱。正确流程是在Hierarchy中右键 → Create Empty命名为Player_Prefab将已配置好的SpriteRenderer、Rigidbody2D、Collider2D等组件拖入该空对象关键步骤选中Player_Prefab在Inspector顶部点击“Apply”按钮非“Override”此时Prefab资产才真正保存组件状态将该Prefab拖入Project窗口重命名为Player.prefab注意若Prefab内含子对象如武器挂点必须确保子对象的Local Position为(0,0,0)否则实例化后子对象会相对父对象偏移。我们团队用Editor脚本自动校验每次Save Prefab时扫描所有子Transform若Local Position非零则弹出警告。4. 核心组件配置详解让2D物理系统真正“听话”4.1 Rigidbody2D的四大参数真相网上教程常说“2D游戏必须用Rigidbody2D”却极少解释参数背后的物理意义。我们用真实测试数据说话Body TypeDynamic动态受重力、力、碰撞影响。适用于玩家角色、可破坏物体。Kinematic运动学不受重力但可通过MovePosition()精确控制。适用于平台、移动电梯。Static静态完全静止仅作为碰撞边界。适用于地面、墙壁。陷阱将敌人设为Kinematic后用AddForce()无效——必须改用MovePosition()。我们曾因此调试8小时只因文档没写清“Kinematic物体忽略所有力”。Constraints勾选Freeze Position Y后物体Y轴坐标被锁死但transform.position new Vector2(x, y)仍可修改真正生效的是Rigidbody2D.velocity new Vector2(vx, 0)。这是Unity的底层设计Constraints限制的是物理引擎的积分运算而非Transform赋值。Gravity Scale设为0即关闭重力但设为0.5并非“一半重力”而是“应用重力时乘以0.5”。实测显示在默认重力值-9.81下Gravity Scale0.5的角色下落速度比Gravity Scale1慢约30%但起跳初速度相同导致跳跃高度降低而非时间延长。Sleep Threshold默认0.005指物体速度低于此值时进入休眠以节省CPU。但2D平台游戏中角色在斜坡上缓慢滑动时易被误判休眠导致碰撞检测失效。我们统一设为0.001牺牲0.3%CPU换取100%碰撞可靠性。4.2 Collider2D类型选择Box、Circle、Polygon的实战取舍类型适用场景性能开销关键注意事项BoxCollider2D角色主体、平台方块★☆☆☆☆最低必须与Sprite Renderer的Bounds中心对齐否则碰撞盒偏移。用GetComponentSpriteRenderer().bounds.center校验CircleCollider2D球形敌人、滚动道具★★☆☆☆Radius值非像素单位而是世界坐标单位。100x100像素的球Radius应设为0.5假设Pixels Per Unit200PolygonCollider2D复杂地形、不规则障碍物★★★★☆最高自动生成的顶点数超256时Android设备崩溃。必须手动简化在Collider Inspector点Edit Collider → 右键顶点→Simplify我们曾用PolygonCollider2D为一棵树建模自动生成412个顶点打包后在华为P30上必现闪退。手动简化至187个顶点后问题消失。简化原则保留轮廓转折点直线段用2个顶点足够。4.3 Tilemap系统深度配置为什么你的瓦片总在移动时闪烁Tilemap闪烁的根源在于瓦片渲染顺序与摄像机裁剪面冲突。解决方案分三步设置Sorting Layer在Edit → Project Settings → Tags and Layers → Sorting Layers中按渲染优先级从高到低添加UIPlayerForegroundTilesBackground。注意Tiles层必须在Player之下否则角色会被瓦片遮挡。配置Camera的Clipping Planes主摄像机的Near设为0.01非默认0.3Far设为1000。过大的Near值会导致Z-Fighting使相邻瓦片交界处闪烁。为Tilemap添加Composite Collider 2D单独为每个Tilemap添加此组件并勾选Geometry Type → Outline。它会将所有瓦片的Collider合并为一个优化后的多边形减少物理引擎计算量。实测显示100x100瓦片地图开启Composite后FixedUpdate耗时从12ms降至3ms。提示Composite Collider 2D必须配合Rigidbody2D使用且Rigidbody2D的Body Type必须为Static。若忘记添加Rigidbody2DComposite组件会显示黄色警告但游戏仍能运行——只是碰撞检测完全失效。5. 输入系统搭建告别Input.GetAxis拥抱新Input System5.1 为什么必须迁移至Input System PackageUnity旧版Input ManagerInput.GetAxis存在三大硬伤无法区分多手柄输入当玩家连接Xbox手柄Switch Pro手柄时Input.GetAxis(Horizontal)会混合两个手柄的摇杆值导致角色乱转。移动端触控延迟高旧系统触控事件需经Unity底层消息队列平均延迟42ms新系统直通TouchPhase延迟压至8ms。不支持触觉反馈新Input System可调用Gamepad.current.SetMotorSpeeds()实现手柄震动旧系统完全不支持。迁移成本其实很低我们用2小时完成整个项目切换。核心步骤是创建Input Actions资产Assets右键 → Create → Input Actions命名为PlayerControls.inputactions在Inspector中点击号添加Action Map命名为Player在Player下添加两个ActionMoveValue类型Binding设为Gamepad/leftStick和Keyboard/adleftArrowrightArrowJumpButton类型Binding设为Gamepad/a和Keyboard/space5.2 Player脚本改造从Update到Input Callback旧代码void Update() { float h Input.GetAxis(Horizontal); rb.velocity new Vector2(h * speed, rb.velocity.y); if (Input.GetButtonDown(Jump) isGrounded) { rb.AddForce(Vector2.up * jumpForce); } }新代码需先在PlayerControls中启用C# Class Generationpublic class Player : MonoBehaviour { private PlayerControls controls; private Rigidbody2D rb; void Awake() { controls new PlayerControls(); rb GetComponentRigidbody2D(); } void OnEnable() { controls.Player.Move.performed ctx Move(ctx.ReadValueVector2()); controls.Player.Jump.performed _ Jump(); controls.Enable(); } void OnDisable() { controls.Disable(); } void Move(Vector2 input) { rb.velocity new Vector2(input.x * speed, rb.velocity.y); } void Jump() { if (isGrounded) { rb.AddForce(Vector2.up * jumpForce, ForceMode2D.Impulse); } } }关键差异performed回调在输入发生瞬间触发而Update每帧轮询。实测表明在60fps设备上新方案输入响应延迟稳定在16.7ms旧方案因帧率波动可能达33ms。5.3 移动端适配虚拟摇杆的精准实现新Input System不内置虚拟摇杆需自行实现。我们采用轻量级方案创建Canvas → Panel → Image设为Source Image的圆角矩形作为摇杆底座在Panel下创建Image设为Source Image的圆形作为摇杆手柄添加脚本VirtualJoystick.cs核心逻辑public class VirtualJoystick : MonoBehaviour { public RectTransform baseRect; // 底座RectTransform public RectTransform handleRect; // 手柄RectTransform public float deadZone 0.2f; // 摇杆死区 private Vector2 inputDirection; private bool isDragging; public Vector2 GetInput() isDragging ? inputDirection : Vector2.zero; public void OnBeginDrag(PointerEventData eventData) { isDragging true; UpdateHandlePosition(eventData.position); } public void OnDrag(PointerEventData eventData) { UpdateHandlePosition(eventData.position); } public void OnEndDrag(PointerEventData eventData) { isDragging false; handleRect.anchoredPosition Vector2.zero; inputDirection Vector2.zero; } private void UpdateHandlePosition(Vector2 screenPos) { Vector2 localPos; if (RectTransformUtility.WorldToScreenPoint(Camera.main, baseRect.position, out localPos)) { Vector2 dir screenPos - localPos; float magnitude dir.magnitude; if (magnitude baseRect.rect.width * 0.5f) { dir dir.normalized * baseRect.rect.width * 0.5f; } handleRect.anchoredPosition dir; inputDirection dir.normalized; if (inputDirection.magnitude deadZone) inputDirection Vector2.zero; } } }注意OnBeginDrag中必须调用RectTransformUtility.WorldToScreenPoint转换坐标系否则在不同分辨率设备上摇杆偏移。我们测试过iPhone SE到iPad Pro全系列此方案误差控制在±2像素内。6. 动画状态机Animator避坑指南让状态切换不再“抽搐”6.1 Animator Controller结构设计为什么不用单层状态机新手常把所有动画塞进一个Controller用Bool参数控制IsRunning、IsJumping、IsAttacking。这会导致状态切换时出现“抽搐”——角色在奔跑中突然跳起腿部动画却还停留在奔跑帧。根本原因是状态机未设置Exit Time和Transition Duration。正确结构是三层嵌套Base Layer存放Idle、Run状态设置Any State到Run的过渡条件为Speed 0.1Upper Body LayerWeight 1存放Attack、Block状态设置Attack的Motion Field为Attack_Anim并勾选Write DefaultsFull Body LayerWeight 0.5存放JumpUp、JumpDown状态仅在IsGrounded false时激活关键参数所有Transition的Has Exit Time必须取消勾选Transition Duration设为0.15非默认0Interruption Source设为Current State。这样当Jump触发时Run状态会平滑过渡到JumpUp而非硬切。6.2 Sprite动画性能优化Texture Atlasing与Frame SkippingUnity 2D动画默认每帧渲染一个Sprite但12fps的奔跑动画在60fps设备上会浪费48次绘制。我们采用双缓冲策略在Animation Clip Inspector中将Sample Rate从60改为12匹配动画原始帧率为Sprite Renderer添加AnimationOptimizer.cs脚本public class AnimationOptimizer : MonoBehaviour { private SpriteRenderer sr; private Animator anim; private int lastFrameHash; void Start() { sr GetComponentSpriteRenderer(); anim GetComponentAnimator(); } void LateUpdate() { int currentHash anim.GetCurrentAnimatorStateInfo(0).fullPathHash; if (currentHash ! lastFrameHash) { sr.sprite anim.GetCurrentAnimatorClipInfo(0)[0].clip.frameRate 0 ? anim.GetCurrentAnimatorClipInfo(0)[0].clip.GetSpriteAtTime( anim.GetCurrentAnimatorStateInfo(0).normalizedTime, true) : null; lastFrameHash currentHash; } } }实测10个角色同时奔跑时GPU Draw Call从320降至187帧率提升11fps。6.3 状态参数同步解决“动画播完了脚本还没收到通知”的问题Animator的OnStateExit回调有时会丢失尤其在快速切换状态时。我们用双重保险在Animation Clip末尾帧添加Animation EventInspector底部Add Event按钮创建回调函数public void OnAnimationEnd() { // 发送事件总线消息 EventBus.Trigger(Animation.End, gameObject.name); // 同时设置脚本变量 isAttacking false; }经验Animation Event的函数名必须与脚本中方法名完全一致包括大小写且参数类型必须匹配。我们曾因把OnAnimationEnd()写成onAnimationEnd()调试3小时。7. 调试与性能分析让问题在打包前就暴露7.1 Scene视图调试神器Gizmos与Debug.DrawLine不要只依赖Console打印日志。在OnDrawGizmos中可视化关键数据void OnDrawGizmos() { // 绘制射线检测范围 Gizmos.color Color.red; Gizmos.DrawRay(transform.position, transform.right * detectDistance); // 绘制碰撞盒 if (collider2D ! null) { Gizmos.color Color.green; Gizmos.DrawWireCube(collider2D.bounds.center, collider2D.bounds.size); } // 绘制目标点 if (target ! null) { Gizmos.color Color.yellow; Gizmos.DrawSphere(target.position, 0.2f); } }效果在Scene视图中实时看到角色视野、碰撞范围、寻路目标比看坐标数字直观十倍。7.2 Profiler深度解读识别真正的性能杀手打开Window → Analysis → Profiler重点关注三栏CPU Usage展开PlayerLoop→FixedUpdate查看Rigidbody2D.Simulate耗时。若超3ms说明物理计算过载需检查Collider2D数量或Rigidbody2D质量。Rendering观察Draw Calls和Set Pass Calls。若前者高后者低说明Batching失败检查材质是否统一若后者高说明Shader复杂度过高。Memory筛选Assets查看Sprite和Texture2D内存占比。单张4K纹理在内存中占16MB4096x4096x4字节远超Android设备推荐的4MB上限。我们曾发现一个隐藏问题美术导入的PNG未勾选Generate Mip Maps但Unity在打包时自动为其生成Mip链导致内存翻倍。解决方案在Texture Importer中强制关闭Mip Maps并勾选Override for Android。7.3 构建前必检清单避免上线后才发现的致命错误每次Build前我们执行以下检查已固化为Editor脚本脚本编译检查Assets/Scripts/下所有.cs文件必须有对应.meta且guid字段不为空资源引用检查遍历所有Prefab用PrefabUtility.LoadPrefabContents()加载捕获MissingReferenceException图集尺寸检查扫描所有SpriteAtlas确保Max Size≤2048iOS或≤4096Android音频压缩检查所有AudioClip的Load Type必须为Decompress On Load短音效或Streaming背景音乐禁用Compressed In Memory权限声明检查AndroidManifest.xml中uses-permission android:nameandroid.permission.WRITE_EXTERNAL_STORAGE /仅在需要保存截图时添加否则被Google Play拒审这份清单已帮我们拦截17次上线事故最近一次是发现某个UI按钮的OnClick事件绑定了已删除的脚本打包后点击直接崩溃。8. 我的实际工作流从接到需求到提交可玩Demo的72小时最后分享一个真实案例上周策划临时提出“做个像素风青蛙跳荷叶的小游戏”要求72小时内出可玩Demo。我的执行路径如下第1-4小时环境准备创建新项目按本文第2节配置Project Settings拉取团队Git仓库的Core模块含EventBus、ObjectPool导入免费像素素材包Kenney.nl的Frogger Assets第5-12小时基础框架搭建Tilemap荷叶层与水面层配置Sorting Layer创建Frog.prefab添加Rigidbody2DDynamic、BoxCollider2D、SpriteRenderer编写FrogMovement.cs用新Input System接收方向输入第13-24小时核心玩法实现荷叶浮动动画用Lerp Mathf.Sin编写FrogJump.cs检测荷叶Collider2D实现跳跃力衰减添加SplashEffect.prefab用ObjectPool管理水花粒子第25-48小时体验打磨调整Rigidbody2D的Gravity Scale0.3让跳跃弧线更柔和为荷叶添加AudioSource跳跃时播放短促音效在UI添加分数Text用EventBus监听Frog.Landed事件第49-72小时测试与交付在真机iPhone 12、Redmi Note 10上测试触控响应用Profiler确认Draw Call≤120内存≤80MB录制30秒演示视频附上Build包与操作说明PDF最终交付物包含可安装APK/IPA、源码Git链接、操作视频、性能报告。策划当天就拿着Demo去和老板汇报了。这背后没有魔法只有对Unity 2D系统每个齿轮如何咬合的清晰认知——而这正是本文想传递给你最实在的东西。我在实际开发中发现最高效的Unity程序员往往不是代码写得最多的人而是在写第一行代码前花最多时间配置好项目骨架的人。就像盖楼地基的钢筋密度、混凝土标号、防震缝宽度决定了后续能盖多高。那些看似“绕远路”的Project Settings调整、文件夹结构设计、Sprite命名规范恰恰是让项目在三个月后依然能快速迭代、不陷入技术债泥潭的关键。如果你正站在Unity 2D开发的起点不妨先放下“马上写代码”的冲动把本文第2节的五项参数调整、第3节的PSD命名规则、第4节的Rigidbody2D约束设置一项一项亲手操作一遍。当你第一次看到角色在斜坡上平稳滑行、UI按钮精准响应、瓦片地图无缝拼接时那种“系统真正听你指挥”的掌控感会比任何炫酷特效都更让人上瘾。

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

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

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…