Unity 适配器模式(实例详解)

文章目录

    • 简介
    • [1. **Input Adapter 示例**](#1. Input Adapter 示例)
    • [2. **Component Adapter 示例**](#2. Component Adapter 示例)
    • [3. **网络数据解析适配器**](#3. 网络数据解析适配器)
    • [4. **物理引擎适配**](#4. 物理引擎适配)
    • [5. **跨平台服务适配**](#5. 跨平台服务适配)

简介

Unity中的适配器模式(Adapter Pattern)主要用于将一个类的接口转换为另一个接口,以便于原本不兼容的对象能够协同工作。在Unity中,适配器可以用于多种场景,例如让不同版本API、不同组件间的交互变得一致,或者对接外部库等。由于Unity使用的是C#语言,以下将提供五个简化的C#代码示例来说明适配器模式在Unity环境下的应用:

1. Input Adapter 示例

假设我们有一个老版本的输入系统,它直接处理键盘按键事件,而新的Unity Input System需要一个特定的接口。我们可以创建一个适配器来使老版输入系统与新接口兼容。

csharp 复制代码
// 老版本输入系统的接口
public class LegacyInputSystem
{
    public bool IsKeyDown(KeyCode key) { /* ... */ }
}

// 新的输入系统接口
public interface INewInput
{
    bool GetKey(KeyCode key);
}

// 适配器类
public class LegacyInputToNewInputAdapter : INewInput
{
    private LegacyInputSystem legacyInput;

    public LegacyInputToNewInputAdapter(LegacyInputSystem input)
    {
        this.legacyInput = input;
    }

    public bool GetKey(KeyCode key)
    {
        return legacyInput.IsKeyDown(key);
    }
}

2. Component Adapter 示例

Unity内置的Rigidbody和CharacterController组件有不同的接口,但你希望在统一逻辑中处理两者。创建一个适配器可以让它们都实现同样的接口。

csharp 复制代码
public interface IMover
{
    void Move(Vector3 direction, float speed);
}

// Rigidbody Mover Adapter
public class RigidbodyMoverAdapter : MonoBehaviour, IMover
{
    private Rigidbody rb;

    void Start()
    {
        rb = GetComponent<Rigidbody>();
    }

    public void Move(Vector3 direction, float speed)
    {
        rb.AddForce(direction * speed, ForceMode.VelocityChange);
    }
}

// CharacterController Mover Adapter
public class CharacterControllerMoverAdapter : MonoBehaviour, IMover
{
    private CharacterController cc;

    void Start()
    {
        cc = GetComponent<CharacterController>();
    }

    public void Move(Vector3 direction, float speed)
    {
        cc.Move(direction.normalized * speed * Time.deltaTime);
    }
}

3. 网络数据解析适配器

如果你正在使用一个第三方JSON解析库,但是Unity项目中已经有一些基于Unity JSONUtility进行数据序列化的代码,可以创建一个适配器以使得新库也能遵循现有接口。

csharp 复制代码
// 第三方JSON解析器接口
public class ThirdPartyJsonParser
{
    public string SerializeObject(object obj); // 序列化方法
    public T DeserializeObject<T>(string json); // 反序列化方法
}

// Unity JSONUtility适配器
public class UnityJsonAdapter
{
    public string ToJson(object obj)
    {
        return JsonUtility.ToJson(obj);
    }

    public T FromJson<T>(string json)
    {
        return JsonUtility.FromJson<T>(json);
    }
}

// 适配器类内部对ThirdPartyJsonParser的封装
public class AdapterForThirdParty : ThirdPartyJsonParser
{
   public override string SerializeObject(object obj)
   {
       return new UnityJsonAdapter().ToJson(obj);
   }

   public override T DeserializeObject<T>(string json)
   {
       return new UnityJsonAdapter().FromJson<T>(json);
   }
}

4. 物理引擎适配

假设有一个自定义的物理计算库,但游戏中的其他部分是基于Unity的物理引擎 Rigidbody 的。创建一个适配器可以将自定义库的行为模拟成 Rigidbody 的行为。

csharp 复制代码
public class CustomPhysicsEngine
{
    public Vector3 ApplyForce(Vector3 force);
    public Vector3 GetVelocity();
}

public class CustomPhysicsToRigidbodyAdapter : MonoBehaviour
{
    private Rigidbody _rb;
    private CustomPhysicsEngine _customPhysics;

    void Start()
    {
        _rb = GetComponent<Rigidbody>();
        _customPhysics = new CustomPhysicsEngine();
    }

    void FixedUpdate()
    {
        var force = _customPhysics.ApplyForce(...);
        _rb.AddForce(force);
        
        if (_rb.velocity != _customPhysics.GetVelocity())
        {
            // 在这里同步或调整Rigidbody的状态
            _rb.velocity = _customPhysics.GetVelocity();
        }
    }
}

5. 跨平台服务适配

对于跨平台开发,某些服务在不同平台上可能有不同的实现。比如音频播放功能,可以创建适配器确保在所有平台上都能通过相同的接口调用。

csharp 复制代码
public interface IAudioPlayer
{
    void PlaySound(AudioClip clip);
    void StopSound();
}

public class MobileAudioPlayer : IAudioPlayer
{
    void PlaySound(AudioClip clip)
    {
        // 移动设备上播放音频
        // ...
    }

    void StopSound()
    {
        // 在移动设备上停止音频
        // ...
    }
}

public class DesktopAudioPlayer : IAudioPlayer
{
    void PlaySound(AudioClip clip)
    {
        // PC上播放音频
        // ...
    }

    void StopSound()
    {
        // 在PC上停止音频
        // ...
    }
}
// 适配器类
public class PlatformSpecificAudioAdapter : IAudioPlayer
{
    private readonly IAudioPlayer _audioPlayer;

    public PlatformSpecificAudioAdapter()
    {
        #if UNITY_IOS || UNITY_ANDROID
            _audioPlayer = new MobileAudioPlayer();
        #else
            _audioPlayer = new DesktopAudioPlayer();
        #endif
    }

    public void PlaySound(AudioClip clip)
    {
        _audioPlayer.PlaySound(clip);
    }

    public void StopSound()
    {
        _audioPlayer.StopSound();
    }
}

以上每个示例展示了如何通过适配器模式在Unity中解决接口不兼容的问题,并保持代码结构清晰、易于维护和扩展。

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

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

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

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

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


​最后我们放松一下眼睛

相关推荐
工藤新一¹3 分钟前
C++/SDL 进阶游戏开发 —— 双人塔防(代号:村庄保卫战 16)
c++·游戏引擎·sdl·c++游戏开发·实践项目
全栈小51 小时前
【C#】.net core6.0无法访问到控制器方法,直接404。由于自己的不仔细,出现个低级错误,这让DeepSeek看出来了,是什么错误呢,来瞧瞧
开发语言·c#·.netcore
暴走约伯3 小时前
【虚幻5蓝图Editor Utility Widget:创建高效模型材质自动匹配和资产管理工具,从3DMax到Unreal和Unity引擎_系列第二篇】
unity·ue5·游戏引擎·虚幻·材质
浅陌sss8 小时前
C#中实现XML解析器
xml·c#
全栈师11 小时前
C#中分组循环的做法
开发语言·c#
FAREWELL0007511 小时前
C#进阶学习(十六)C#中的迭代器
开发语言·学习·c#·迭代器模式·迭代器
一颗橘子宣布成为星球11 小时前
Unity AI-使用Ollama本地大语言模型运行框架运行本地Deepseek等模型实现聊天对话(一)
人工智能·unity·语言模型·游戏引擎
DXM052111 小时前
牟乃夏《ArcGIS Engine地理信息系统开发教程》学习笔记3-地图基本操作与实战案例
开发语言·笔记·学习·arcgis·c#·ae·arcgis engine
Tandy12356_14 小时前
Godot开发2D冒险游戏——第三节:游戏地图绘制
游戏引擎·godot
csdn_aspnet14 小时前
C# 如何验证磁盘路径,如:D:\\m\aa.txt
c#