Unity 命令模式(实例详解)

文章目录

在Unity中使用命令模式(Command Pattern)是一种常见的设计模式,用于实现对游戏或应用中一系列动作的记录、撤销和重做操作。下面通过五个简化的C#代码示例来详细说明命令模式在Unity中的应用:

示例1:基础命令类结构

csharp 复制代码
// 基础命令接口
public interface ICommand
{
    void Execute();
    void Undo();
}

// 具体命令类 - 例如移动角色命令
public class MoveCharacterCommand : ICommand
{
    private readonly Transform _character;
    private Vector3 _previousPosition;

    public MoveCharacterCommand(Transform character, Vector3 newPosition)
    {
        _character = character;
        _previousPosition = character.position;
    }

    public void Execute()
    {
        _character.position = newPosition; // 假设newPosition是目标位置
    }

    public void Undo()
    {
        _character.position = _previousPosition;
    }
}

// 命令管理器类,负责执行和回滚命令
public class CommandManager
{
    private List<ICommand> _commandHistory = new List<ICommand>();

    public void ExecuteCommand(ICommand command)
    {
        command.Execute();
        _commandHistory.Add(command);
    }

    public void UndoLastCommand()
    {
        if (_commandHistory.Count > 0)
        {
            var lastCommand = _commandHistory[_commandHistory.Count - 1];
            lastCommand.Undo();
            _commandHistory.RemoveAt(_commandHistory.Count - 1);
        }
    }
}

示例2:旋转对象命令

csharp 复制代码
public class RotateObjectCommand : ICommand
{
    private readonly Transform _target;
    private Quaternion _originalRotation;

    public RotateObjectCommand(Transform target, Quaternion newRotation)
    {
        _target = target;
        _originalRotation = target.rotation;
    }

    public void Execute()
    {
        _target.rotation = newRotation;
    }

    public void Undo()
    {
        _target.rotation = _originalRotation;
    }
}

// 使用:
var rotateCmd = new RotateObjectCommand(someGameObject.transform, Quaternion.Euler(0, 90, 0));
commandManager.ExecuteCommand(rotateCmd);

示例3:增加道具命令

csharp 复制代码
public class AddInventoryItemCommand : ICommand
{
    private readonly PlayerInventory _inventory;
    private readonly Item _itemToAdd;
    private bool _wasAdded;

    public AddInventoryItemCommand(PlayerInventory inventory, Item item)
    {
        _inventory = inventory;
        _itemToAdd = item;
    }

    public void Execute()
    {
        _wasAdded = _inventory.AddItem(_itemToAdd);
    }

    public void Undo()
    {
        if (_wasAdded)
        {
            _inventory.RemoveItem(_itemToAdd);
        }
    }
}

// 使用:
var addItemCmd = new AddInventoryItemCommand(player.Inventory, newItem);
commandManager.ExecuteCommand(addItemCmd);

示例4:切换场景命令

csharp 复制代码
public class ChangeSceneCommand : ICommand
{
    private readonly string _sceneName;
    private readonly Scene _previousScene;

    public ChangeSceneCommand(Scene currentScene, string newSceneName)
    {
        _sceneName = newSceneName;
        _previousScene = currentScene;
    }

    public void Execute()
    {
        SceneManager.LoadScene(_sceneName);
    }

    public void Undo()
    {
        SceneManager.LoadScene(_previousScene.name);
    }
}

// 使用(假设有一个SceneManager实例提供加载场景的方法)
var changeSceneCmd = new ChangeSceneCommand(SceneManager.GetActiveScene(), "NextScene");
commandManager.ExecuteCommand(changeSceneCmd);

示例5:播放音效命令

csharp 复制代码
public class PlaySoundCommand : ICommand
{
    private readonly AudioSource _audioSource;
    private AudioClip _previousClip;
    private float _previousTime;

    public PlaySoundCommand(AudioSource audioSource, AudioClip clipToPlay)
    {
        _audioSource = audioSource;
        if (_audioSource.isPlaying)
        {
            _previousClip = _audioSource.clip;
            _previousTime = _audioSource.time;
        }
    }

    public void Execute()
    {
        _audioSource.clip = clipToPlay;
        _audioSource.Play();
    }

    public void Undo()
    {
        if (_previousClip != null)
        {
            _audioSource.clip = _previousClip;
            _audioSource.time = _previousTime;
            if (_audioSource.isPlaying)
            {
                _audioSource.Pause();
            }
        }
    }
}

// 使用:
var playSoundCmd = new PlaySoundCommand(someAudioSource, newSoundClip);
commandManager.ExecuteCommand(playSoundCmd);

这些示例展示了如何定义不同的命令,并且每个命令都实现了ICommand接口以确保它们都能执行和撤销操作。在实际项目中,命令管理器会存储这些命令并根据需要执行撤销/重做功能。

python推荐学习汇总连接:
50个开发必备的Python经典脚本(1-10)

50个开发必备的Python经典脚本(11-20)

50个开发必备的Python经典脚本(21-30)

50个开发必备的Python经典脚本(31-40)

50个开发必备的Python经典脚本(41-50)


​最后我们放松一下眼睛

相关推荐
Aman19843 小时前
Claude Code做Unity项目移植(二): 自动执行只读操作,告别频繁的
unity·游戏开发·vibe coding·claude code
泛凡(Linyongui)10 小时前
基于 CW32L010 的智能厨卫调温旋钮方案--低成本 EC21 编码旋钮全解析
单片机·嵌入式硬件·c#
暴走约伯12 小时前
【VFX工具链源码拆解 02】告别机械劳动(上):一键统改百个子粒子颜色与批量重命名
3d·unity·c#·材质
郝学胜-神的一滴13 小时前
游戏设计:原型与开发 18:Unity入门的第一课
人工智能·程序人生·游戏·ui·unity·游戏引擎
信息安全失业大专人员13 小时前
每日了解一个智能体-WorkBuddy
开发语言·ai·c#·智能体
呆呆敲代码的小Y14 小时前
【实战精选面试题】C# 面试题详细解答,按难易程度排序
android·java·游戏·c#·游戏开发·unity面试题·c#面试题
淡海水15 小时前
09-01-内存-Unity资源生命周期全景
unity·c#·游戏引擎·.netcore·gc
椒颜皮皮虾྅18 小时前
让 C# 读懂整张图:DeploySharp 驱动 PaddleOCR v4/v5/v6,打通 OCR 全流程
开发语言·人工智能·深度学习·学习·c#·ocr·cuda
昂好的day18 小时前
C# 同步异步与多线程:Thread / Task / 线程池一次讲透(上篇)
开发语言·windows·c#
LF男男18 小时前
Flower Defense—UIFacade
unity