Unity 设计模式-策略模式(Strategy Pattern)详解

策略模式(Strategy Pattern)是一种行为型设计模式,定义了一系列算法,并将每种算法封装到独立的类中,使得它们可以互相替换。策略模式让算法可以在不影响客户端的情况下独立变化,客户端通过与这些策略对象进行交互来执行不同的行为。

在策略模式中,核心思想是将算法的定义和使用分离,使得不同的策略(算法)可以灵活地切换,符合面向对象设计中的开闭原则,即对扩展开放、对修改关闭。

策略模式的结构

  • 策略接口(Strategy Interface):定义所有策略的共同行为,这通常是一个抽象类或接口。
  • 具体策略类(Concrete Strategy):实现策略接口的具体算法。
  • 上下文类(Context Class):维护对某个策略对象的引用,并提供对客户端的接口,允许客户端调用策略算法。

适用场景

  • 避免使用难以维护的多重条件选择语句
  • 当策略中有较为复杂的数据结构或者算法不需要暴露在客户端或者其他时。

在 Unity 中使用 策略模式

在 Unity 中使用策略模式的一个典型应用场景是为游戏角色定义不同的移动方式,例如:走路、跑步、跳跃等。在游戏开发中,不同的角色可能有不同的移动方式。通过策略模式,我们可以将这些不同的移动逻辑封装到独立的策略类中,并动态切换角色的移动方式。

1、通过策略模式实现角色的移动

(1) 定义策略接口

首先定义一个策略接口 IMoveStrategy,它规定所有移动策略都必须实现一个 Move() 方法。

cs 复制代码
public interface IMoveStrategy
{
    void Move(Transform characterTransform);
}

(2) 定义具体策略类

创建几个具体的移动策略类 WalkStrategyRunStrategyJumpStrategy,分别实现不同的移动行为。

cs 复制代码
using UnityEngine;
 
// 走路策略
public class WalkStrategy : IMoveStrategy
{
    public void Move(Transform characterTransform)
    {
        characterTransform.Translate(Vector3.forward * 2f * Time.deltaTime);
        Debug.Log("Character is walking.");
    }
}
 
// 跑步策略
public class RunStrategy : IMoveStrategy
{
    public void Move(Transform characterTransform)
    {
        characterTransform.Translate(Vector3.forward * 5f * Time.deltaTime);
        Debug.Log("Character is running.");
    }
}
 
// 跳跃策略
public class JumpStrategy : IMoveStrategy
{
    public void Move(Transform characterTransform)
    {
        characterTransform.Translate(Vector3.up * 5f * Time.deltaTime);
        Debug.Log("Character is jumping.");
    }
}

(3) 定义上下文类

Character 类作为上下文类,负责维护当前的移动策略,并提供方法来设置不同的移动策略和执行移动操作。

cs 复制代码
using UnityEngine;
 
public class Character : MonoBehaviour
{
    private IMoveStrategy moveStrategy;
 
    // 设置移动策略
    public void SetMoveStrategy(IMoveStrategy strategy)
    {
        moveStrategy = strategy;
    }
 
    // 执行移动
    public void PerformMove()
    {
        if (moveStrategy != null)
        {
            moveStrategy.Move(transform);
        }
        else
        {
            Debug.LogWarning("Move strategy not set!");
        }
    }
}

(4) 客户端代码

GameController 中,我们实例化角色,并动态设置和切换移动策略。

cs 复制代码
using UnityEngine;
 
public class GameController : MonoBehaviour
{
    private Character character;
 
    void Start()
    {
        // 创建角色
        character = gameObject.AddComponent<Character>();
 
        // 初始化为走路策略
        character.SetMoveStrategy(new WalkStrategy());
    }
 
    void Update()
    {
        // 执行移动
        character.PerformMove();
 
        // 根据输入切换策略
        if (Input.GetKeyDown(KeyCode.W))
        {
            character.SetMoveStrategy(new WalkStrategy());
        }
        else if (Input.GetKeyDown(KeyCode.R))
        {
            character.SetMoveStrategy(new RunStrategy());
        }
        else if (Input.GetKeyDown(KeyCode.Space))
        {
            character.SetMoveStrategy(new JumpStrategy());
        }
    }
}

示例解释

  • WalkStrategy:角色以较慢的速度向前移动,模拟走路的行为。
  • RunStrategy:角色以较快的速度向前移动,模拟跑步的行为。
  • JumpStrategy:角色向上跳跃,模拟跳跃的行为。

在 GameController 中,使用键盘输入(W 键、R 键和空格键)来动态切换角色的移动策略。按下相应的键后,角色将切换到走路、跑步或跳跃模式。

通过策略模式,角色的移动方式可以灵活切换,而不需要修改任何核心代码。

策略模式 在 Unity 中的优势是可以动态切换角色行为,如移动、攻击等。通过将不同的移动方式封装到独立的类中,我们可以更方便地扩展系统,并根据游戏需求随时切换策略。

2、通过策略模式实现修改图片的颜色

(1)定义策略接口

首先定义一个抽象类或接口ChangeColor,并且声明一个image参数和ExChangeColor的虚方法

cs 复制代码
using UnityEngine.UI;
public abstract class ChangeColor 
{
    public Image img;
    public virtual void ExChangeColor() { }
}

(2)定义具体策略类

然后创建几个具体的策略类,ChangeColor和ChangeBlue,分别用来改变不同颜色

cs 复制代码
//修改图片颜色为红色
using UnityEngine;
public class ChangeRed : ChangeColor
{
    public override void ExChangeColor()
    {
        img.color = Color.red;
    }
}

-------------------
//修改图片颜色为蓝色
using UnityEngine;
public class ChangeBlue : ChangeColor
{
    public override void ExChangeColor()
    {
        img.color = Color.blue;
    }
}

(3)定义上下文类

维护对strategy 对象的引用,并提供方法来设置不同的操作

cs 复制代码
using UnityEngine.UI;
public class StategyContext 
{
    ChangeColor strategy;
    public StategyContext(ChangeColor strategy,Image img)
    {
        this.strategy = strategy;
        this.strategy.img = img;
    }

    public void StategyContextInterface()
    {
        strategy.ExChangeColor();
    }
}

(4)客户端代码

StategyManager 中,我们实例化角色,并动态设置和切换移动策略。

cs 复制代码
using UnityEngine.UI;
public class StategyManager : MonoBehaviour
{
    [SerializeField] private Image img;
    StategyContext stategyContext;
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.R))
        {
            stategyContext = new StategyContext(new ChangeRed(), img);
            stategyContext.StategyContextInterface();
        }
        if (Input.GetKeyDown(KeyCode.B))
        {
            stategyContext = new StategyContext(new ChangeBlue(), img);
            stategyContext.StategyContextInterface();
        }
    }
}

今天是2024年12月4日

重复一段毒鸡汤来勉励我和你

你的对手在看书

你的仇人在磨刀

你的闺蜜在减肥

隔壁的老王在练腰

而你在干嘛?

相关推荐
西岭千秋雪_6 小时前
设计模式の单例&工厂&原型模式
java·单例模式·设计模式·简单工厂模式·工厂方法模式·抽象工厂模式·原型模式
m0_748251728 小时前
Spring Boot 经典九设计模式全览
java·spring boot·设计模式
fuvuof9 小时前
设计模式——单例模式和工厂模式
python·单例模式·设计模式
岳轩子14 小时前
23种设计模式之备忘录模式
windows·设计模式·备忘录模式
岳轩子14 小时前
23种设计模式之中介者模式
设计模式·中介者模式
Vincent(朱志强)17 小时前
设计模式详解(十):策略模式——Strategy
设计模式·策略模式
WangMing_X18 小时前
C# 23种设计模式(1)单例模式(单件模式)
单例模式·设计模式
wkj00118 小时前
PHP开发设计模式:单例模式
单例模式·设计模式·php
不爱吃米饭_19 小时前
工作中常用的8种设计模式
设计模式
岳轩子19 小时前
23种设计模式之命令模式
设计模式·命令模式