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)


​最后我们放松一下眼睛

相关推荐
Dongwoo Jeong39 分钟前
UI架构的历史与基础入门
c#·mvc·mvvm·mvp·mvi·architecture
mascon40 分钟前
C#自定义扩展方法 及 EventHandler<TEventArgs> 委托
开发语言·c#
冰茶_5 小时前
掌握LINQ:查询语法与方法语法全解析
sql·学习·microsoft·微软·c#·linq
与火星的孩子对话5 小时前
Unity3D开发AI桌面精灵/宠物系列 【六】 人物模型 语音口型同步 LipSync 、梅尔频谱MFCC技术、支持中英文自定义编辑- 基于 C# 语言开发
人工智能·unity·c#·游戏引擎·宠物·lipsync
她说彩礼65万5 小时前
C# 中的锁
开发语言·c#
虾球xz8 小时前
游戏引擎学习第293天:移动Familiars
c++·学习·游戏引擎
敲代码的 蜡笔小新9 小时前
【行为型之访问者模式】游戏开发实战——Unity灵活数据操作与跨系统交互的架构秘诀
unity·设计模式·c#·访问者模式
明耀10 小时前
WPF C# 用WebView加载H5页面(uniapp项目,vue项目)
uni-app·c#·wpf
我不是程序猿儿14 小时前
【C#】 lock 关键字
java·开发语言·c#