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)


​最后我们放松一下眼睛

相关推荐
IMPYLH1 小时前
Lua 的 Coroutine(协程)模块
开发语言·笔记·后端·中间件·游戏引擎·lua
用户4488466710605 小时前
.NET进阶——深入理解Lambda表达式(2)手搓LINQ语句
c#·.net
云中飞鸿10 小时前
wpf 类图
c#
世洋Blog11 小时前
SiYangUnityEventSystem,一个Unity中的事件系统
观察者模式·unity·c#·游戏引擎·事件系统
呆呆敲代码的小Y11 小时前
【Unity实战篇】| 游戏滑动框添加特殊效果,如实时高亮显示、曲线滑动等
游戏·unity·游戏引擎·实战·u3d·免费游戏·unity实战技巧
切糕师学AI11 小时前
如何用 VS Code + C# Dev Kit 创建类库项目并在主项目中引用它?
开发语言·c#
Tatalaluola12 小时前
【Quest开发】用unity UI快速实现交互
unity·游戏引擎
技术小甜甜12 小时前
[Godot] 在 Godot 3.1 中配置 ADB 可执行文件的实用指南
游戏·adb·游戏引擎·godot
William_cl12 小时前
【CSDN 专栏】C# ASP.NET控制器过滤器:自定义 ActionFilterAttribute 实战(避坑 + 图解)
c#·asp.net·状态模式
William_cl12 小时前
【CSDN 专栏】C# ASP.NET Razor 视图引擎实战:.cshtml 从入门到避坑(图解 + 案例)
开发语言·c#·asp.net