Unity3D自学笔记——架构应用(七)客户端识别角色是否已经创建

本文详细介绍了游戏客户端如何根据服务端返回的数据判断角色是否存在,并据此调整界面元素的可见性和交互状态,包括创建和进入游戏按钮的显示逻辑。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

客户端识别角色是否已经创建

角色已经创建则会隐藏创建按钮,显示进入游戏按钮,并且名字禁止输入
这里写图片描述
角色没有创建则隐藏进入游戏按钮,显示创建按钮,启用名字输入
这里写图片描述

分析
1.我们首先要从服务端获取账号下的角色数据,玩家登录的时候,判断是否已经拥有角色,若有则把UserEntity(UserEntity 包含了AccountEntity)返回给客户端进行缓存,若没有则返回AccountEntity
2.在英雄选择的时候去缓存中判断是否已经创建了该英雄,然后进行界面处理

服务端

ALI.ARPG.Domain
增加一个验证,若英雄已经拥有则不允许再次创建

CreateHeroValidateHandler

public ValidationResult Validate(CreateHeroCommand command)
        {
            ValidationResult result = null;
            if(command.HeroID == 0)
            {
                result = new ValidationResult(Resource.HeroRequire);
            }
            else if (string.IsNullOrEmpty(command.Name.Trim()))
            {
                result = new ValidationResult(Resource.HeroNameRequire);
            }
            else
            {
                HeroEntity hero = heroRepository.FindBy(command.HeroID);
                AccountEntity account = accountRepository.FindBy(command.AccountID);
                UserEntity user = userRepository.FindBy(x=>x.Account.ID == command.AccountID && x.Hero.ID == command.HeroID);
                UserEntity sameNameUser = userRepository.FindBy(x => x.Name == command.Name);

                unitOfWork.Commit();
                if(hero == null)
                {
                    result = new ValidationResult(Resource.HeroNotFount);
                }
                else if(account == null)
                {
                    result = new ValidationResult(Resource.AccountNotExist);
                }
                else if(sameNameUser != null)
                {
                    result = new ValidationResult(Resource.HeroNameSame);
                }
                else if(user != null)
                {//该账户下已经拥有该英雄
                    result = new ValidationResult(Resource.HeroIsExist);
                }
            }

            return result;
        }

修改LoginHandler

 public class UserLoginHandler : ICommandHandler<UserLoginCommand>
    {
        private readonly AccountRepository accountRepository;
        private readonly UserRepository userRepository;
        private UnitOfWork unitOfWork;

        public UserLoginHandler()
        {
            unitOfWork = new UnitOfWork();
            accountRepository = new AccountRepository(unitOfWork.Session);
            userRepository = new UserRepository(unitOfWork.Session);
        }
        public ICommandResult Excute(UserLoginCommand command)
        {
            AccountEntity account = accountRepository.FindBy(x => x.Name == command.Name && x.Password == command.Password);
            account.IsLogin = true;
            account.LoginTime = DateTime.Now;
            accountRepository.Update(account);

            //登录时查找是否有UserEntity
            IEnumerable<UserEntity> users = userRepository.FilterBy(x => x.Account.ID == account.ID);

            unitOfWork.Commit();

            //有则返回UserEntity
            if (users != null && users.Count() != 0)
                return new CommandResult<UserEntity>(true, users);
            else//否则返回AccountEntity
                return new CommandResult<AccountEntity>(true, account);
        }
    }

ALI.ARPG.Server
AliPeer
修改Login处理请求

protected virtual void HandleLoginOperation(OperationRequest operationRequest, SendParameters sendParameters)
        {
            object json;
            operationRequest.Parameters.TryGetValue(operationRequest.OperationCode, out json);
            AccountEntity account = JsonMapper.ToObject<AccountEntity>(json.ToString());
            var command = Mapper.Map<AccountEntity, UserLoginCommand>(account);
            ValidationResult error = commandBus.Validate(command);
            OperationResponse response = new OperationResponse((byte)OperationCode.Login);

            if (error != null)
            {
                response.ReturnCode = (short)ReturnCode.Error;
                Dictionary<byte, object> dict = new Dictionary<byte, object>();
                string strJson = JsonMapper.ToJson(error);
                dict.Add((byte)ReturnCode.Error, strJson);
                response.Parameters = dict;
            }
            else
            {
                var result = commandBus.Submit(command);

                if (result.Success)
                {
                    string strJson = string.Empty;
                    byte key;

                    //如果账户下有角色数据则返回角色数据,否者返回英雄数据
                    //客户端通过key来判定是AccountEntity还是UserEntity,然后进行相应解析及缓存
                    if (result is CommandResult<AccountEntity>)
                    {//通过返回值类型来进行判断
                        key = 0;
                        CommandResult<AccountEntity> data = result as CommandResult<AccountEntity>;
                        strJson = JsonMapper.ToJson(data.Result);
                    }
                    else
                    {
                        key = 1;
                        CommandResult<UserEntity> data = result as CommandResult<UserEntity>;
                        strJson = JsonMapper.ToJson(data.Result);
                    }

                    response.ReturnCode = (short)ReturnCode.Sucess;
                    Dictionary<byte, object> dict = new Dictionary<byte, object>();                    
                    dict.Add(key, strJson);
                    response.Parameters = dict;
                }
                else
                {
                    response.ReturnCode = (short)ReturnCode.Faild;
                }
            }

            SendOperationResponse(response, sendParameters);
        }

客户端

PhotonManger修改LoginResponse

private void HandleLoginResponse(OperationResponse operationResponse)
    {
        object json;
        switch ((ReturnCode)operationResponse.ReturnCode)
        {
            case ReturnCode.Sucess:
                Debug.Log("登录成功");
                //通过Key来判断返回的类型
                if (operationResponse.Parameters.ContainsKey(0))
                {//AccountEntity
                    operationResponse.Parameters.TryGetValue(0, out json);
                    if (json != null)
                    {
                    //缓存AccountEntity
                        JsonData data = JsonMapper.ToObject(json.ToString());
                        new JsonToEntity<AccountEntity>(PhotonCacheType.Account, data).BuildEntityToCache();

                        //进入创建英雄场景
                        StartCoroutine(GameMain.Instance.LoadScene(SceneName.CharacterSelection));
                    }
                }
               else if (operationResponse.Parameters.ContainsKey(1))
                {//UserEntity
                    operationResponse.Parameters.TryGetValue(1, out json);
                    if (json != null)
                    {
                    //缓存UserEntity
                        JsonData data = JsonMapper.ToObject(json.ToString());
                        new JsonToEntity<UserEntity>(PhotonCacheType.User, data).BuildEntityToCache();
                     //为了统一操作,所以再将UserEntity里的Account进行缓存
                        UserEntity user = PhotonDataCache.GetValue<UserEntity>(PhotonCacheType.User);
                        AccountEntity account = user.Account;
                        PhotonDataCache.AddOrUpdateDataCache(PhotonCacheType.Account, account.ID, account);

                        //进入创建英雄场景
                        StartCoroutine(GameMain.Instance.LoadScene(SceneName.CharacterSelection));
                    }
                }
                    break;
            case ReturnCode.Error:
                PopupErrorMessage(operationResponse);
                break;
        }
    }

界面处理
修改选择英雄的事件

public class UISelectHero : UIScene {
    private UIHeroInfo m_HeroInfo;
    private UIBottom m_Bottom;
    private int m_SelectedHeroID;

    public int SelectedHeroID
    {
        get
        {
            return m_SelectedHeroID;
        }

        set
        {
            m_SelectedHeroID = value;
        }
    }

    protected override void Start()
    {
        base.Start();
        InitWidget();
    }

    private void InitWidget()
    {
        m_HeroInfo = UIManager.Instance.GetUI<UIHeroInfo>(UIName.UIHeroInfo);
        m_Bottom = UIManager.Instance.GetUI<UIBottom>(UIName.UIBottom);

        for (int i = 0; i < this.GetWidgetCount(); i++)
        {
            UISceneWidget m_TogButton = GetWidget("togHero" + (i + 1));
            if(m_TogButton != null)
            {
                m_TogButton.PointerClick += TogButtonOnPointerClick;
            }
        }
    }

    private void TogButtonOnPointerClick(UnityEngine.EventSystems.PointerEventData obj)
    {
        //获取HeroId
        string heroID = obj.selectedObject.name;
        int id;
        heroID = heroID.Substring(heroID.Length - 1);       
        m_SelectedHeroID = (Int32.TryParse(heroID, out id)) ? id : 0;
        //显示英雄介绍
        m_HeroInfo.SetHeroInfo(m_SelectedHeroID);
        //判断英雄是否已经创建
        Dictionary<int, IEntity> users = PhotonDataCache.GetValue(PhotonCacheType.User);

        var user = users.Select(x => x.Value).Cast<UserEntity>().Where(x => x.Hero.ID == id);
        if(user.Count() > 0)
        {//英雄已经创建
            m_Bottom.ExistHero(true);
            m_Bottom.IptName.text = user.ToList().First().Name;
        }
        else
        {
            m_Bottom.ExistHero(false);
            m_Bottom.IptName.text = string.Empty;
        }
    }
}

UIBottom的方法,将它Public提供给外部调用

public void ExistHero(bool isExist)
    {
        IptName.interactable = !isExist;
        m_BtnNew.gameObject.SetActive(!isExist);
        m_BtnEnter.gameObject.SetActive(isExist);
    }

搞定

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值