Unity 访问者模式(实例详解)

文章目录

访问者模式(Visitor Pattern)在Unity中主要用于封装对一个对象结构中各个元素的操作,使得可以在不改变这些元素类的前提下增加新的操作。下面我将提供五个简化版的代码实例来说明如何在C#中为Unity项目实现访问者模式:

实例1:简单的形状与统计访客

csharp 复制代码
// 抽象元素接口
public interface IShape
{
    void Accept(IVisitor visitor);
}

// 具体元素类
public class Circle : IShape
{
    public float Radius { get; set; }

    public void Accept(IVisitor visitor)
    {
        visitor.Visit(this);
    }
}

public class Square : IShape
{
    public float SideLength { get; set; }

    public void Accept(IVisitor visitor)
    {
        visitor.Visit(this);
    }
}

// 访问者接口
public interface IVisitor
{
    void Visit(Circle circle);
    void Visit(Square square);
}

// 具体访问者:面积计算器
public class AreaCalculator : IVisitor
{
    public float TotalArea { get; private set; }

    public void Visit(Circle circle)
    {
        TotalArea += Mathf.PI * circle.Radius * circle.Radius;
    }

    public void Visit(Square square)
    {
        TotalArea += square.SideLength * square.SideLength;
    }
}

// 使用示例
public class ShapeExample : MonoBehaviour
{
    public List<IShape> shapes;

    void Start()
    {
        IVisitor areaVisitor = new AreaCalculator();
        foreach (var shape in shapes)
        {
            shape.Accept(areaVisitor);
        }
        Debug.Log("Total area: " + areaVisitor.TotalArea);
    }
}

实例2:游戏对象组件访问者

csharp 复制代码
// 抽象游戏对象组件接口
public interface IGameObjectComponent
{
    void Accept(IGameObjectVisitor visitor);
}

// 具体游戏对象组件
public class TransformComponent : IGameObjectComponent
{
    public Vector3 Position { get; set; }

    public void Accept(IGameObjectVisitor visitor)
    {
        visitor.VisitTransform(this);
    }
}

public class RenderComponent : IGameObjectComponent
{
    public Material Material { get; set; }

    public void Accept(IGameObjectVisitor visitor)
    {
        visitor.VisitRender(this);
    }
}

// 访问者接口
public interface IGameObjectVisitor
{
    void VisitTransform(TransformComponent component);
    void VisitRender(RenderComponent component);
}

// 具体访问者:序列化器
public class GameObjectSerializer : IGameObjectVisitor
{
    public void VisitTransform(TransformComponent component)
    {
        // 序列化Transform组件数据
    }

    public void VisitRender(RenderComponent component)
    {
        // 序列化渲染组件数据
    }
}

// 使用示例
public class GameObjectManager : MonoBehaviour
{
    public GameObject targetObject;

    void SerializeComponents()
    {
        IGameObjectVisitor serializer = new GameObjectSerializer();
        foreach (var component in targetObject.GetComponents<IGameObjectComponent>())
        {
            component.Accept(serializer);
        }
    }
}

// ... 更多具体访问者的实现 ...

实例4:Unity场景对象遍历与清理访客

csharp 复制代码
// 抽象游戏对象接口,扩展自MonoBehaviour以适应Unity环境
public interface ISceneGameObject : MonoBehaviour
{
    void Accept(ISceneVisitor visitor);
}

// 具体的游戏对象类
public class GameObjectWithComponents : MonoBehaviour, ISceneGameObject
{
    public Transform MyTransform;
    public MeshRenderer Renderer;

    // 接受访问者
    public void Accept(ISceneVisitor visitor)
    {
        visitor.Visit(this);
    }
}

// 访问者接口
public interface ISceneVisitor
{
    void Visit(GameObjectWithComponents gameObject);
}

// 清理访客:销毁无用的MeshRenderer
public class UnusedRendererCleaner : ISceneVisitor
{
    void Visit(GameObjectWithComponents gameObject)
    {
        if (gameObject.Renderer == null || !gameObject.Renderer.enabled)
        {
            GameObject.Destroy(gameObject.Renderer);
        }
    }
}

// 使用示例
public class SceneManager : MonoBehaviour
{
    public List<ISceneGameObject> sceneObjects;

    void Start()
    {
        ISceneVisitor cleaner = new UnusedRendererCleaner();
        foreach (var obj in sceneObjects)
        {
            obj.Accept(cleaner);
        }
    }
}

// ... 更多具体访问者的实现 ...

实例5:角色行为树访问者

csharp 复制代码
// 抽象行为节点接口
public interface IBehaviorTreeNode
{
    void Accept(BehaviorTreeVisitor visitor);
    bool Evaluate();
}

// 具体的行为节点
public class MoveToTargetNode : IBehaviorTreeNode
{
    public Transform Target;
    public float DistanceThreshold;

    public void Accept(BehaviorTreeVisitor visitor) => visitor.VisitMoveToTarget(this);
    public bool Evaluate() => Vector3.Distance(transform.position, Target.position) > DistanceThreshold;
}

public class AttackEnemyNode : IBehaviorTreeNode
{
    public Transform Enemy;

    public void Accept(BehaviorTreeVisitor visitor) => visitor.VisitAttackEnemy(this);
    public bool Evaluate() => Enemy != null && Enemy.gameObject.activeSelf;
    
    // 其他评估条件...
}

// 访问者接口
public interface BehaviorTreeVisitor
{
    void VisitMoveToTarget(MoveToTargetNode node);
    void VisitAttackEnemy(AttackEnemyNode node);
    // 更多行为节点类型...
}

// 具体访问者:AI逻辑执行器
public class AIExecutor : BehaviorTreeVisitor
{
    void VisitMoveToTarget(MoveToTargetNode node)
    {
        // 执行移动到目标的行为逻辑
    }

    void VisitAttackEnemy(AttackEnemyNode node)
    {
        // 执行攻击敌人的行为逻辑
    }
    
    // 其他行为节点的处理方法...
}

// 使用示例
public class CharacterAI : MonoBehaviour
{
    public IBehaviorTreeNode rootNode;

    void Update()
    {
        var executor = new AIExecutor();
        rootNode.Accept(executor);
        if (rootNode.Evaluate())
        {
            // 根据行为树执行相应动作
        }
    }
}

以上实例展示了访问者模式在不同Unity应用场景下的灵活运用。

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

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

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

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

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


​最后我们放松一下眼睛

相关推荐
Death2001 小时前
Qt 中的 QListWidget、QTreeWidget 和 QTableWidget:简化的数据展示控件
c语言·开发语言·c++·qt·c#
Death2002 小时前
Qt 3D、QtQuick、QtQuick 3D 和 QML 的关系
c语言·c++·qt·3d·c#
yufei-coder2 小时前
C#基础语法
开发语言·c#·.net
yngsqq2 小时前
031集——文本文件按空格分行——C#学习笔记
笔记·学习·c#
新手unity自用笔记17 小时前
项目-坦克大战学习-子弹的移动与销毁
笔记·学习·c#
qinzechen18 小时前
分享几个做题网站------学习网------工具网;
java·c语言·c++·python·c#
Artistation Game19 小时前
九、怪物行为逻辑
游戏·unity·游戏引擎
百里香酚兰19 小时前
【AI学习笔记】基于Unity+DeepSeek开发的一些BUG记录&解决方案
人工智能·学习·unity·大模型·deepseek
妙为19 小时前
unreal engine5制作动作类游戏时,我们使用刀剑等武器攻击怪物或敌方单位时,发现攻击特效、伤害等没有触发
游戏·游戏引擎·虚幻·碰撞预设
yufei-coder1 天前
C# Windows 窗体开发基础
vscode·microsoft·c#·visual studio