You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决Alteruna多人游戏中玩家自定义角色Prefab生成问题

解决Alteruna框架下根据玩家选择生成对应角色Prefab的方案

核心思路

Alteruna默认的单预制体生成逻辑是因为未配置多角色的网络资源注册,且自动生成规则固定。要实现自定义角色生成,需完成预制体网络注册、角色选择数据同步、替换自动生成逻辑三个核心步骤。

具体实现步骤

1. 注册所有角色Prefab到Alteruna网络资源

Alteruna需要提前知晓所有可跨网络生成的预制体,否则联机时会出现资源找不到的问题。两种实现方式:

  • 可视化配置:在场景的Alteruna Network Manager组件中,找到Network Objects列表,将12个角色Prefab全部添加进去。
  • 代码动态注册(适合批量处理,灵活性更高):
using Alteruna;
using UnityEngine;
using System.Collections.Generic;

public class CharacterRegistry : MonoBehaviour
{
    [SerializeField] private List<GameObject> _characterPrefabs; // 拖拽12个角色Prefab到这里

    void Awake()
    {
        foreach (var prefab in _characterPrefabs)
        {
            // 确保每个Prefab都带有Alteruna要求的Avatar组件
            if (!prefab.GetComponent<Avatar>())
            {
                prefab.AddComponent<Avatar>();
            }
            NetworkObjectRegistry.RegisterPrefab(prefab);
        }
    }
}

2. 获取玩家的角色选择数据

从SQL数据库读取当前玩家预选中的角色ID(菜单选择阶段已存入数据库),需在进入联机房间前或刚连接时完成读取:

// 异步读取数据库,避免阻塞主线程
private async Task<int> GetSelectedCharacterId()
{
    // 替换为你的实际数据库查询逻辑(如ADO.NET、EF Core等)
    using (var conn = new SqlConnection("你的数据库连接字符串"))
    {
        await conn.OpenAsync();
        var cmd = new SqlCommand("SELECT SelectedCharacterId FROM Players WHERE PlayerId = @PlayerId", conn);
        cmd.Parameters.AddWithValue("@PlayerId", CurrentPlayerId); // 当前玩家的唯一标识
        return (int)await cmd.ExecuteScalarAsync();
    }
}

3. 替换Alteruna的自动生成逻辑

步骤3.1 禁用默认自动生成

在场景的Alteruna Avatar Manager组件中,取消勾选Auto Spawn Player选项。

步骤3.2 本地玩家生成逻辑

监听连接成功事件,读取角色ID后生成对应Prefab:

using Alteruna;
using UnityEngine;
using System.Threading.Tasks;

public class CustomPlayerSpawner : MonoBehaviour
{
    [SerializeField] private AvatarManager _avatarManager;
    [SerializeField] private List<GameObject> _characterPrefabs;

    void Start()
    {
        _avatarManager.OnConnected += HandleLocalPlayerConnected;
    }

    private async void HandleLocalPlayerConnected()
    {
        int selectedId = await GetSelectedCharacterId();
        GameObject targetPrefab = _characterPrefabs[selectedId];
        
        // 生成本地玩家角色
        _avatarManager.SpawnPlayer(targetPrefab);
        
        // 将角色ID同步到玩家属性,供其他玩家获取
        _avatarManager.LocalPlayer.SetProperty("SelectedCharacter", selectedId);
    }
}

步骤3.3 其他玩家生成逻辑

监听其他玩家加入事件,根据对方同步的角色ID生成对应Prefab:

void OnEnable()
{
    _avatarManager.OnPlayerJoined += HandlePlayerJoined;
}

void OnDisable()
{
    _avatarManager.OnPlayerJoined -= HandlePlayerJoined;
}

private void HandlePlayerJoined(Player player)
{
    // 跳过本地玩家(已自行生成)
    if (player.IsLocal) return;
    
    // 获取对方同步的角色ID
    if (player.TryGetProperty<int>("SelectedCharacter", out int characterId))
    {
        GameObject targetPrefab = _characterPrefabs[characterId];
        // 生成该玩家的角色
        _avatarManager.SpawnPlayer(targetPrefab, player);
    }
}

注意事项

  • 所有角色Prefab必须带有Alteruna.Avatar组件,否则无法被Alteruna同步。
  • 确保角色ID的取值范围在0-11之间(对应12个角色),避免索引越界。
  • 若玩家断开重连,需重新执行角色读取和生成逻辑(可监听OnReconnected事件)。

内容的提问来源于stack exchange,提问作者SuperMen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 18:23:25