Unity代理模式

在游戏开发中,技能系统几乎是绕不开的核心模块

一开始我们可能只关心技能能不能放出来,但随着功能增加,问题也会接踵而至:

冷却时间、耗蓝、公共CD、网络校验、AI复用......

如果把这些逻辑全部堆在技能本体或者玩家脚本里,代码很快就会变得又长又乱,后期几乎无法维护。

本篇文章将通过一个简单但非常实用的 Unity 示例,演示如何使用**代理模式(Proxy Pattern)**来解耦技能本体与技能规则,让玩家只关心"释放技能",而不必关心技能背后复杂的限制逻辑。

1.技能接口定义

cs 复制代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public interface ISkill
{
    void Cast();
}

2.具体的技能

cs 复制代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

// 火球技能
public class FireBallSkill : ISkill
{
    public void Cast()
    {
        Debug.Log("释放火球术!");
    }
}

// 分身术技能
public class CloneSkill : ISkill
{
    public void Cast()
    {
        Debug.Log("释放分身术!");
    }
}

// 治疗技能
public class HealSkill : ISkill
{
    public void Cast()
    {
        Debug.Log("释放治疗术!");
    }
}

3.技能释放代理

玩家只需要调用代理中提供的Cast()方法,其他的玩家都不用关心。

cs 复制代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SkillCooldownProxy : ISkill
{
    private ISkill realSkill;

    private float cooldownTime = 3f;   // 冷却时长
    private float lastCastTime = -999f;//防止刚进入游戏无法释放技能

    public SkillCooldownProxy(ISkill skill)
    {
        realSkill = skill;
    }

    public void Cast()
    {
        if (Time.time - lastCastTime < cooldownTime)
        {
            Debug.Log("技能冷却中...");
            return;
        }

        lastCastTime = Time.time;

        realSkill.Cast();

        Debug.Log("技能释放");
    }
}

4.玩家调用

玩家只知道要释放技能,释放技能的冷却或者耗蓝这些他都不用关心,比如后面要制作AI或者敌人的时候就可以直接将代理进行组合排列。

cs 复制代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerInput : MonoBehaviour
{
    private ISkill fireBall;
    private ISkill FenshenShu;

    void Start()
    {
        // 注意这里:玩家拿到的是"代理"
        fireBall = new SkillCooldownProxy(new FireBallSkill());
        FenshenShu = new SkillCooldownProxy(new CloneSkill());
    }

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Q))
        {
            fireBall.Cast();
        }
        if (Input.GetKeyDown(KeyCode.E))
        {
            FenshenShu.Cast();
        }
    }
}

5.运行结果

将PlayerInput加到场景中的一个空对象上,然后运行游戏按下Q键,发现成功打印了火球释放,连续按下会提示技能正在冷却。

6.总结

技能本体只负责"技能做什么",

代理类负责"技能能不能做"。

当后期需求增加时,比如:

  • 技能耗蓝

  • 公共 CD

  • 网络校验

  • AI 自动释放限制

我们只需要新增对应的代理,而无需修改原有技能代码,甚至可以像搭积木一样对代理进行组合。

相关推荐
玖玥拾8 小时前
Unity Shader 基础与图形学(一)
unity·图形渲染·图形学·shader
WiChP16 小时前
【V0.1B16】从零开始的2D游戏引擎开发之路
开发语言·算法·游戏引擎
百里香酚兰17 小时前
【Unity学习笔记】如何把粉色Prefab还原
笔记·学习·unity
xcLeigh19 小时前
Unity基础:使用Transform控制物体旋转——Rotate与LookAt详解
unity·教程·transform·rotate·lookat
平行云21 小时前
3D应用推流太贵太慢?ImmerShare Lite:利用本地算力实现极简一键分享
unity·ue5·实时云渲染·云桌面·像素流·云游戏·串流
淡海水1 天前
11-04-Unity-Span-foreach-LINQ的分配与热路径边界
unity·c#·linq·foreach·span
狂人开飞机1 天前
23、实战平台跳跃游戏
游戏·游戏引擎·godot
灸木2 天前
Unity 多线程与并发:什么时候该用多线程?
unity
淡海水2 天前
11-02-Unity-Mono-vs-IL2CPP-两种脚本后端的数据结构行为差异
数据结构·unity·游戏引擎·il2cpp·mono
彧azz2 天前
初学Unity:编辑器
笔记·学习·unity·游戏引擎