Unity 组合模式(实例详解)

发布时间:2024年01月24日


在Unity中,组合模式(Composite Pattern)是一种结构型设计模式,它允许你将对象组合成树形结构来表现“整体-部分”的层次结构,并且用户可以一致地处理单个对象和组合对象。下面我会提供三个简化的代码实例来说明组合模式在Unity中的应用:

示例1:Unity中的图形界面元素组合

// 抽象组件接口
public abstract class UIComponent
{
    public string Name { get; set; }
    
    public abstract void Render();
    public abstract void Add(UIComponent component);
    public abstract void Remove(UIComponent component);
}

// 叶子节点(具体组件)
public class UIButton : UIComponent
{
    private Texture2D buttonTexture;

    // 构造函数等...

    public override void Render()
    {
        GUI.DrawTexture(new Rect(0, 0, buttonSize.x, buttonSize.y), buttonTexture);
    }

    // 叶子节点不支持添加或删除子组件
    public override void Add(UIComponent component) {}
    public override void Remove(UIComponent component) {}
}

// 组合节点(容器组件)
public class UIMenu : UIComponent
{
    private List<UIComponent> components = new List<UIComponent>();

    public override void Render()
    {
        foreach (var component in components)
            component.Render();
    }

    public override void Add(UIComponent component)
    {
        components.Add(component);
    }

    public override void Remove(UIComponent component)
    {
        components.Remove(component);
    }
}

// 使用示例:
var menu = new UIMenu("MainMenu");
menu.Add(new UIButton("Button1"));
menu.Add(new UIButton("Button2"));

// 渲染整个菜单及其包含的所有按钮
menu.Render();

示例2:Unity中的游戏对象层级组合

// 抽象的游戏对象类
public abstract class GameObjectComposite
{
    public string Name { get; set; }
    protected List<GameObjectComposite> children = new List<GameObjectComposite>();

    public virtual void Update() 
    {
        foreach (var child in children)
            child.Update();
    }

    public void Add(GameObjectComposite obj)
    {
        children.Add(obj);
    }

    public void Remove(GameObjectComposite obj)
    {
        children.Remove(obj);
    }
}

// 具体的游戏对象叶子节点
public class GameObjectLeaf : GameObjectComposite
{
    public override void Update()
    {
        // 实现叶子节点的更新逻辑,如移动、动画播放等
    }
}

// 具体的游戏对象容器节点
public class GameObjectGroup : GameObjectComposite
{
    // 可能会有额外的方法和属性用于管理子对象
    // ...

    public override void Update()
    {
        base.Update();
        // 实现容器节点自身的更新逻辑
    }
}

// 使用示例:
var group = new GameObjectGroup("Enemies");
group.Add(new GameObjectLeaf("Enemy1"));
group.Add(new GameObjectLeaf("Enemy2"));

// 更新所有敌人
group.Update();

示例3:Unity中的场景图节点组合

// 抽象场景图节点接口
public abstract class SceneNode
{
    public string Name { get; set; }
    protected List<SceneNode>childNodes = new List<SceneNode>();

    public abstract void Draw();

    public void AddChild(SceneNode node)
    {
        childNodes.Add(node);
    }

    public void RemoveChild(SceneNode node)
    {
        childNodes.Remove(node);
    }
}

// 叶子节点:一个具体的3D模型
public class ModelNode : SceneNode
{
    public MeshRenderer Renderer { get; private set; }

    public ModelNode(MeshFilter meshFilter, MeshRenderer renderer)
    {
        Renderer = renderer;
        // 初始化其他必要组件...
    }

    public override void Draw()
    {
        Renderer.enabled = true;
        // 调用渲染方法或其他绘制逻辑
    }
}

// 容器节点:一个场景图分支
public class GroupNode : SceneNode
{
    public override void Draw()
    {
        foreach (var node in childNodes)
            node.Draw();
    }
}

// 使用示例:
var groupNode = new GroupNode("BuildingParts");
groupNode.AddChild(new ModelNode(meshFilter1, renderer1));
groupNode.AddChild(new ModelNode(meshFilter2, renderer2));

// 绘制整个建筑群
groupNode.Draw();

以上每个示例都展示了如何使用组合模式来表示一个树形结构,其中抽象基类定义了对组件进行添加、移除以及执行通用操作的方法,而叶子节点和组合节点分别实现这些方法以适应各自的具体功能。

示例4:Unity中的场景管理组合

// 抽象场景类,作为组合模式的组件基类
public abstract class SceneComposite
{
    public string Name { get; set; }
    
    protected List<SceneComposite> childScenes = new List<SceneComposite>();

    public abstract void Load();
    public abstract void Unload();

    public void AddChildScene(SceneComposite scene)
    {
        childScenes.Add(scene);
    }

    public void RemoveChildScene(SceneComposite scene)
    {
        childScenes.Remove(scene);
    }
}

// 叶子节点:具体场景
public class ConcreteScene : SceneComposite
{
    private Scene unityScene;

    public ConcreteScene(Scene scene)
    {
        unityScene = scene;
    }

    public override void Load()
    {
        SceneManager.LoadScene(unityScene, LoadSceneMode.Additive);
    }

    public override void Unload()
    {
        SceneManager.UnloadSceneAsync(unityScene);
    }
}

// 组合节点:复合场景
public class CompositeScene : SceneComposite
{
    public override void Load()
    {
        foreach (var child in childScenes)
            child.Load();
    }

    public override void Unload()
    {
        foreach (var child in childScenes.Reverse())
            child.Unload();
    }
}

// 使用示例:
var mainScene = new ConcreteScene(SceneUtility.GetSceneByPath("Assets/Scenes/Main"));
var subScene1 = new ConcreteScene(SceneUtility.GetSceneByPath("Assets/Scenes/Sub1"));
var subScene2 = new ConcreteScene(SceneUtility.GetSceneByPath("Assets/Scenes/Sub2"));

var compositeScene = new CompositeScene();
compositeScene.AddChildScene(mainScene);
compositeScene.AddChildScene(subScene1);
compositeScene.AddChildScene(subScene2);

// 加载整个复合场景
compositeScene.Load();

// 游戏流程中某个时刻卸载所有场景
compositeScene.Unload();

在以上示例中,我们创建了一个抽象场景类SceneComposite,它拥有加载和卸载的方法以及添加、移除子场景的功能。叶子节点ConcreteScene对应于Unity中的具体场景实例,它们有自己的加载和卸载逻辑。而组合节点CompositeScene则负责统一管理多个子场景,并调用它们的相应方法来实现整体加载或卸载。这种设计允许更灵活地管理和组织游戏中的场景层次结构。

示例5:Unity中的角色技能树组合

// 抽象技能类,作为组合模式的组件基类
public abstract class SkillComposite
{
    public string Name { get; set; }
    protected List<SkillComposite> childSkills = new List<SkillComposite>();

    public abstract void Use(Character character);

    public void AddChildSkill(SkillComposite skill)
    {
        childSkills.Add(skill);
    }

    public void RemoveChildSkill(SkillComposite skill)
    {
        childSkills.Remove(skill);
    }
}

// 叶子节点:具体技能
public class ConcreteSkill : SkillComposite
{
    private float damage;
    private float cooldown;

    public ConcreteSkill(string name, float damage, float cooldown)
    {
        Name = name;
        this.damage = damage;
        this.cooldown = cooldown;
    }

    public override void Use(Character character)
    {
        if (!character.IsOnCooldown(this))
        {
            character.ApplyDamage(damage);
            character.SetCooldown(this, cooldown);
        }
    }
}

// 组合节点:技能组合(例如连招)
public class ComboSkill : SkillComposite
{
    public override void Use(Character character)
    {
        foreach (var child in childSkills)
            child.Use(character);
    }
}

// 使用示例:
var punch = new ConcreteSkill("Punch", 10f, 2f);
var kick = new ConcreteSkill("Kick", 15f, 3f);
var combo = new ComboSkill();
combo.AddChildSkill(punch);
combo.AddChildSkill(kick);

// 角色使用连招技能
combo.Use(playerCharacter);

在这个示例中,我们创建了一个抽象技能类SkillComposite,它定义了技能的基本操作如使用方法以及添加和移除子技能的方法。叶子节点ConcreteSkill代表具体的单个技能,它们有自己的伤害值、冷却时间及使用逻辑。而组合节点ComboSkill则是一个由多个子技能组成的连招,当调用其Use方法时,会依次触发所有子技能的效果。

这种设计模式在游戏开发中非常有用,比如构建角色技能树系统,玩家可以根据自己的策略自由组合不同的技能来形成独特的连招或战术。

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

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

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

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

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

?最后我们放松一下眼睛
在这里插入图片描述

文章来源:https://blog.csdn.net/qqrrjj2011/article/details/135814770
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。