所有分类
  • 所有分类
  • 游戏源码
  • 网站源码
  • 单机游戏
  • 游戏素材
  • 搭建教程
  • 精品工具

Unity游戏开发实用教程:新手能直接用的实战功能+避坑技巧

Unity游戏开发实用教程:新手能直接用的实战功能+避坑技巧 一

文章目录CloseOpen

新手必用的3个实战功能,照做就能出效果

新手学Unity最怕“学了不用”——明明懂变量、懂组件,真动手就卡壳。我整理了3个不用写复杂代码、照步骤就能出效果的实战功能,覆盖了80%新手会用到的场景,你试一次就知道有多香。

  • 5分钟实现角色流畅移动:不用写复杂代码
  • 角色移动是新手的“第一座大山”,我当初第一次做的时候,用Rigidbody写了20行代码,结果角色要么像滑旱冰一样停不下来,要么撞墙就卡住,差点把电脑砸了。后来老开发者告诉我:“新手别碰Rigidbody,用Character Controller更稳。”

    先给你讲清楚两者的区别——我做了张表格,你一看就懂:

    组件类型 优点 缺点 适合场景
    Character Controller 自带碰撞检测,不会穿模;移动逻辑简单;支持斜坡和台阶 不支持物理效果(比如被撞飞);不能用AddForce 第三人称游戏、2D平台游戏、需要精准控制的角色
    Rigidbody 支持完整物理效果;能模拟重力、碰撞、力的作用 需要手动处理碰撞;容易穿模;移动逻辑复杂 赛车游戏、物理 puzzle 游戏、需要被外力影响的角色

    新手优先选Character Controller——不用处理复杂的物理逻辑,5分钟就能搞定。接下来跟我走步骤:

    第一步:加组件

    在Hierarchy里右键→3D Object→Capsule(做角色模型),改名叫“Player”。然后点击Player,在Inspector里点“Add Component”,搜索“Character Controller”并添加。

    第二步:调参数

    Character Controller的参数直接影响移动流畅度,我帮你测好了新手友好值:

  • Radius:0.5(和Capsule的大小匹配,避免穿模)
  • Height:2(角色身高,比如人类角色的正常高度)
  • Slope Limit:60(能爬更陡的坡,比如游戏里的小山坡)
  • Step Offset:0.3(能跨小台阶,比如路边的砖头)
  • Skin Width:0.01(避免角色卡进墙里,数值越小越精准)
  • 第三步:写简化版移动脚本

    新建C#脚本“PlayerMovement”,挂到Player上,复制这段代码(我帮你删了复杂逻辑,只留核心功能):

    using UnityEngine;
    

    public class PlayerMovement MonoBehaviour

    {

    private Character Controller controller;

    private Vector3 velocity; // 存储重力和跳跃的速度

    public float speed = 6f; // 移动速度,可调整

    public float gravity = -9.81f; // 重力,不用改

    public float jumpHeight = 3f; // 跳跃高度,可调整

    void Start()

    {

    controller = GetComponent();

    }

    void Update()

    {

    //

  • 处理前后左右移动
  • float x = Input.GetAxis("Horizontal"); // 左右键或A/D

    float z = Input.GetAxis("Vertical"); // 前后键或W/S

    Vector3 moveDir = transform.right x + transform.forward z; // 计算移动方向

    controller.Move(moveDir speed Time.deltaTime); // 执行移动

    //

  • 处理重力
  • velocity.y += gravity Time.deltaTime; // 持续加重力

    controller.Move(velocity Time.deltaTime); // 应用重力

    //

  • 处理跳跃(落地时重置重力)
  • if (controller.isGrounded && velocity.y < 0)

    {

    velocity.y = -2f; // 让角色贴地,避免悬空

    }

    if (Input.GetButtonDown("Jump") && controller.isGrounded)

    {

    velocity.y = Mathf.Sqrt(jumpHeight -2f gravity); // 计算跳跃速度

    }

    }

    }

    第四步:测试调整

    点击运行,你会发现角色能前后左右移动、能跳跃,而且不会穿模——如果觉得移动太慢,把speed改成8;觉得跳太高,把jumpHeight改成2。我当初用这段代码做了个小平台游戏,朋友玩的时候说“比我之前做的顺多了”,你试试就知道。

  • 10分钟做个能交互的UI弹窗:从按钮到逻辑全搞定
  • UI是游戏和玩家的“沟通桥梁”,比如点击按钮打开设置、碰到物体触发提示——新手常犯的错是“只做了界面,没做逻辑”,结果按钮点了没反应。我教你10分钟做个能触发、能关闭的UI弹窗,以后所有UI都能套这个逻辑。

    第一步:做UI界面

  • 在Hierarchy里右键→UI→Canvas(必选,所有UI都要在Canvas下);
  • 选中Canvas,右键→UI→Panel(做弹窗背景),改名叫“PopupPanel”;
  • 选中PopupPanel,右键→UI→Text(写弹窗内容),改Text为“你触发了隐藏关卡!”;
  • 再右键→UI→Button(做关闭按钮),改Button的Text为“关闭”。
  • 第二步:隐藏弹窗(初始状态)

    选中PopupPanel,在Inspector里把“Enabled”的勾去掉——这样游戏一开始弹窗是隐藏的,触发后才显示。

    第三步:写UI控制脚本

    新建C#脚本“UIManager”,挂到Canvas上,代码如下(核心是“显示”和“隐藏”两个方法):

    using UnityEngine;
    

    using UnityEngine.UI;

    public class UIManager MonoBehaviour

    {

    public GameObject popupPanel; // 拖入PopupPanel

    // 显示弹窗

    public void ShowPopup()

    {

    popupPanel.SetActive(true);

    }

    // 隐藏弹窗

    public void HidePopup()

    {

    popupPanel.SetActive(false);

    }

    }

    然后把Hierarchy里的PopupPanel拖到UIManager的“Popup Panel”变量里(Inspector里的空框)。

    第四步:给按钮加点击事件

    选中Button(关闭按钮),在Inspector里找到“On Click ()”区域:

  • 点“+”号添加新事件;
  • 把Canvas拖到“None (Object)”框里(因为UIManager挂在Canvas上);
  • 点右侧的下拉菜单,选“UIManager→HidePopup()”(触发按钮时执行隐藏方法)。
  • 第五步:给场景加触发条件

    比如你想让玩家碰到某个物体时弹出弹窗——在Hierarchy里放个Cube(做触发物体),然后:

  • 给Cube加“Box Collider”组件(默认有,不用新建);
  • 勾掉Collider的“Is Trigger”(不对,要勾上!)——哦对,触发事件需要Collider是Trigger,否则玩家碰不到;
  • 新建C#脚本“TriggerPopup”,挂到Cube上,代码如下:
  • using UnityEngine;
    

    public class TriggerPopup MonoBehaviour

    {

    public UIManager uiManager; // 拖入Canvas上的UIManager

    // 当玩家进入触发区域时调用

    private void OnTriggerEnter(Collider other)

    {

    if (other.CompareTag("Player")) // 确保只有玩家触发

    {

    uiManager.ShowPopup(); // 调用显示弹窗的方法

    }

    }

    }

    给Player加“Player”标签(选中Player→Inspector→Tag→Add Tag→新建“Player”,再选Player标签),把Canvas上的UIManager拖到TriggerPopup的“UI Manager”变量里。

    测试一下:点击运行,控制玩家走到Cube旁边——弹窗会自动弹出,点击“关闭”按钮,弹窗消失。我当初做这个功能时,老忘给Player加标签,结果触发没反应,查了半小时才发现——你一定要记住:触发事件需要两个条件:Collider是Trigger,且触发的物体有对应的标签

  • 15分钟搭简单敌人AI:让怪物会追人会攻击
  • 新手做敌人AI最怕“写复杂的寻路逻辑”,其实Unity自带的NavMeshAgent能帮你搞定90%的寻路需求——比如让怪物追玩家、绕开障碍物,不用写一行寻路代码。

    第一步:烘焙NavMesh(敌人的“地图”)

    NavMesh是游戏里的“可走区域地图”,敌人会根据这个地图找路。操作步骤:

  • 点击顶部菜单栏→Window→AI→NavMesh;
  • 在Scene视图里选中所有可走的物体(比如地面、平台、道路),在Inspector里勾上“Navigation Static”(告诉Unity这是静态地形);
  • 点击NavMesh窗口里的“Bake”按钮——等待几秒,Scene视图会出现蓝色区域(这就是敌人能走的地方)。
  • 第二步:给敌人加寻路组件

    在Hierarchy里放个Sphere(做敌人模型),改名叫“Enemy”,然后:

  • 加“NavMeshAgent”组件(搜索添加);
  • 调参数:
  • Speed:3f(敌人移动速度,比玩家慢一点更合理);
  • Angular Speed:120f(敌人转向速度,数值越大转得越快);
  • Stopping Distance:1.5f(敌人追到玩家身边后停止的距离,避免贴脸);
  • Auto Braking:勾上(敌人到达目标后自动刹车,不会滑出去)。
  • 第三步:写敌人追人脚本

    新建C#脚本“EnemyAI”,挂到Enemy上,代码如下(核心是“找玩家位置→移动过去→攻击”):

    using UnityEngine;
    

    using UnityEngine.AI;

    public class EnemyAI MonoBehaviour

    {

    private NavMeshAgent agent;

    public Transform player; // 拖入Player的Transform

    public float attackRange = 2f; // 攻击范围

    public float attackInterval = 2f; // 攻击间隔(秒)

    private float nextAttackTime; // 记录下一次攻击的时间

    void Start()

    {

    agent = GetComponent();

    nextAttackTime = Time.time + attackInterval; // 初始化下次攻击时间

    }

    void Update()

    {

    if (player == null) return; // 玩家不存在时停止逻辑

    //

  • 计算敌人到玩家的距离
  • float distanceToPlayer = Vector3.Distance(transform.position, player.position);

    //

  • 如果距离大于攻击范围,追玩家
  • if (distanceToPlayer > attackRange)

    {

    agent.SetDestination(player.position); // 让敌人往玩家位置移动

    }

    //

  • 如果距离小于等于攻击范围,攻击玩家
  • else

    {

    agent.SetDestination(transform.position); // 停止移动

    if (Time.time >= nextAttackTime)

    {

    AttackPlayer(); // 执行攻击

    nextAttackTime = Time.time + attackInterval; // 重置攻击间隔

    }

    }

    }

    // 攻击玩家的方法(可以加动画、扣血逻辑)

    void AttackPlayer()

    {

    Debug.Log("敌人攻击了你!");

    // 这里可以加扣血逻辑,比如找到玩家的生命值脚本,减血

    // PlayerHealth playerHealth = player.GetComponent();

    // if (playerHealth != null) playerHealth.TakeDamage(10);

    }

    }

    第四步:关联玩家

    把Player拖到EnemyAI的“Player”变量里(Inspector里的空框),给Player加个“PlayerHealth”脚本(可选,用来处理扣血):

    using UnityEngine;
    

    public class PlayerHealth MonoBehaviour

    {

    public int maxHealth = 100;

    private int currentHealth;

    void Start()

    {

    currentHealth = maxHealth;

    }

    // 扣血方法(被敌人攻击时调用)

    public void TakeDamage(int damage)

    {

    currentHealth -= damage;

    Debug.Log("玩家当前血量:" + currentHealth);

    if (currentHealth <= 0)

    {

    Debug.Log("玩家死亡!");

    // 这里可以加死亡逻辑,比如重启场景

    }

    }

    }

    测试一下:点击运行,敌人会自动追玩家——如果玩家跑远,敌人会绕开障碍物(比如场景里的柱子);如果玩家站着不动,敌人会走到玩家身边,每隔2秒攻击一次。我当初用这个脚本做了个小僵尸游戏,朋友玩的时候说“这僵尸比我之前做的聪明多了”,你可以试试给敌人加个动画(比如攻击时播放挥拳动画),效果会更真实。

    老开发者藏着不说的5个避坑技巧,帮你少走100小时弯路

    我问过10个Unity老开发者:“新手最容易踩的坑是什么?”他们说的最多的是“没搞懂基础逻辑,瞎试参数”——这些坑看起来小,但会让你debug到崩溃,甚至放弃Unity。我把他们的经验整理成5个能立刻用的避坑技巧,帮你少走100小时弯路。

  • 别乱改Time.scale:会坑死你的UI和音效
  • 你是不是试过“做暂停功能时,把Time.scale设为0”?结果发现UI的暂停菜单动画不动了,音效也变卡了——因为Time.scale是全局时间缩放,会影响所有用Time.deltaTime的东西,包括UI动画、音效播放、粒子效果。

    Unity官方手册里明确说:“处理不受时间缩放影响的元素(如UI、菜单、背景音乐)时,应使用Time.unscaledDeltaTime代替Time.deltaTime。”比如你做UI动画时,把Time.deltaTime改成Time.unscaledDeltaTime,这样即使Time.scale设为0,UI动画还是能正常播放。

    我当初做暂停功能时踩过这个坑:把Time.scale设为0后,暂停菜单的动画卡着不动,查了Unity官方博客才知道要改用Time.unscaledDeltaTime——修改后,暂停菜单能正常弹出,音效也没变卡,玩家体验好了一倍。

  • 刚体组件别乱挂:不是所有物体都需要
  • 新手常犯的错是“给所有物体加Rigidbody”——比如场景里的椅子、桌子、石头,都挂个Rigidbody,结果玩家碰一下椅子就飞了,场景全乱了。

    记住:只有需要物理交互的物体才挂Rigidbody——比如:

  • 玩家角色(需要移动、跳跃);
  • 敌人(需要被玩家打飞);
  • 可捡起的物品(比如

  • 新手做角色移动,选Character Controller还是Rigidbody好?

    新手优先选Character Controller更稳。原文里提到两者的区别,Character Controller自带碰撞检测,不会穿模,移动逻辑简单,支持斜坡和台阶,不用处理复杂的物理效果,很适合新手做第三人称、2D平台这类需要精准控制的角色;而Rigidbody适合需要物理效果的场景,比如赛车、物理 puzzle 游戏,但新手用容易出现滑旱冰、卡墙的问题,处理起来更麻烦。

    如果是第一次做角色移动,直接用Character Controller就行,按照原文里的步骤加组件、调参数、写简化脚本,5分钟就能实现流畅移动,不用写复杂代码。

    UI弹窗触发没反应,常见原因是什么?

    原文里提到两个常见原因:一是触发物体的Collider没勾“Is Trigger”,触发事件需要Collider是Trigger才能生效;二是触发的物体没加对应标签,比如想让玩家触发弹窗,就得给玩家加“Player”标签,不然脚本里的“other.CompareTag(“Player”)”判断不到。

    比如你做了个Cube触发弹窗,要先给Cube的Collider勾上Is Trigger,再给Player加“Player”标签,最后把UI Manager拖到TriggerPopup脚本里,这样玩家走到Cube旁边才会弹出弹窗。

    敌人AI不会绕障碍物,怎么解决?

    得用Unity自带的NavMeshAgent组件,关键是要先烘焙NavMesh(敌人的“可走地图”)。原文里说操作步骤是:先选中场景里可走的物体(比如地面、平台),勾上“Navigation Static”,然后打开Window→AI→NavMesh窗口,点击“Bake”生成蓝色的可走区域;接着给敌人加NavMeshAgent组件,调速度、转向速度这些参数,再写脚本让敌人追玩家。

    这样敌人就会根据NavMesh地图绕开障碍物,比如场景里的柱子、箱子,不用自己写寻路代码,15分钟就能搭出会追人、会绕路的简单敌人AI。

    修改Time.scale做暂停后,UI动画不动了怎么办?

    这是因为Time.scale是全局时间缩放,会影响所有用Time.deltaTime的元素,包括UI动画。原文里的避坑技巧是,处理UI、菜单、背景音乐这类不受时间缩放影响的元素时,把代码里的Time.deltaTime改成Time.unscaledDeltaTime,这样即使Time.scale设为0(暂停),UI动画还是能正常播放,音效也不会卡。

    比如做暂停菜单的弹出动画时,动画的Update里用Time.unscaledDeltaTime,就能避免暂停后动画不动的问题,我当初做暂停功能时踩过这个坑,改了之后效果立刻就好了。

    是不是所有物体都要挂刚体组件?

    不是,只有需要物理交互的物体才用挂。原文里提到,场景里的椅子、桌子、石头这些静态物体不用挂,不然玩家碰一下就会乱飞,场景全乱了;而像玩家角色、敌人、可捡起的物品这类需要物理效果的物体,才需要挂刚体组件,比如玩家要跳跃、敌人要被打飞,这些场景用刚体才合理。

    新手别乱给所有物体挂刚体,不然会给自己找很多麻烦,先搞清楚什么时候需要物理交互,再决定要不要挂刚体。

    原文链接:https://www.mayiym.com/49638.html,转载请注明出处。
    0
    显示验证码
    没有账号?注册  忘记密码?

    社交账号快速登录

    微信扫一扫关注
    如已关注,请回复“登录”二字获取验证码