下面我将详细介绍如何在鸿蒙HarmonyOS 5中使用Unity开发一个判断用户是否拥有王者荣耀英雄的应用。

1. 环境准备与项目设置

  1. ​安装必要工具​​:

    • Unity 2021 LTS或更高版本
    • DevEco Studio 3.0+
    • HarmonyOS SDK
  2. ​创建Unity项目​​:

    File > New Project > 3D Template
  3. ​添加HarmonyOS支持​​:
    在Player Settings中设置:

    • Company Name
    • Product Name
    • Bundle Identifier (com.yourcompany.honorkings)

2. 数据结构设计

创建英雄数据模型HeroModel.cs

using System;

[Serializable]
public class HeroModel
{
    public int heroId;
    public string heroName;
    public string heroRole;
    public Sprite heroIcon;
    public bool isOwned; // 是否拥有该英雄
}

[CreateAssetMenu(fileName = "HeroData", menuName = "Game/Hero Data")]
public class HeroData : ScriptableObject
{
    public HeroModel[] heroes;
}

3. 用户数据管理

创建用户数据管理脚本UserDataManager.cs

using System.Collections.Generic;
using UnityEngine;

public class UserDataManager : MonoBehaviour
{
    public static UserDataManager Instance;
    
    // 存储用户拥有的英雄ID列表
    private HashSet<int> ownedHeroIds = new HashSet<int>();
    
    private void Awake()
    {
        if (Instance == null)
        {
            Instance = this;
            DontDestroyOnLoad(gameObject);
            LoadUserData();
        }
        else
        {
            Destroy(gameObject);
        }
    }
    
    // 从HarmonyOS本地存储加载数据
    private void LoadUserData()
    {
        // 这里需要调用HarmonyOS本地存储接口
        // 伪代码示例:
        // var savedIds = HarmonyOS.Preferences.GetString("owned_hero_ids", "");
        // 解析字符串到HashSet
        
        // 测试数据
        ownedHeroIds.Add(101); // 示例英雄ID
        ownedHeroIds.Add(103);
    }
    
    // 检查是否拥有英雄
    public bool CheckHeroOwned(int heroId)
    {
        return ownedHeroIds.Contains(heroId);
    }
    
    // 添加英雄到已拥有列表
    public void AddHero(int heroId)
    {
        if (!ownedHeroIds.Contains(heroId))
        {
            ownedHeroIds.Add(heroId);
            SaveUserData();
        }
    }
    
    // 保存数据到HarmonyOS本地存储
    private void SaveUserData()
    {
        // 将HashSet转换为字符串保存
        // HarmonyOS.Preferences.SetString("owned_hero_ids", string.Join(",", ownedHeroIds));
        // HarmonyOS.Preferences.Flush();
    }
}

4. UI界面实现

4.1 英雄卡片预制体

创建HeroCard.prefab包含:

  • Hero Icon (Image)
  • Hero Name (TextMeshPro)
  • Owned Badge (GameObject)
  • Lock Icon (GameObject)

4.2 英雄卡片控制器HeroCardController.cs

using UnityEngine;
using TMPro;

public class HeroCardController : MonoBehaviour
{
    public Image heroIcon;
    public TMP_Text heroName;
    public GameObject ownedBadge;
    public GameObject lockIcon;
    
    public void Setup(HeroModel hero)
    {
        heroIcon.sprite = hero.heroIcon;
        heroName.text = hero.heroName;
        
        bool isOwned = UserDataManager.Instance.CheckHeroOwned(hero.heroId);
        ownedBadge.SetActive(isOwned);
        lockIcon.SetActive(!isOwned);
    }
}

5. 主界面控制器MainUIController.cs

using System.Linq;
using UnityEngine;
using UnityEngine.UI;

public class MainUIController : MonoBehaviour
{
    public HeroData heroData;
    public Transform contentPanel;
    public GameObject heroCardPrefab;
    public TMP_InputField searchInput;
    
    private void Start()
    {
        PopulateHeroList(heroData.heroes.ToList());
        
        searchInput.onValueChanged.AddListener(OnSearchInputChanged);
    }
    
    private void PopulateHeroList(List<HeroModel> heroes)
    {
        ClearHeroList();
        
        foreach (var hero in heroes)
        {
            GameObject card = Instantiate(heroCardPrefab, contentPanel);
            HeroCardController cardController = card.GetComponent<HeroCardController>();
            cardController.Setup(hero);
        }
    }
    
    private void OnSearchInputChanged(string searchText)
    {
        var filtered = heroData.heroes.Where(h => 
            h.heroName.Contains(searchText)).ToList();
        PopulateHeroList(filtered);
    }
    
    private void ClearHeroList()
    {
        foreach (Transform child in contentPanel)
        {
            Destroy(child.gameObject);
        }
    }
}

6. HarmonyOS与Unity集成

6.1 配置AndroidManifest.xml

在Unity导出前,确保AndroidManifest.xml包含必要的HarmonyOS权限:

<uses-permission android:name="ohos.permission.READ_USER_STORAGE" />
<uses-permission android:name="ohos.permission.WRITE_USER_STORAGE" />

6.2 创建HarmonyOS入口Ability

// MainAbility.java
public class MainAbility extends Ability {
    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        setUIContent(ResourceTable.Layout_ability_main);
        
        // 启动Unity Activity
        findComponentById(ResourceTable.Id_unity_button).setClickedListener(component -> {
            Intent unityIntent = new Intent();
            Operation operation = new Intent.OperationBuilder()
                .withDeviceId("")
                .withBundleName(getBundleName())
                .withAbilityName("com.unity3d.player.UnityPlayerActivity")
                .build();
            unityIntent.setOperation(operation);
            startAbility(unityIntent);
        });
    }
}

7. 数据持久化方案

7.1 HarmonyOS本地存储

在Unity中通过AndroidJavaClass调用HarmonyOS的Preferences:

// HarmonyOSDataBridge.cs
using UnityEngine;

public class HarmonyOSDataBridge : MonoBehaviour
{
    private static AndroidJavaClass harmonyOSUtils;
    
    public static void SaveData(string key, string value)
    {
        if (harmonyOSUtils == null)
        {
            harmonyOSUtils = new AndroidJavaClass("com.example.HarmonyOSUtils");
        }
        
        harmonyOSUtils.CallStatic("setPreference", key, value);
    }
    
    public static string LoadData(string key, string defaultValue)
    {
        if (harmonyOSUtils == null)
        {
            harmonyOSUtils = new AndroidJavaClass("com.example.HarmonyOSUtils");
        }
        
        return harmonyOSUtils.CallStatic<string>("getPreference", key, defaultValue);
    }
}

7.2 对应的HarmonyOS Java代码

// HarmonyOSUtils.java
import ohos.app.Context;
import ohos.data.preferences.Preferences;

public class HarmonyOSUtils {
    private static Context context;
    
    public static void init(Context ctx) {
        context = ctx;
    }
    
    public static void setPreference(String key, String value) {
        Preferences preferences = Preferences.getPreferences(context, "user_data");
        preferences.putString(key, value);
        preferences.flush();
    }
    
    public static String getPreference(String key, String defaultValue) {
        Preferences preferences = Preferences.getPreferences(context, "user_data");
        return preferences.getString(key, defaultValue);
    }
}

8. 测试与调试

  1. ​单元测试​​:

    [Test]
    public void TestHeroOwnedStatus()
    {
        UserDataManager.Instance.AddHero(101);
        Assert.IsTrue(UserDataManager.Instance.CheckHeroOwned(101));
        Assert.IsFalse(UserDataManager.Instance.CheckHeroOwned(102));
    }
  2. ​UI测试​​:

    • 验证英雄卡片正确显示拥有/未拥有状态
    • 测试搜索功能
    • 验证数据持久化

9. 性能优化建议

  1. ​对象池管理​​:

    public class HeroCardPool : MonoBehaviour
    {
        public GameObject cardPrefab;
        public int poolSize = 20;
        
        private Queue<GameObject> pool = new Queue<GameObject>();
        
        private void Start()
        {
            for (int i = 0; i < poolSize; i++)
            {
                GameObject card = Instantiate(cardPrefab);
                card.SetActive(false);
                pool.Enqueue(card);
            }
        }
        
        public GameObject GetCard()
        {
            if (pool.Count > 0)
            {
                GameObject card = pool.Dequeue();
                card.SetActive(true);
                return card;
            }
            return Instantiate(cardPrefab);
        }
        
        public void ReturnCard(GameObject card)
        {
            card.SetActive(false);
            pool.Enqueue(card);
        }
    }
  2. ​异步加载英雄图标​​:

    public IEnumerator LoadHeroIconAsync(string iconPath, Image targetImage)
    {
        ResourceRequest request = Resources.LoadAsync<Sprite>(iconPath);
        yield return request;
        
        if (request.asset != null)
        {
            targetImage.sprite = request.asset as Sprite;
        }
    }

10. 扩展功能

  1. ​网络同步​​:

    • 从王者荣耀API获取用户真实英雄数据
    • 实现登录系统
  2. ​更多显示选项​​:

    • 英雄熟练度显示
    • 皮肤拥有状态
    • 英雄战力值
  3. ​排序与筛选​​:

    • 按英雄类型筛选
    • 按获取时间排序
    • 按英雄价格筛选

通过以上实现,你可以在鸿蒙HarmonyOS 5中使用Unity开发一个完整的王者荣耀英雄拥有判断应用,该应用能够准确显示用户已拥有和未拥有的英雄,并提供良好的用户体验。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐