Unity 中继承(父类子类)用法详解

继承 是面向对象编程(OOP)三大特性之一,在 Unity 开发中核心作用是:提取公共代码→父类 ,子类只写独有逻辑,减少重复代码、方便统一管理。

一、核心概念

复制代码
父类(基类):存放所有子类共用的变量、方法(比如怪物都有血量、移动,玩家都有受伤、升级)。
子类(派生类):继承父类后,自动拥有父类的所有非私有成员,只需写自己独有的逻辑。
关键字:: 表示继承,base 调用父类成员,override 重写父类方法。

二、基础语法(最简示例)

  1. 父类(通用脚本,挂载不挂载都行)
cpp 复制代码
using UnityEngine;

// 父类:所有角色的通用属性和行为
public class Character : MonoBehaviour
{
    // 公共变量:子类直接用
    public int hp = 100;
    public float moveSpeed = 5f;

    // 虚方法:允许子类重写(override)
    public virtual void TakeDamage(int damage)
    {
        hp -= damage;
        Debug.Log("父类:受到伤害,剩余血量:" + hp);
    }

    // 普通方法:子类直接调用,不能重写
    public void Move()
    {
        transform.Translate(Vector3.forward * moveSpeed * Time.deltaTime);
    }
}
  1. 子类(继承父类,挂载到游戏物体)
cpp 复制代码
using UnityEngine;

// 子类:玩家,继承 Character
public class Player : Character
{
    // 子类独有变量
    public int attackPower = 20;

    // 重写父类方法(独有逻辑)
    public override void TakeDamage(int damage)
    {
        // 调用父类原本的逻辑(必须写 base.方法名)
        base.TakeDamage(damage);
        
        // 子类独有逻辑:玩家受伤后闪红
        Debug.Log("子类:玩家受伤特效触发!");
    }

    // 子类独有方法
    public void Attack()
    {
        Debug.Log("玩家攻击,伤害:" + attackPower);
    }
}

三、Unity 中继承的关键规则

  1. 继承权限(必须记)

    复制代码
    父类修饰符	子类能否访问	场景面板显示	      用法
    public	      ✅ 能    ✅ 显示	         公共属性 / 方法
    protected	  ✅ 能	   ❌ 不显示	      子类专用(最常用,安全不暴露)
    private	     ❌ 不能    ❌ 不显示    	父类私有,子类完全无法访问

✅ 最佳实践:父类不想公开、但子类要用的变量 / 方法,用 protected。

  1. 方法重写(核心)

    复制代码
    父类方法加 virtual → 允许子类修改
    子类方法加 override → 重写父类逻辑
    子类中用 base.方法名() → 调用父类原本逻辑
  2. MonoBehaviour 继承规则

    复制代码
    只要父类继承了 MonoBehaviour,子类不需要重复写
    子类脚本可以直接挂载到 Unity 游戏物体上
    父类可以不挂载,子类挂载后自动拥有父类的所有功能

四、实用完整案例(Unity 怪物 / 玩家通用系统)

  1. 父类:EnemyBase(所有怪物的通用逻辑)
cpp 复制代码
using UnityEngine;

// 所有怪物的父类
public class EnemyBase : MonoBehaviour
{
    [Header("===== 通用属性 =====")]
    protected int maxHp = 50;
    protected int currentHp;
    protected float moveSpeed = 2f;

    void Start()
    {
        // 父类初始化,所有子类自动执行
        currentHp = maxHp;
        Debug.Log(gameObject.name + " 初始化完成");
    }

    // 所有怪物通用受伤逻辑
    public virtual void TakeDamage(int damage)
    {
        currentHp -= damage;
        Debug.Log("怪物受伤,剩余血量:" + currentHp);

        if (currentHp <= 0)
        {
            Die();
        }
    }

    // 通用死亡逻辑
    protected virtual void Die()
    {
        Debug.Log(gameObject.name + " 死亡");
        Destroy(gameObject);
    }

    // 通用移动
    public void MoveToTarget(Transform target)
    {
        transform.position = Vector3.MoveTowards(
            transform.position, 
            target.position, 
            moveSpeed * Time.deltaTime
        );
    }
}
  1. 子类:SlimeEnemy(史莱姆怪物,独有逻辑)
cpp 复制代码
using UnityEngine;

// 史莱姆:继承 EnemyBase
public class SlimeEnemy : EnemyBase
{
    // 子类独有属性
    private float jumpForce = 3f;

    // 重写死亡逻辑(史莱姆死亡会分裂)
    protected override void Die()
    {
        // 先执行父类死亡逻辑
        base.Die();
        // 子类独有:分裂小史莱姆
        Debug.Log("史莱姆分裂成2个小史莱姆!");
    }

    // 子类独有方法
    public void Jump()
    {
        Debug.Log("史莱姆跳跃!");
        GetComponent<Rigidbody>().AddForce(Vector3.up * jumpForce, ForceMode.Impulse);
    }
}
  1. 子类:BossEnemy(Boss 怪物,独有逻辑)
cpp 复制代码
using UnityEngine;

// Boss:继承 EnemyBase
public class BossEnemy : EnemyBase
{
    // 重写受伤逻辑(Boss受伤会狂暴)
    public override void TakeDamage(int damage)
    {
        base.TakeDamage(damage);
        
        // 独有逻辑:血量低于30% 狂暴
        if (currentHp < maxHp * 0.3f)
        {
            moveSpeed = 5f;
            Debug.Log("Boss狂暴!移速提升");
        }
    }
}

五、Unity 编辑器中的表现

复制代码
 子类脚本挂载到物体后,自动拥有父类的所有组件 / 功能
 父类的 public/[SerializeField] 变量会在 Inspector 面板显示
 修改父类代码,所有子类自动同步更新(不用逐个改)

六、常见使用场景

复制代码
UI 面板基类:所有面板共用打开 / 关闭 / 隐藏逻辑
角色系统:玩家、怪物、NPC 共用血量、受伤、移动
技能系统:所有技能共用冷却、释放、伤害计算
武器系统:剑、枪、弓 共用攻击、耐久、切换逻辑

七、避坑指南

复制代码
不要滥用继承:只有多个类有大量公共代码时才用
private 成员子类无法访问,用 protected
重写方法必须加 override,父类必须加 virtual
子类 Awake/Start 不会自动执行父类的,需要手动写 base.Awake()
一个类只能继承一个父类(C# 不支持多继承)
相关推荐
nnsix15 小时前
Unity API 兼容的 .NET Standard 2.1 和 .NET Framework 区别
unity·游戏引擎·.net
mxwin16 小时前
Unity Shader 制作半透明物体 使用多Pass提前写入深度的方式 避免穿模
unity·游戏引擎
nnsix17 小时前
Unity HybridCLR 笔记
笔记·unity·游戏引擎
nnsix19 小时前
Unity Addressables 笔记
unity·游戏引擎
RReality19 小时前
【Unity Shader URP】视差贴图 实战教程
ui·平面·unity·游戏引擎·图形渲染·贴图
小清兔1 天前
Addressable的设置打包流程
笔记·游戏·unity·c#
3D霸霸1 天前
Sourcetree 拉取新工程
数据仓库·unity
程序员正茂2 天前
Unity3d中RawImage显示视频画面偏白的解决方法
unity·视频·rawimage
mxwin2 天前
Unity SetPassCall和DrawCall的区别是什么
unity·游戏引擎·shader
电子云与长程纠缠2 天前
UE5 GameFeature创建与使用
开发语言·学习·ue5·游戏引擎