unity网络游戏开发

  • Post author:
  • Post category:其他



【千锋合集】史上最全Unity3D全套教程|匠心之作_哔哩哔哩_bilibili

toggle group的添加

自己搭建UI和预设体

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

using UIFrame;

public class LobbyFacade : MonoBehaviour

{


// Start is called before the first frame update

void Start()

{


UIManager.Instance.ShowUI(“MainPanel”);

UIManager.Instance.ShowUI(“TopPanel”);

}

// Update is called once per frame

void Update()

{

}

}

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

using UIFrame;

public class MainPanelController : UIControllerBase

{


protected override void ControllerStart()

{


base.ControllerStart();

Debug.Log(“MainPanel Start!”);

BindEvent();

}

protected void BindEvent()

{

}

}

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

using UIFrame;

public class MainPanelModule : UIModuleBase

{


public override void Awake()

{


base.Awake();

//创建控制器

var controller = new MainPanelController();

//绑定控制

BindController(controller);

}

}

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

using UIFrame;

public class TopPanelController : UIControllerBase

{


protected override void ControllerStart()

{


base.ControllerStart();

Debug.Log(“TopPanel Start!”);

BindEvent();

}

protected void BindEvent() {

}

}

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

using UIFrame;

public class TopPanelModule : UIModuleBase

{


public override void Awake()

{


base.Awake();

//创建控制器

var controller = new TopPanelController();

//绑定控制

BindController(controller);

}

}

——————————————————————————————————————————–

json文件

{


“AllData”:[

{


“SceneName”:”LobbyScene”,

“Data”: [

{ “PanelName”:”TopPanel”,

“PanelPath”:”LobbyUIPanels/TopPanel” },

{ “PanelName”:”MainPanel”,

“PanelPath”: “LobbyUIPanels/MainPanel” },

{“PanelName”: “RoomPanel”,

“PanelPath”: “LobbyUIPanels/RoomPanel” },

{ “PanelName”:”RoomListPanel”,

“PanelPath”: “LobbyUIPanels/RoomListPanel” }

]

}

]

}


所有代码汇总:


using


System.Collections;


using


System.Collections.Generic;


using


UnityEngine;


using


UIFrame;


public


class


TopPanelModule


: UIModuleBase


{


public


override


void


Awake


()


{


base


.Awake();


//


创建控制器


var


controller =


new


TopPanelController();


//


绑定控制


BindController(controller);


}


}


using


System.Collections;


using


System.Collections.Generic;


using


UnityEngine;


public


class


CameraFollow


: MonoBehaviour


{


[Header(





跟随速度





)]


public


float


moveSpeed = 3f;


// Start is called before the first frame update


void


Start


()


{


}


// Update is called once per frame


void


Update


()


{


if


(HumanGameManager.Instance.currentHero ==


null


) {


return


;


}


float


Instance_x = HumanGameManager.Instance.currentHero.position.x;


float


Instance_y = 15f;


float


Instance_z = HumanGameManager.Instance.currentHero.position.z;


Vector3 followPosition =


new


Vector3(Instance_x, Instance_y, Instance_z);


transform.position = Vector3.Lerp(transform.position, followPosition,Time.deltaTime*moveSpeed);


}


}


using


System.Collections;


using


System.Collections.Generic;


using


UnityEngine;


using


Photon.Pun;


using


Photon.Realtime;


using


UIFrame;


using


Hashtable = ExitGames.Client.Photon.Hashtable;


using


ExitGames.Client.Photon;


using


System;


public


class


GameController


: MonoBehaviourPunCallbacks


{


public


bool


hasInit =


false


;


// Start is called before the first frame update


void


Start


()


{


//


设置每秒发送包数


PhotonNetwork.SendRate = 30;


//PhotonNetwork.Instantiate(JsonDataManager.Instance.FindHeroPath(HumanGameManager.Instance.selectedHeroIndex),Vector3.zero,Quaternion.identity);


//


设置玩家加载成功属性


SetPlayerLoaded();


//


房主检测是否所有玩家都加载成功


//CheckAllPlayerLoaded();


//Test();


}


private


void


Test() {


if


(!PhotonNetwork.IsMasterClient)


return


;


//


生产场景网络对象


PhotonNetwork.InstantiateSceneObject(JsonDataManager.Instance.FindHeroPath(0),Vector3.back,Quaternion.identity);


}


// Update is called once per frame


void


Update


()


{


}


///


<summary>


///


设置当前玩家已经加载场景成功


///


</summary>


private


void


SetPlayerLoaded() {


Hashtable hashtable =


new


Hashtable();


//


添加属性


hashtable.Add(GameConst.LOADED_PROPERTY,


true


);


//


设置属性


PhotonNetwork.LocalPlayer.SetCustomProperties(hashtable);


}


///


<summary>


///


检测所有玩家是否都已经加载场景成功


///


</summary>


private


bool


CheckAllPlayerLoaded() {


if


(!PhotonNetwork.IsMasterClient)


return


false


;


for


(


int


i = 0; i < PhotonNetwork.PlayerList.Length; i++) {


//


是否加载


object


isLoaded =


false


;


//


尝试加载属性


PhotonNetwork.PlayerList[i].CustomProperties.TryGetValue(GameConst.LOADED_PROPERTY,


out


isLoaded);


//


如果没有加载到或加载到了,值还为未加载场景成功


if


(isLoaded ==


null


|| !(


bool


)isLoaded) {


return


false


;


}


}


Hashtable hashtable =


new


Hashtable();


//


添加房间属性


hashtable.Add(GameConst.INITHERO_PROPERTY,


true


);


//


设置房间属性


PhotonNetwork.CurrentRoom.SetCustomProperties(hashtable);


//


表示所有玩家都已经加载场景成功


return


true


;


}


#region


Photon Callbacks


public


override


void


OnRoomPropertiesUpdate(Hashtable propertiesThatChanged)


{


object


canInit =


false


;


//


尝试获取属性


propertiesThatChanged.TryGetValue(GameConst.INITHERO_PROPERTY,


out


canInit);


if


(canInit ==


null


) {


canInit =


false


;


}


//


属性获取到,且值为


True


if


((


bool


)canInit&&!hasInit) {


//


每个玩家生成各自的英雄


InitHero();


}


}


private


void


InitHero()


{


//


标记已经创建好了英雄


hasInit =


true


;


PhotonNetwork.Instantiate(JsonDataManager.Instance.FindHeroPath(HumanGameManager.Instance.selectedHeroIndex),


new


Vector3(PhotonNetwork.LocalPlayer.ActorNumber*3-3,0,0),Quaternion.identity);


}


public


override


void


OnPlayerPropertiesUpdate(Player targetPlayer, Hashtable changedProps)


{


//


房主检测是否所有玩家都加载成功


CheckAllPlayerLoaded();


}


#endregion


}


using


System.Collections;


using


System.Collections.Generic;


using


UnityEngine;


using


Photon.Pun;


using


UIFrame;


using


UnityEngine.AI;


using


System;


public


class


HeroController


: MonoBehaviourPunCallbacks,IPunObservable


{


[Header(





攻击范围





)]


public


float


attackRange = 2f;


[Header(





移动速度





)]


public


float


moveSpeed = 3f;


[Header(





转身速度





)]


public


float


turnSpeed;


//


射线碰撞检测器


private


RaycastHit hit;


private


NavMeshAgent nav;


private


Animator ani;


private


PhotonAnimatorView aniView;


//


导航去找英雄


private


bool


gotoHero =


false


;


//


目标英雄


private


PhotonView targetHero;


//


攻击特效脚本


private


TriggerProjectile _triggerProjectile;


private


void


Awake


()


{


nav = GetComponent<NavMeshAgent>();


ani = GetComponent<Animator>();


aniView = GetComponent<PhotonAnimatorView>();


_triggerProjectile = GetComponent<TriggerProjectile>();


}


private


void


Start


() {


//


设置制动距离


nav.stoppingDistance = 0;


//


设置移动速度


nav.speed = moveSpeed;


if


(photonView.IsMine) {


//


标记当前英雄


HumanGameManager.Instance.currentHero = transform;


}


}


private


void


Update


()


{


if


(!photonView.IsMine)


return


;


//if (photonView.Owner == null)


//return;


CheckArrive();


HeroInput();


CheckTargetHeroInRange();


}


///


<summary>


///


检测目标英雄是否脱离攻击范围


///


</summary>


private


void


CheckTargetHeroInRange() {


if


(targetHero ==


null


)


return


;


//


如果对方已经走远


if


(Vector3.Distance(targetHero.transform.position, transform.position) > attackRange) {


//


停止攻击


ani.SetBool(GameConst.PLAYERATTACK_PARA,


false


);


//


导航去目标角色


SetHeroDestination(targetHero.transform.position);


}


}


///


<summary>


///


检测当前英雄是否到达导航目标


///


</summary>


private


void


CheckArrive() {


//


到达目标


if


(nav.remainingDistance – nav.stoppingDistance <= 0.05f) {


ani.SetFloat(GameConst.SPEED_PARA, 0);


if


(targetHero!=


null


)


{


//


转向目标


RotateTo(targetHero.transform.position);


//


攻击


ani.SetBool(GameConst.PLAYERATTACK_PARA,


true


);


}


else


{


//


停止攻击


ani.SetBool(GameConst.PLAYERATTACK_PARA,


false


);


}


}


}


///


<summary>


///


转向目标


///


</summary>


///


<param name=”


target


“></param>


private


void


RotateTo(Vector3 target) {


//


方向向量


Vector3 dir = target – transform.position;


//


转成四元数


Quaternion targetQua = Quaternion.LookRotation(dir);


//Lerp


transform.rotation = Quaternion.Lerp(transform.rotation, targetQua, Time.deltaTime * turnSpeed);


}


///


<summary>


///


英雄操作输入检测


///


</summary>


private


void


HeroInput() {


if


(Input.GetButtonDown(


“HeroMove”


))


{


//


将鼠标位置转换为物理射线


Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);


if


(Physics.Raycast(ray,


out


hit, 100, 1 << 8 | 1 << 9))


{


//


如果点击的是当前英雄


if


(hit.collider.gameObject == gameObject)


return


;


//


设置位置


//


如果点击的是地面


if


(hit.collider.gameObject.layer == LayerMask.NameToLayer(


“Ground”


))


{


nav.stoppingDistance = 0;


//


标记目标丢失


targetHero =


null


;


//


生成对象


GameObject tempParticle = Instantiate(AssetsManager.Instance.GetAsset(SystemDefine.ClickParticlePath))


as


GameObject;


//


设置位置


tempParticle.transform.position = hit.point;


//


定时销毁


Destroy(tempParticle, 2);


}


else


{


nav.stoppingDistance = attackRange;


//


获取目标英雄


targetHero = hit.collider.GetComponent<PhotonView>();


//


同步给其他玩家


photonView.RPC(


“SendTarget”


,RpcTarget.All,targetHero.ViewID);


}


//


设置导航目标


nav.SetDestination(hit.point);


nav.velocity = Vector3.zero;


//


设置导航目标


SetHeroDestination(hit.point);


}


}


}


[PunRPC]


public


void


SendTarget(


int


viewID) {


_triggerProjectile.targetPoint=PhotonView.Find(viewID).transform;


}


private


void


SetHeroDestination(Vector3 target) {


//


设置动画参数


ani.SetFloat(GameConst.SPEED_PARA, 1.5f);


//


当前玩家指向目标的方向向量


Vector3 dir=target – transform.position;


//


计算夹角


float


angle=Vector3.Angle(dir, transform.forward);


if


(angle > 80) {


nav.velocity = Vector3.zero;


}


nav.velocity = Vector3.zero;


//


设置导航目标


nav.SetDestination(target);


}


public


void


OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)


{


return


;


if


(stream.IsWriting)


{


if


(targetHero !=


null


)


{


//


写入


ViewID


stream.SendNext(targetHero.ViewID);


//


设置特效目标


_triggerProjectile.targetPoint = targetHero.transform;


}


}


else


if


(stream.IsReading)


{


try


{


//


读取


ViewID


int


viewID = (


int


)stream.ReceiveNext();


//


通过


ViewID


拿到


PhotonView


_triggerProjectile.targetPoint = PhotonView.Find(viewID).transform;


}


catch


(Exception e)


{


Debug.LogWarning(e);


}


}


}


}


using


System.Collections;


using


System.Collections.Generic;


using


UnityEngine;


public


class


HumanGameManager


: MonoBehaviour


{


public


static


HumanGameManager Instance;


///


<summary>


///


选择英雄编号


///


</summary>


public


byte


selectedHeroIndex = 1;


///


<summary>


///


当前英雄


///


</summary>


public


Transform currentHero;


private


void


Awake()


{


Instance =


this


;


//


过渡场景时,不要销毁


DontDestroyOnLoad(gameObject);


}


// Start is called before the first frame update


void


Start()


{


}


// Update is called once per frame


void


Update()


{


}


}


using


System.Collections;


using


System.Collections.Generic;


using


UnityEngine;


public


class


TriggerProjectile


: MonoBehaviour


{


public


GameObject projectile;


public


Transform shootPoint;


public


Transform targetPoint;


private


GameObject magicMissile;


public


float


attackCostTime=1;


public


float


attackHeight = 12;


public


GameObject hitEffect;


public


void


shoot() {


magicMissile = Instantiate(projectile, shootPoint.position,transform.rotation);


StartCoroutine(lerpyLoop(magicMissile));


}


//shoot loop


public


IEnumerator lerpyLoop(GameObject projectileInstance) {


float


progress = 0;


float


timeScale = 1.0f / attackCostTime;


Vector3 origin = projectileInstance.transform.position;


if


(targetPoint ==


null


)


yield


break


;


while


(progress < 1) {


if


(projectileInstance && targetPoint) {


progress += timeScale * Time.deltaTime;


float


ypos = (progress-Mathf.Pow(progress,2)) * attackHeight;


float


ypos_b = ((progress+0.1f)-Mathf.Pow(progress+0.1f,2))*attackHeight;


projectileInstance.transform.position = Vector3.Lerp(origin,targetPoint.position,progress);


if


(progress < 0.9f) {


projectileInstance.transform.LookAt(Vector3.Lerp(origin,targetPoint.position,progress+0.1f)+


new


Vector3(0,ypos_b,0));


}


yield


return


null


;


}


}


}


public


void


clearProjectiles() {


if


(magicMissile)


Destroy(magicMissile);


}


}


using


System.Collections;


using


System.Collections.Generic;


using


UnityEngine;


using


UIFrame;


using


Photon.Pun;


using


Photon.Realtime;


using


Photon;


public


class


RoomPanelModule


:UIModuleBase


{


//


创建控制器


RoomPanelController controller;


public


override


void


Awake


()


{


base


.Awake();


//


创建控制器


controller =


new


RoomPanelController();


//


绑定控制


BindController(controller);


}


///


<summary>


///


更新玩家


UI


的显示


///


</summary>


public


void


UpdatePlayerUIMsg() {


controller.UpdatePlayerMsg();


}


//


【新】


public


void


SetPlayerReadyStateHash(


int


playerID,


bool


isReady) {


controller.SetPlayerReadyStateHash(playerID, isReady);


}


///


<summary>


///


设置玩家准备状态


///


</summary>


///


<param name=”


playerID


“></param>


///


<param name=”


isReady


“></param>


public


void


SetPlayerReadyState(


int


playerID,


bool


isReady) {


controller.SetPlayerReadyState(playerID,isReady);


}


public


void


ShowStartGameBtn() {


controller.ShowStartGameBtn();


}


public


override


void


OnEnter()


{


base


.OnEnter();


_canvasGroup.alpha = 1;


UpdatePlayerUIMsg();


}


public


override


void


OnPause()


{


base


.OnPause();


_canvasGroup.alpha = 0;


}


public


override


void


OnResume()


{


base


.OnResume();


_canvasGroup.alpha = 1;


}


public


override


void


OnExit()


{


base


.OnExit();


_canvasGroup.alpha = 0;


controller.ClearPlayerUIList();


//


离开房间时,取消当前玩家的准备状态(新)


SetPlayerReadyState(PhotonNetwork.LocalPlayer.ActorNumber,


false


);


}


}


using


System.Collections;


using


System.Collections.Generic;


using


UnityEngine;


using


UIFrame;


using


Photon.Pun;


using


Photon.Realtime;


public


class


RoomListPanelModule


: UIModuleBase


{


//


对应的控制器


private


RoomListPanelController controller;


public


override


void


Awake


()


{


base


.Awake();


//


创建控制器


controller =


new


RoomListPanelController();


//


绑定控制


BindController(controller);


}


///


<summary>


///


设置房间信息列表


///


</summary>


///


<param name=”


roomInfos


“></param>


public


void


SetRoomInfos(List<RoomInfo> roomInfos) {


//


设置房间信息列表


controller.UpdateRoomList(roomInfos);


}


public


override


void


OnEnter()


{


base


.OnEnter();


_canvasGroup.alpha = 1;


controller.UpdateRoomListUI();


}


public


override


void


OnPause()


{


base


.OnPause();


_canvasGroup.alpha = 0;


}


public


override


void


OnResume()


{


base


.OnResume();


_canvasGroup.alpha = 1;


if


(!PhotonNetwork.InLobby) {


PhotonNetwork.JoinLobby();


}


controller.UpdateRoomListUI();


}


public


override


void


OnExit()


{


base


.OnExit();


_canvasGroup.alpha = 0;


}


}


using


System.Collections;


using


System.Collections.Generic;


using


UnityEngine;


using


UIFrame;


public


class


InfoPanelModule


: UIModuleBase


{


//


创建控制器


private


InfoPanelController controller;


public


override


void


Awake


()


{


base


.Awake();


//


创建控制器


controller =


new


InfoPanelController();


//


绑定控制


BindController(controller);


}


public


override


void


OnEnter()


{


base


.OnEnter();


_canvasGroup.alpha = 1;


controller.SetInfoText(LobbyManager.Instance.infoMessage);


}


public


override


void


OnPause()


{


base


.OnPause();


_canvasGroup.alpha = 0;


}


public


override


void


OnResume()


{


base


.OnResume();


_canvasGroup.alpha = 1;


}


public


override


void


OnExit()


{


base


.OnExit();


_canvasGroup.alpha = 0;


}


}


using


System.Collections;


using


System.Collections.Generic;


using


UnityEngine;


using


UnityEngine.Events;


using


UnityEngine.UI;


using


UIInterface;


using


TMPro;


namespace


UIInterface


{


public


class


UIMono


: MonoBehaviour, IRectTransform, IText, IImage, IRawImage, IButton, IInputField, ItmpTextPro, ITMP_InputFIeld,IGameObject


{


#region


Component


private


RectTransform _rectTransform;


private


Text _text;


private


Image _image;


private


RawImage _rawImage;


private


Button _button;


private


InputField _inputField;


private


TMP_Text _textmesh;


private


TMP_InputField _tmpinputField;


#endregion


#region


Mono Callback


protected


virtual


void


Awake


() {


_rectTransform = GetComponent<RectTransform>();


_text = GetComponent<Text>();


_image = GetComponent<Image>();


_rawImage = GetComponent<RawImage>();


_button = GetComponent<Button>();


_inputField = GetComponent<InputField>();


_textmesh=GetComponent<TMP_Text>();


_tmpinputField = GetComponent<TMP_InputField>();


}


#endregion


public


virtual


void


AddOnClickListener(UnityAction action)


{


_button.onClick.AddListener(action);


}


public


virtual


void


AddOnValueChangeListener(UnityAction<


string


> action)


{


_inputField.onValueChanged.AddListener(action);


}


public


virtual


Color GetImageColor()


{


return


_image.color;


}


public


virtual


string


GetInputFieldText()


{


return


_inputField.text;


}


public


virtual


Sprite GetSprite()


{


return


_image.sprite;


}


public


virtual


void


SetImageColor(Color color)


{


_image.color = color;


}


public


virtual


void


SetInputFieldText(


string


text)


{


_inputField.text = text;


}


public


virtual


void


SetSprite(Sprite sprite)


{


_image.sprite = sprite;


}


public


virtual


void


SetTextColor(Color color)


{


_text.color = color;


}


public


virtual


void


SetTextText(


string


text)


{


_text.text = text;


}


public


virtual


string


GetTextText()


{


return


_text.text;


}


public


void


SetParent(Transform parent)


{


transform.SetParent(parent);


}


public


void


SetParent(Transform parent,


bool


stayWorldPos)


{


transform.SetParent(parent,stayWorldPos);


}


public


void


tmpSetTextText(


string


text)


{


_textmesh.text = text;


}


public


string


tmpGetText()


{


return


_textmesh.text;


}


public


void


tmpSetColor(Color color)


{


_textmesh.color = color;


}


public


void


tmpAddOnValueChangeListener(UnityAction<


string


> action)


{


_tmpinputField.onValueChanged.AddListener(action);


}


public


string


tmpGetInputFieldText()


{


return


_tmpinputField.text;


}


public


void


tmpSetInputFieldText(


string


text)


{


_tmpinputField.text = text;


}


public


void


SetGameObjectActive(


bool


active)


{


gameObject.SetActive(active);


}


}


}


using


System.Collections;


using


System.Collections.Generic;


using


UnityEngine;


namespace


UIInterface {


public


interface


ItmpTextPro


{


void


tmpSetTextText(


string


text);


string


tmpGetText();


void


tmpSetColor(Color color);


}


}


using


System.Collections;


using


System.Collections.Generic;


using


UnityEngine;


using


TMPro;


using


UnityEngine.Events;


namespace


UIInterface {


public


interface


ITMP_InputFIeld


{


void


tmpAddOnValueChangeListener(UnityAction<


string


> action);


string


tmpGetInputFieldText();


void


tmpSetInputFieldText(


string


text);


}


}


using


System.Collections;


using


System.Collections.Generic;


using


UnityEngine;


namespace


UIInterface {


public


interface


IText


{


void


SetTextText(


string


text);


string


GetTextText();


void


SetTextColor(Color color);


}


}


using


System.Collections;


using


System.Collections.Generic;


using


UnityEngine;


namespace


UIInterface


{


public


interface


IRectTransform


{


void


SetParent(Transform parent);


void


SetParent(Transform parent,


bool


stayWorldPos);


}


}


using


System.Collections;


using


System.Collections.Generic;


using


UnityEngine;


using


UIFrame;


public


class


MainPanelModule


: UIModuleBase


{


public


override


void


Awake


()


{


base


.Awake();


//


创建控制器


var


controller =


new


MainPanelController();


//


绑定控制


BindController(controller);


}


public


override


void


OnEnter()


{


base


.OnEnter();


_canvasGroup.interactable =


false


;


}


public


void


ResumePanelInteractable() {


_canvasGroup.interactable =


true


;


}


}


using


System.Collections;


using


System.Collections.Generic;


using


UnityEngine;


using


UnityEngine.Events;


namespace


UIInterface


{


public


interface


IInputField


{


void


AddOnValueChangeListener(UnityAction<


string


> action);


string


GetInputFieldText();


void


SetInputFieldText(


string


text);


}


}


using


System.Collections;


using


System.Collections.Generic;


using


UnityEngine;


namespace


UIInterface


{


public


interface


IImage


{


void


SetSprite(Sprite sprite);


Sprite GetSprite();


void


SetImageColor(Color color);


Color GetImageColor();


}


}


using


System.Collections;


using


System.Collections.Generic;


using


UnityEngine;


namespace


UIInterface {


public


interface


IGameObject


{


void


SetGameObjectActive(


bool


active);


}


}


using


System.Collections;


using


System.Collections.Generic;


using


UnityEngine;


using


UnityEngine.Events;


namespace


UIInterface


{


public


interface


IButton


{


void


AddOnClickListener(UnityAction action);


}


}


using


System.Collections;


using


System.Collections.Generic;


using


UnityEngine;


using


System.Reflection;


using


System;


namespace


UIFrame {


public


class


Singleton


<


T


>


where


T:


class


{


//


单例对象


private


static


T _singleton;


//


获取单例


public


static


T Instance {


get


{


if


(_singleton ==


null


) {


//


如果这样写,那么该类型


T


必有一个


public


的构造函数


//_singleton = new T();


//


通过反射的方式,去实例化一个对象出来


//


派生的单例类中必须要有一个私有的无参构造


_singleton=(T)Activator.CreateInstance(


typeof


(T), nonPublic:


true


);


}


return


_singleton;


}


}


}


}


using


System.Collections;


using


System.Collections.Generic;


using


UnityEngine;


using


UIFrame;


using


System;


namespace


UIFrame {


public


class


JsonDataManager


: Singleton<JsonDataManager>


{


private


JsonDataManager()


{


//Json


解析【


Json


文件


orJsonString




//private void JsonUtilityTest<T>(string json) {


//T result=JsonUtility.FromJson<T>(“json”);


panelDataDic =


new


Dictionary<


int


, Dictionary<


string


,


string


>>();


widgetDataDic =


new


Dictionary<


int


, Dictionary<


string


,


string


>>();


widgetData =


new


JsonWidgetsModel();


heroDataDic =


new


Dictionary<


int


, Dictionary<


int


,


string


>>();


ParsePanelData();


ParseWidgetData();


ParseHeroData();


}


///


<summary>


///


解吸英雄数据


///


</summary>


private


void


ParseHeroData()


{


//


获取配置文本资源


TextAsset heroConfig = AssetsManager.Instance.GetAsset(SystemDefine.HeroConfigPath)


as


TextAsset;


//





widget


的配置文件进行解析


heroData = JsonUtility.FromJson<JsonHeroModel>(heroConfig.text);


//





Widget


转换为方便检索的字典


for


(


int


i = 0; i < heroData.AllData.Length; i++)


{


//


创建一个字典


Dictionary<


int


,


string


> crtDic =


new


Dictionary<


int


,


string


>();


//


添加一个场景


ID


和一个字典


heroDataDic.Add(i, crtDic);


//


遍历当前场景内所有


Panel


路径资源


for


(


int


j = 0; j < heroData.AllData[i].Data.Length; j++)


{


//





PanelName





Key


,以


PanelPath





value


进行存储


crtDic.Add(heroData.AllData[i].Data[j].HeroIndex, heroData.AllData[i].Data[j].HeroPath);


}


}


}


#region


Json Parse


///


<summary>


///


解析动态元件数据


///


</summary>


private


void


ParseWidgetData()


{


//


获取配置文本资源


TextAsset widgetConfig = AssetsManager.Instance.GetAsset(SystemDefine.WidgetConfigPath)


as


TextAsset;


//





widget


的配置文件进行解析


widgetData = JsonUtility.FromJson<JsonWidgetsModel>(widgetConfig.text);


//





Widget


转换为方便检索的字典


for


(


int


i = 0; i < widgetData.AllData.Length; i++)


{


//


创建一个字典


Dictionary<


string


,


string


> crtDic =


new


Dictionary<


string


,


string


>();


//


添加一个场景


ID


和一个字典


widgetDataDic.Add(i, crtDic);


//


遍历当前场景内所有


Panel


路径资源


for


(


int


j = 0; j < widgetData.AllData[i].Data.Length; j++)


{


//





PanelName





Key


,以


PanelPath





value


进行存储


crtDic.Add(widgetData.AllData[i].Data[j].WidgetName, widgetData.AllData[i].Data[j].WidgetPath);


}


}


}


#endregion


#region


Saved Structure


//Panel


解析后的数据


JsonPanelsModel panelData;


//Panel


解析后的数据【字典版】


private


Dictionary<


int


,Dictionary<


string


,


string


>> panelDataDic;


//Widget


解析后的数据


JsonWidgetsModel widgetData;


//Widget


解析后的数据【字典版】


private


Dictionary<


int


, Dictionary<


string


,


string


>> widgetDataDic;


//Hero


解析后的数据


JsonHeroModel heroData;


//Hero


解析后的数据【字典版】


private


Dictionary<


int


, Dictionary<


int


,


string


>>heroDataDic;


#endregion


#region


DataFind


//Json


解析【


Json


文件


orJsonString




private


void


ParsePanelData() {


//


获取配置文本资源


TextAsset panelConfig = AssetsManager.Instance.GetAsset(SystemDefine.PanelConfigPath)


as


TextAsset;


//





Panel


的配置文件进行解析


panelData= JsonUtility.FromJson<JsonPanelsModel>(panelConfig.text);


//





PanelData


转换为方便检索的字典


for


(


int


i=0;i<panelData.AllData.Length;i++) {


//


创建一个字典


Dictionary<


string


,


string


> crtDic =


new


Dictionary<


string


,


string


>();


//


添加一个场景


ID


和一个字典


panelDataDic.Add(i,crtDic);


//


遍历当前场景内所有


Panel


路径资源


for


(


int


j=0;j<panelData.AllData[i].Data.Length;j++) {


//





PanelName





Key


,以


PanelPath





value


进行存储


crtDic.Add(panelData.AllData[i].Data[j].PanelName, panelData.AllData[i].Data[j].PanelPath);


}


}


}


///


<summary>


///


通过


Panel


名称返回


Panel


的资源路径


///


</summary>


///


<param name=”


panelName


“></param>


///


<returns></returns>


public


string


FindPanelPath(


string


panelName,


int


sceneID = (


int


)SystemDefine.SceneID.MainScene) {


if


(!panelDataDic.ContainsKey(sceneID))


return


null


;


if


(!panelDataDic[sceneID].ContainsKey(panelName))


return


null


;


//


如果


ID





Panel


在字典中都存在,则直接返回


return


panelDataDic[sceneID][panelName];


}


///


<summary>


///


通过元件名称找到其对应的路径


///


</summary>


///


<param name=”


panelName


“></param>


///


<returns></returns>


public


string


FindWidgetPath(


string


widgetName,


int


sceneID = (


int


)SystemDefine.SceneID.MainScene)


{


if


(!widgetDataDic.ContainsKey(sceneID))


return


null


;


if


(!widgetDataDic[sceneID].ContainsKey(widgetName))


return


null


;


//


如果


ID





Widget


在字典中都存在,则直接返回


return


widgetDataDic[sceneID][widgetName];


}


///


<summary>


///


通过英雄


ID


获取资源路径


///


</summary>


///


<param name=”


heroIndex


“></param>


///


<param name=”


sceneID


“></param>


///


<returns></returns>


public


string


FindHeroPath(


int


heroIndex,


int


sceneID = (


int


)SystemDefine.SceneID.MainScene)


{


if


(!heroDataDic.ContainsKey(sceneID))


return


null


;


if


(!heroDataDic[sceneID].ContainsKey(heroIndex))


return


null


;


//


如果


ID





Widget


在字典中都存在,则直接返回


return


heroDataDic[sceneID][heroIndex];


}


#endregion


}


}


using


System.Collections;


using


System.Collections.Generic;


using


UnityEngine;


namespace


UIFrame


{


public


class


AssetsManager


: Singleton<AssetsManager>


{


//


私有构造


private


AssetsManager() {


assetsCache =


new


Dictionary<


string


, Object>();


}


///


<summary>


///


资源缓存


///


</summary>


private


Dictionary<


string


, Object> assetsCache;


///


<summary>


///


获取资源


///


</summary>


///


<typeparam name=”


T


“></typeparam>


///


<param name=”


path


“>


资源路径


</param>


///


<returns></returns>


public


Object OldGetAsset<


T


>(


string


path)


{


//


要返回的资源


Object assetObj =


null


;


//


如果缓存中没有该资源


if


(!assetsCache.ContainsKey(path))


{


//


通过


resources


加载资源


assetObj = Resources.Load(path);


//


将资源存进缓存


assetsCache.Add(path, assetObj);


}


else


{


//


如果缓存中有,则直接从缓存中拿


assetObj = assetsCache[path];


}


return


assetObj;


}


///


新方法





获取资源


public


Object GetAsset(


string


path) {


//


要返回的资源


Object assetObj =


null


;


//


尝试从字典中获取该路径所对应的资源


if


(!assetsCache.TryGetValue(path,


out


assetObj))


{


//


通过


resources


加载资源


assetObj = Resources.Load(path);


//


将资源存进缓存


assetsCache.Add(path, assetObj);


}


return


assetObj;


}


}


}


using


System.Collections;


using


System.Collections.Generic;


using


UnityEngine;


using


UIFrame;


using


UIInterface;


namespace


UIFrame


{


public


class


UIWidgetBase


: UIMono


{


//


当前元件所处的模块


private


UIModuleBase currentModule;


//


临时参数


private


ArrayList tempParameters;


///


<summary>


///


设置临时参数


///


</summary>


///


<param name=”


para


“></param>


public


void


SetTemParamters(


object


para) {


if


(tempParameters ==


null


) {


tempParameters =


new


ArrayList();


}


if


(!tempParameters.Contains(para)) {


tempParameters.Add(para);


}


}


///


<summary>


///


获取临时参数


///


</summary>


///


<param name=”


index


“></param>


///


<returns></returns>


public


object


GetTempParamter(


int


index) {


return


tempParameters[index];


}


public


void


UIWidgetInit(UIModuleBase uiModuleBase) {


//


设置当前所属模块


currentModule = uiModuleBase;


//


将当前元件,添加到


UIManager


的字典中


UIManager.Instance.addUIWidget(currentModule.name, widgetName: name, uiWidget:


this


);


}


protected


virtual


void


OnDestroy


()


{




将当前元件,从


UIManager


的字典中移除


UIManager.Instance.RemoveUIWidget(currentModule.name, widgetName: name);


}


}


}


using


System.Collections;


using


System.Collections.Generic;


using


UnityEngine;


public


class


UIType


{


public


string


Name {


get


;


set


; }


public


string


Path {


get


;


set


; }


public


UIType(


string


path) {


Path = path;


//eg.Panels/MainScene/MainPanel


//MainPanel


//Substring(17,3) 17


以后的


3


个字母


//


通过


Path


的字符串拿到其中名字


//


最后一个斜杠后面的就是


Path


所对应的名字


Name = path.Substring(path.LastIndexOf(


“/”


)+1);


}


}


using


System.Collections;


using


System.Collections.Generic;


using


UnityEngine;


namespace


UIFrame


{


public


static


class


SystemDefine


{


#region


Configuration Path


public


const


string


PanelConfigPath =


“Configuration/UIPanelConfig”


;


public


const


string


WidgetConfigPath =


“Configuration/UIWidgetConfig”


;


public


const


string


HeroConfigPath =


“Configuration/HeroConfig”


;


public


const


string


ClickParticlePath =


“Particles/Fire”


;


#endregion


#region


Scene ID


public


enum


SceneID


{


MainScene=0,


FightScene=1


}


#endregion


#region


Widget Token


public


static


string


[] WIDGET_TOKENS =


new


string


[] {


“_F”


,


“_S”


,


“_T”


};


#endregion


#region


PlayerColors


public


static


Color[] PLAYER_COLORS;


#endregion


#region


Static Constructor


static


SystemDefine() {


PLAYER_COLORS =


new


[] {


Color.red,


Color.blue,


Color.gray,


Color.green,


Color.cyan


};


}


#endregion


}


}


using


System.Collections;


using


System.Collections.Generic;


using


UnityEngine;


using


UIFrame;


namespace


UIFrame {


///


<summary>


///


子类挂载在每一个


Panel


模块上


///


</summary>


///


当前模块组件依赖于


CanvasGroup


[RequireComponent(


typeof


(CanvasGroup))]


public


class


UIModuleBase


: MonoBehaviour


{


protected


CanvasGroup _canvasGroup;


///


<summary>


///


所有的子对象


///


</summary>


private


Transform[] allChild;


public


virtual


void


Awake() {


_canvasGroup = GetComponent<CanvasGroup>();


//


获取当前模块的所有子对象


allChild = GetComponentsInChildren<Transform>();


//


修改当前模块的名称


[


去掉


Clone]


gameObject.name = gameObject.name.Remove(gameObject.name.Length-


“(Clone)”


.Length);


//


给所有可用的


UI


元件添加行为


AddWidgetBehaviour();


}


#region


Controller Bind


protected


void


BindController(UIControllerBase controllerBase) {


controllerBase.ControllerInit(


this


);


}


#endregion


#region


Set Widgets


private


void


AddWidgetBehaviour() {


//


遍历所有的子对象


for


(


int


i=0;i<allChild.Length;i++) {


//


遍历所有标记


Token


for


(


int


j = 0; j < SystemDefine.WIDGET_TOKENS.Length; j++) {


//


判断当前元件对象是否以该标记作为名称结尾的


if


(allChild[i].name.EndsWith(SystemDefine.WIDGET_TOKENS[j])) {


//


添加组件


AddComponentForWidget(i);


}


}


}


}


protected


virtual


void


AddComponentForWidget(


int


index) {


//


给该元件添加


UIWidgetBase


组件


UIWidgetBase uiWidgetBase=allChild[index].gameObject.AddComponent<UIWidgetBase>();


//


设置该元件的模块是


this


uiWidgetBase.UIWidgetInit(uiModuleBase:


this


);


}


#endregion


#region


Find Widget


public


UIWidgetBase FindCurrentModuleWidget(


string


widgetName) {


return


UIManager.Instance.FindWidget(moduleName:name,widgetName:widgetName);


}


#endregion


///


<summary>


///


进入当前模块执行该函数


///


</summary>


public


virtual


void


OnEnter() {


_canvasGroup.blocksRaycasts =


true


;


//


当前窗口在


Canvas


中的最后一个位置,保证显示最前面


transform.SetSiblingIndex(transform.parent.childCount-1);


}


///


<summary>


///


离开当前模块执行该函数


///


</summary>


public


virtual


void


OnExit() {


_canvasGroup.blocksRaycasts =


false


;


}


///


<summary>


///


暂离当前模块执行该函数


///


</summary>


public


virtual


void


OnPause() {


_canvasGroup.blocksRaycasts =


false


;


}


///


<summary>


///


恢复当前模块执行该函数


///


</summary>


public


virtual


void


OnResume() {


_canvasGroup.blocksRaycasts =


true


;


}


}


}


using


System.Collections;


using


System.Collections.Generic;


using


UnityEngine;


using


UIFrame;


namespace


UIFrame


{


///


<summary>


///


专注于写


UI


中的业务逻辑


///


</summary>


public


class


UIControllerBase


{


//


当前所处模块


public


UIModuleBase crtModule;


public


void


ControllerInit(UIModuleBase moduleBase) {


crtModule = moduleBase;


//


启动


ControllerStart();


}


protected


virtual


void


ControllerStart() {


}


}


}


using


System.Collections;


using


System.Collections.Generic;


using


UnityEngine;


namespace


UIFrame {


[System.Serializable]


public


class


JsonWidgetsModel


{


public


SceneWidgetDataModel[] AllData;


}


[System.Serializable]


public


class


SceneWidgetDataModel


{


public


string


SceneName;


public


WidgetDataModel[] Data;


}


[System.Serializable]


public


class


WidgetDataModel


{


public


string


WidgetName;


public


string


WidgetPath;


}


}


using


System;


using


System.Collections;


using


System.Collections.Generic;


using


UnityEngine;


namespace


UIFrame {


[System.Serializable]


public


class


JsonPanelsModel


{


public


SceneDataModel[] AllData;


public


static


implicit


operator


JsonPanelsModel(JsonWidgetsModel v)


{


throw


new


NotImplementedException();


}


}


[System.Serializable]


public


class


SceneDataModel


{


public


string


SceneName;


public


PanelDataModel[] Data;


}


[System.Serializable]


public


class


PanelDataModel


{


public


string


PanelName;


public


string


PanelPath;


}


}


using


System.Collections;


using


System.Collections.Generic;


using


UnityEngine;


namespace


UIFrame


{


[System.Serializable]


public


class


JsonHeroModel


{


public


SceneHeroDataModel[] AllData;


}


[System.Serializable]


public


class


SceneHeroDataModel


{


public


string


SceneName;


public


HeroDataModel[] Data;


}


[System.Serializable]


public


class


HeroDataModel


{


public


int


HeroIndex;


public


string


HeroPath;


}


}


using


System.Collections;


using


System.Collections.Generic;


using


UnityEngine;


using


UIFrame;


namespace


UIFrame


{


public


class


UITypeManager


: Singleton<UITypeManager>


{


private


UITypeManager() {


_uiTypes =


new


Dictionary<


string


, UIType>();


}


//UIType


的缓冲池


private


Dictionary<


string


, UIType> _uiTypes;


///


<summary>


///


通过


UIPanelName


名称,获取其


UIType


///


</summary>


///


<param name=”


uiPanelName


“></param>


public


UIType GetUIType(


string


uiPanelName) {


//


要返回的


UITYPE


UIType uiType =


null


;


//


如果缓存池内没有该


Key


if


(!_uiTypes.TryGetValue(uiPanelName,


out


uiType)) {


//


实例化一个新的


UIType


uiType =


new


UIType(


JsonDataManager.Instance.FindPanelPath(uiPanelName)


);


//


添加到字典


_uiTypes.Add(uiPanelName,uiType);


}


return


uiType;


}


}


}


using


System.Collections;


using


System.Collections.Generic;


using


UnityEngine;


using


UIFrame;


namespace


UIFrame {


public


class


UIManager


:Singleton<UIManager> {


private


UIManager() {


uiModuleList =


new


List<UIModuleBase>();


uiModules =


new


Dictionary<UIType, UIModuleBase>();


_canvas = GameObject.Find(


“Canvas”


).transform;


uiModuleStack =


new


Stack<UIModuleBase>();


uiWidgets=


new


Dictionary<


string


, Dictionary<


string


, UIWidgetBase>>();


}


//UI


模块的栈存储


private


Stack<UIModuleBase> uiModuleStack;


//UIType.Path—>GameObject


里的


UIModule


组件


//


管理当前场景的所有


UI


模块


private


Dictionary<UIType, UIModuleBase> uiModules;


//


管理当前场景的所有


UI


元件


private


Dictionary<


string


,Dictionary<


string


,UIWidgetBase>> uiWidgets;


//


当前场景中的画布


private


Transform _canvas;


//UI


模块的列表存储


private


List<UIModuleBase> uiModuleList;


#region


UI Module GameObject


///


<summary>


///


通过名字去获取模块


///


</summary>


///


<param name=”


uiPanelName


“></param>


///


<returns></returns>


public


UIModuleBase GetUIModuleByName(


string


uiPanelName) {


//


获取


UIType


UIType _uiType = UITypeManager.Instance.GetUIType(uiPanelName);


//


获取


UIModuleBase


return


GetUIModule(_uiType);


}


///


<summary>


///


通过


UIType


获取该


Type


所对应的模块游戏对象身上的


UIModuleBase


///


</summary>


///


<param name=”


uiType


“></param>


///


<returns></returns>


private


UIModuleBase GetUIModule(UIType uiType) {


//


当前要返回的模块


UIModuleBase crtModule =


null


;


//


如果字典中没有该模块


if


(!uiModules.TryGetValue(uiType,


out


crtModule))


{


//Instantiate


生成该模块


crtModule= InstantiateUIModule(prefab: AssetsManager.Instance.GetAsset(uiType.Path)


as


GameObject);


//


将该模块添加到字典中


uiModules.Add(uiType,crtModule);


}


else


if


(uiModules[uiType]==


null


) {


//Instantiate


生成该模块


crtModule = InstantiateUIModule(prefab: AssetsManager.Instance.GetAsset(uiType.Path)


as


GameObject);


//


将该模块更新到字典中


uiModules[uiType]=crtModule;


}


return


crtModule;


}


private


UIModuleBase InstantiateUIModule(GameObject prefab) {


//


生成当前模块


GameObject crtModuleObj=GameObject.Instantiate(prefab);


//


设置父物体为画布


crtModuleObj.transform.SetParent(_canvas, worldPositionStays:


false


);


//


等价于


crtModuleObj.transform.localPosition = Vector3.zero;


//


返回组件


return


crtModuleObj.GetComponent<UIModuleBase>();


}


#endregion


///


<summary>


///


通过


PanelName


获取模块对象并压栈


///


</summary>


///


<param name=”


uiPanelName


“></param>


#region


UI Module Stack


public


void


PushUI(


string


uiPanelName) {


//


获取


UIType


UIType _uiType=UITypeManager.Instance.GetUIType(uiPanelName);


//


获取


UIModuleBase


UIModuleBase crtModuleBase=GetUIModule(_uiType);


//


如果栈里面有元素


if


(uiModuleStack.Count!=0) {


//


此时栈顶的窗口进入暂停状态


uiModuleStack.Peek().OnPause();


}


//


进入窗口压栈


uiModuleStack.Push(crtModuleBase);


//


新窗口执行


Enter


crtModuleBase.OnEnter();


}


///


<summary>


///


栈顶元素出栈


///


</summary>


public


void


PopUI() {


if


(uiModuleStack.Count != 0)


{


//


当前栈顶元素出栈,并执行离开的回调方法


uiModuleStack.Pop().OnExit();


}


else


{


Debug.LogWarning(message:


“UI


栈中没有元素,无法出栈!





);


}


//


栈顶元素出栈后,栈内还有没有元素


if


(uiModuleStack.Count!=0) {


uiModuleStack.Peek().OnResume();


}


}


#endregion


#region


UI Module list


public


void


ShowUI(


string


uiPanelName)


{


//


获取


UIType


UIType _uiType = UITypeManager.Instance.GetUIType(uiPanelName);


//


获取


UIModuleBase


UIModuleBase crtModuleBase = GetUIModule(_uiType);


if


(!uiModuleList.Contains(crtModuleBase)) {


//


添加到列表


uiModuleList.Add(crtModuleBase);


}


//


新窗口执行


Enter


crtModuleBase.OnEnter();


}


#endregion


///


<summary>


///


注册


UI


模块


///


</summary>


///


<param name=”


moduleName


“>


模块名称


</param>


#region


UI Widgets->Module (Un)Register


private


void


RegisterUIModuleToUIWidgets(


string


moduleName) {


if


(!uiWidgets.ContainsKey(moduleName))


{


//


向字典添加元素


uiWidgets.Add(moduleName,


new


Dictionary<


string


, UIWidgetBase>());


}


else


{


//Debug.Log(message:”


该模块已经存在!


“);


}


}


///


<summary>


///


取消注册


UI


模块


///


</summary>


///


<param name=”


moduleName


“></param>


public


void


UnRegisterUiModuleFromUIWidgets(


string


moduleName) {


if


(uiWidgets.ContainsKey(moduleName))


{


//


从字典中移除该元素


uiWidgets.Remove(moduleName);


}


else


{


Debug.LogWarning(message:





无法取消注册该模块,因为无该模块。





);


}


}


#endregion


#region


UI Widgets Add/Remove


///


<summary>


///


添加元件


///


</summary>


///


<param name=”


moduleName


“>


模块名称


</param>


///


<param name=”


widgetName


“>


元件名称


</param>


///


<param name=”


uiWidgetBase


“>


元件对象


</param>


public


void


addUIWidget(


string


moduleName,


string


widgetName,UIWidgetBase uiWidget) {


//


如果模块不存在,添加模块


RegisterUIModuleToUIWidgets(moduleName);


//


如果字典中已经存在该元件


if


(uiWidgets[moduleName].ContainsKey(widgetName))


{


Debug.LogWarning(message:





该元件已经再字典中存在,无需再添加


…”


);


}


else


{


uiWidgets[moduleName].Add(widgetName,uiWidget);


}


}


///


<summary>


///


移除元件


///


</summary>


///


<param name=”


moduleName


“>


模块名称


</param>


///


<param name=”


widgetName


“>


元件名称


</param>


public


void


RemoveUIWidget(


string


moduleName,


string


widgetName) {


if


(uiWidgets[moduleName].ContainsKey(widgetName))


{


//


移除该元件


uiWidgets[moduleName].Remove(widgetName);


}


else


{


Debug.LogWarning(message:





该元件在字典中不存在


…”


);


}


}


#endregion


///


<summary>


///


获取某个模块的某个元件


///


</summary>


///


<param name=”


moduleName


“>


模块


</param>


///


<param name=”


widgetName


“>


元件


</param>


///


<returns></returns>


#region


Find Widget


public


UIWidgetBase FindWidget(


string


moduleName,


string


widgetName) {


//


如果模块不存在


,


注册模块


RegisterUIModuleToUIWidgets(moduleName);


//


要返回的


UIModle


UIWidgetBase uiWidget =


null


;


//


尝试获取该元件,如果没有获取到,返回


Null


uiWidgets[moduleName].TryGetValue(widgetName,


out


uiWidget);


return


uiWidget;


}


#endregion


#region


Dynamic Widget Instantiate


public


GameObject CreateDynamicWidget(


string


widgetName) {


//


获取元件的资源路径


string


widgetPath=JsonDataManager.Instance.FindWidgetPath(widgetName);


//


获取预设体


GameObject prefab=AssetsManager.Instance.GetAsset(widgetPath)


as


GameObject;


//


创建对象


return


GameObject.Instantiate(prefab);


}


///


<summary>


///


创建动态元件,并设置父物体


///


</summary>


///


<param name=”


widgetName


“></param>


///


<param name=”


parent


“></param>


///


<param name=”


worldPosStays


“></param>


///


<returns></returns>


public


GameObject CreateDynamicWidget(


string


widgetName,Transform parent,


bool


worldPosStays) {


//


创建对象


GameObject obj=CreateDynamicWidget(widgetName);


//Debug.Log(“CreateDynamicWidget”+obj);


//


设置父物体


obj.transform.SetParent(parent,worldPosStays);


return


obj;


}


#endregion


}


}


using


System.Collections;


using


System.Collections.Generic;


using


UnityEngine;


using


UIFrame;


public


class


GameFacade


: MonoBehaviour {


private


void


Start()


{


//


启动游戏


UIManager.Instance.PushUI(


“MainPanel”


);


}


}


using


System.Collections;


using


System.Collections.Generic;


using


UnityEngine;


using


UIFrame;


using


Photon.Pun;


using


Photon.Realtime;


using


UnityEngine.UI;


public


class


TopPanelController


: UIControllerBase


{


protected


override


void


ControllerStart()


{


base


.ControllerStart();


Debug.Log(


“TopPanel Start!”


);


BindEvent();


}


protected


void


BindEvent() {


//crtModule


crtModule.FindCurrentModuleWidget(


“BackButton_F”


).AddOnClickListener(()=> {


//


离开房间和大厅


if


(PhotonNetwork.InLobby)


{


PhotonNetwork.LeaveLobby();


}


else


if


(PhotonNetwork.InRoom) {


PhotonNetwork.LeaveRoom();


}


//


暂时


UIManager.Instance.PopUI();


UIManager.Instance.PopUI();


});


Debug.Log(PhotonNetwork.NetworkClientState);


MonoHelper.Instance.InvokeRepeat(method:()=> { crtModule.FindCurrentModuleWidget(


“StatusInfo_F”


).SetTextText(


“Status: ”


+ PhotonNetwork.NetworkClientState); },0,()=> {


return


false


; });


}


}


using


System.Collections;


using


System.Collections.Generic;


using


UnityEngine;


using


UIFrame;


using


Photon.Pun;


using


Photon.Realtime;


public


class


RoomPanelController


: UIControllerBase


{


///


<summary>


///


当前房间的所有玩家


///


</summary>


Dictionary<


int


, GameObject> roomPlayers;


protected


override


void


ControllerStart()


{


base


.ControllerStart();


roomPlayers =


new


Dictionary<


int


, GameObject>();


crtModule.FindCurrentModuleWidget(


“StartGameButton_F”


).AddOnClickListener(() =>


{


//


加载进入游戏场景


PhotonNetwork.LoadLevel(


“CompleteMainScene”


);


}


);


}


private


void


BindEvent() {


}


///


<summary>


///


清空玩家列表


///


</summary>


public


void


ClearPlayerUIList() {


foreach


(var item


in


roomPlayers) {


//


销毁游戏对象


GameObject.Destroy(item.Value);


}


//


清理


roomPlayers.Clear();


}


private


void


GeneratePlayerUIList() {


Transform parent = crtModule.FindCurrentModuleWidget(


“PlayerList_F”


).transform;


for


(


int


i = 0; i < PhotonNetwork.PlayerList.Length; i++) {


//


生成一个玩家


GameObject tempPlayer=UIManager.Instance.CreateDynamicWidget(


“PlayerInfo”


,parent,


false


);


//


执行玩家初始化


tempPlayer.GetComponent<PlayerBehaviour>().PlayerInit(PhotonNetwork.PlayerList[i]);


//


添加到字典


roomPlayers.Add(PhotonNetwork.PlayerList[i].ActorNumber, tempPlayer);


}


}


//


更新玩家信息


public


void


UpdatePlayerMsg() {


ClearPlayerUIList();


GeneratePlayerUIList();


}


///


<summary>


///


设置玩家准备状态


///


</summary>


///


<param name=”


playerID


“></param>


///


<param name=”


isReady


“></param>


public


void


SetPlayerReadyState(


int


playerID,


bool


isReady) {


if


(!roomPlayers.ContainsKey(playerID))


return


;


roomPlayers[playerID].GetComponent<PlayerBehaviour>().SetReadyStateUI(isReady);


}


//




public


void


SetPlayerReadyStateHash(


int


playerID,


bool


isReady) {


if


(!roomPlayers.ContainsKey(playerID))


return


;


roomPlayers[playerID].GetComponent<PlayerBehaviour>().SetPlayerReadyState(isReady);


}


///


<summary>


///


显示游戏开始按钮


///


</summary>


public


void


ShowStartGameBtn() {


//1.


当前玩家是主客户端


//2


:房间里的所有玩家都已经准备


crtModule.FindCurrentModuleWidget(


“StartGameButton_F”


).SetGameObjectActive(PhotonNetwork.IsMasterClient&&AllPlayerHasReady());


}


///


<summary>


///


是否所有玩家都已经准备


///


</summary>


///


<returns></returns>


private


bool


AllPlayerHasReady() {


foreach


(var item


in


roomPlayers) {


//


如果遍历到任意一个玩家没有准备,则不能开始游戏


if


(!item.Value.GetComponent<PlayerBehaviour>().isReady) {


return


false


;


}


}


//


能运行到此处,说明所有玩家都已经准备


return


true


;


}


}


using


System.Collections;


using


System.Collections.Generic;


using


UnityEngine;


using


Photon.Pun;


using


UIFrame;


using


Photon.Realtime;


public


class


RoomListPanelController


: UIControllerBase


{


//


房间信息


public


List<RoomInfo> roomInfos;


//


所有的房间


Dictionary<


string


, RoomBehaviour> rooms;


protected


override


void


ControllerStart()


{


base


.ControllerStart();


roomInfos =


new


List<RoomInfo>();


rooms =


new


Dictionary<


string


, RoomBehaviour>();


}


public


void


UpdateRoomList(List<RoomInfo> roomInfos) {


this


.roomInfos = roomInfos;


UpdateRoomListUI();


}


void


ClearRoomListUI() {


foreach


(var item


in


rooms) {


//


销毁房间信息的游戏对象


GameObject.Destroy(item.Value.gameObject);


}


//


清除


rooms.Clear();


}


private


void


ShowRoomListUI() {


//


找到父对象


Transform parent = crtModule.FindCurrentModuleWidget(


“RoomList_F”


).transform;


//


遍历


RoomInfos


foreach


(var item


in


roomInfos) {


if


(!item.IsOpen)


continue


;


if


(!item.IsVisible)


continue


;


if


(item.MaxPlayers == 0)


continue


;


//


生成一个房间


GameObject tempRoom = UIManager.Instance.CreateDynamicWidget(


“RoomInfo”


, parent,


false


);


//


执行房间初始化


tempRoom.GetComponent<RoomBehaviour>().RoomInit(item);


//


添加到字典


rooms.Add(item.Name, tempRoom.GetComponent<RoomBehaviour>());


}


}


public


void


UpdateRoomListUI() {


ClearRoomListUI();


ShowRoomListUI();


}


}


using


System.Collections;


using


System.Collections.Generic;


using


UnityEngine;


using


UIFrame;


public


class


InfoPanelController


: UIControllerBase


{


protected


override


void


ControllerStart()


{


base


.ControllerStart();


crtModule.FindCurrentModuleWidget(


“CancelButton_F”


).AddOnClickListener(()=> { UIManager.Instance.PopUI(); });


BindEvent();


}


private


void


BindEvent()


{


}


public


void


SetInfoText(


string


text) {


crtModule.FindCurrentModuleWidget(


“Text _F”


).tmpSetTextText(text);


}


}


using


System.Collections;


using


System.Collections.Generic;


using


UnityEngine;


using


Photon.Pun;


using


Photon.Realtime;


using


TMPro;


using


UnityEngine.UI;


public


class


RoomBehaviour


: MonoBehaviour


{


private


RoomInfo _roomInfo;


#region


UI Field


private


TMP_Text roomNameText;


private


TMP_Text slotsText;


private


Button joinButton;


#endregion


private


void


Awake


()


{


roomNameText = transform.GetChild(0).GetComponent<TMP_Text>();


slotsText = transform.GetChild(1).GetComponent<TMP_Text>();


joinButton = transform.GetChild(2).GetComponent<Button>();


}


public


void


RoomInit(RoomInfo roomInfo)


{


_roomInfo = roomInfo;


roomNameText.text = roomInfo.Name;


joinButton.onClick.AddListener(


() => {


//


离开大厅


PhotonNetwork.LeaveLobby();


//


进入房间


PhotonNetwork.JoinRoom(roomInfo.Name);


}


);


}


private


void


Update


()


{


slotsText.text = _roomInfo.PlayerCount +


“/”


+ _roomInfo.MaxPlayers;


}


}


using


System.Collections;


using


System.Collections.Generic;


using


UnityEngine;


using


Photon.Pun;


using


Photon.Realtime;


using


UnityEngine.UI;


using


UIFrame;


using


TMPro;


using


UIInterface;


using


UnityEngine.Events;


using


ExitGames.Client.Photon;


namespace


UIFrame


{


public


class


PlayerBehaviour


: MonoBehaviour, IButton


{


//


当前玩家


private


Player _player;


#region


UI Field


private


Image color;


private


TMP_Text playerName;


private


Button readyButton;


private


Button notReadyButton;


private


GameObject hasReadySign;


#endregion


//


当前玩家是否准备


public


bool


isReady =


false


;


private


void


Awake


()


{


color = transform.Find(


“Color”


).GetComponent<Image>();


playerName = transform.Find(


“PlayerName”


).GetComponent<TMP_Text>();


readyButton = transform.Find(


“ReadyButton”


).GetComponent<Button>();


//


标记玩家是否已经准备


hasReadySign = readyButton.transform.Find(


“isReadySign”


).gameObject;


notReadyButton = transform.Find(


“NonReadyButton”


).GetComponent<Button>();


//


绑定点击事件


readyButton.onClick.AddListener(OnReadyButtonClick);


}


private


void


OnReadyButtonClick()


{


if


(!_player.IsLocal)


return


;


bool


crtReadyState = GetPlayerReadyState();


//


设置当前玩家准备状态【新】


SetPlayerReadyState(!crtReadyState);


}


///


<summary>


///


设置当前玩家准备状态【新】


///


</summary>


///


<param name=”


isReady


“></param>


public


void


SetPlayerReadyState(


bool


isReady)


{


ExitGames.Client.Photon.Hashtable hashtable =


new


ExitGames.Client.Photon.Hashtable();


hashtable.Add(GameConst.READY_PROPERTY, isReady);


//


设置


_player.SetCustomProperties(hashtable);


//


触发自己的


UI


变化


SetReadyStateUI(isReady);


//readyButton.gameObject.SetActive(!isReady);


// notReadyButton.gameObject.SetActive(isReady);


}


///


<summary>


///


玩家初始化


///


</summary>


///


<param name=”


player


“></param>


public


void


PlayerInit(Player player)


{


_player = player;


playerName.text = player.NickName;


//


设置玩家编号所对应的颜色显示


color.color = GameConst.PLAYER_COLORS[(player.ActorNumber – 1) % GameConst.PLAYER_COLORS.Length];


if


(player.IsLocal)


{


readyButton.gameObject.SetActive(


true


);


notReadyButton.gameObject.SetActive(


false


);


}


else


{


readyButton.gameObject.SetActive(


false


);


notReadyButton.gameObject.SetActive(


true


);


}


//


关于准备状态


SetReadyStateUI((GetPlayerReadyState()));


}


public


void


AddOnClickListener(UnityAction action)


{


throw


new


System.NotImplementedException();


}


///


<summary>


///


获取玩家的准备状态


///


</summary>


///


<returns></returns>


private


bool


GetPlayerReadyState()


{


//


结果


object


result =


null


;


//


尝试获取准备属性


_player.CustomProperties.TryGetValue(GameConst.READY_PROPERTY,


out


result);


if


(result ==


null


)


return


false


;


return


(


bool


)result;


}


///


<summary>


///


设置当前玩家的准备状态


UI


///


</summary>


public


void


SetReadyStateUI(


bool


isReady)


{


this


.isReady = isReady;


hasReadySign.SetActive(isReady);


//


如果玩家不是





自己





,准备按钮要看准备的状态


if


(!_player.IsLocal)


{


readyButton.gameObject.SetActive(isReady);


readyButton.interactable =


false


;


notReadyButton.gameObject.SetActive(!isReady);


}


}


}


}


using


System;


using


System.Collections;


using


System.Collections.Generic;


using


UnityEngine;


using


Photon.Pun;


public


class


MonoHelper


: MonoBehaviour


{


public


static


MonoHelper Instance;


private


void


Awake


()


{


Instance =


this


;


}


///


<summary>


///


持续执行某个函数


///


</summary>


///


<param name=”


method


“></param>


///


<param name=”


interval


“></param>


///


<param name=”


endCondition


“></param>


public


void


InvokeRepeat(Action method,


float


interval,Func<


bool


> endCondition) {


StartCoroutine(RepeatCRT(method, interval, endCondition));


}


IEnumerator RepeatCRT(Action method,


float


interval, Func<


bool


> endCondition) {


while


(


true


) {


if


(interval <= 0) {


yield


return


0; }


else


{


yield


return


new


WaitForSeconds(interval); }


//


执行事件


method();


//


判断结束条件是否达成


if


(endCondition())


yield


break


;


}


}


}


using


System.Collections;


using


System.Collections.Generic;


using


UnityEngine;


using


Photon.Pun;


using


UIFrame;


using


Photon.Realtime;


using


ExitGames.Client.Photon;


public


class


LobbyManager


: MonoBehaviourPunCallbacks


{


public


static


LobbyManager Instance;


public


string


infoMessage=


“”


;


//


获取房间模块


//private RoomPanelModule roomPanel;


//


获取大厅模块


private


RoomListPanelModule roomListPannel;


private


void


Awake


()


{


Instance =


this


;


//


设置为当前对象在过渡场景时不要销毁


//DontDestroyOnLoad(gameObject);


//


支持后台运行


Application.runInBackground =


true


;


//


机制网络场景同步


PhotonNetwork.AutomaticallySyncScene =


true


;


//


实例化房间列表


//rooms = new List<RoomInfo>();


}


// Start is called before the first frame update


void


Start


()


{


//


连接云服务器


PhotonNetwork.ConnectUsingSettings();


//roomPanel = UIManager.Instance.GetUIModuleByName(“RoomPanel”) as RoomPanelModule;


//roomListPannel = UIManager.Instance.GetUIModuleByName(“RoomListPanel”) as RoomListPanelModule;


}


public


override


void


OnConnectedToMaster()


{


base


.OnConnectedToMaster();


//


恢复主模块的可交互性


MainPanelModule mainPanel =UIManager.Instance.GetUIModuleByName(


“MainPanel”


)


as


MainPanelModule;


mainPanel.ResumePanelInteractable();


}


public


override


void


OnJoinedRoom()


{


//


进入房间界面


UIManager.Instance.PushUI(


“RoomPanel”


);


//roomPanel.SetPlayerReadyState(PhotonNetwork.LocalPlayer.ActorNumber, false);


【旧】


//


更新房间时,取消当前玩家的准备状态


[





]


RoomPanelModule roomPanel = UIManager.Instance.GetUIModuleByName(


“RoomPanel”


)


as


RoomPanelModule;


roomPanel.SetPlayerReadyStateHash(PhotonNetwork.LocalPlayer.ActorNumber,


false


);


}


public


override


void


OnJoinRandomFailed(


short


returnCode,


string


message)


{


//


储存失败原因信息


infoMessage =message;


//


显示提示框


UIManager.Instance.PushUI(


“InfoPanel”


);


}


public


override


void


OnJoinedLobby()


{


base


.OnJoinedLobby();


//


进入大厅界面


UIManager.Instance.PushUI(


“RoomListPanel”


);


}


public


override


void


OnPlayerEnteredRoom(Player newPlayer)


{


base


.OnPlayerEnteredRoom(newPlayer);


RoomPanelModule roomPanel = UIManager.Instance.GetUIModuleByName(


“RoomPanel”


)


as


RoomPanelModule;


//


更新玩家列表


roomPanel.UpdatePlayerUIMsg();


//


设置是否显示启动游戏按钮


roomPanel.ShowStartGameBtn();


}


public


override


void


OnPlayerLeftRoom(Player otherPlayer)


{


base


.OnPlayerLeftRoom(otherPlayer);


RoomPanelModule roomPanel = UIManager.Instance.GetUIModuleByName(


“RoomPanel”


)


as


RoomPanelModule;


//


更新玩家列表


roomPanel.UpdatePlayerUIMsg();


//


设置是否显示启动游戏按钮


roomPanel.ShowStartGameBtn();


}


public


override


void


OnCreateRoomFailed(


short


returnCode,


string


message)


{


//


储存失败原因信息


infoMessage = message;


//


显示提示框


UIManager.Instance.PushUI(


“InfoPanel”


);


}


public


override


void


OnPlayerPropertiesUpdate(Player targetPlayer, ExitGames.Client.Photon.Hashtable changedProps)


{


object


result =


null


;


//


获取准备状态


changedProps.TryGetValue(GameConst.READY_PROPERTY,


out


result);


if


(result ==


null


) {


result =


false


;


}


RoomPanelModule roomPanel = UIManager.Instance.GetUIModuleByName(


“RoomPanel”


)


as


RoomPanelModule;


//


调用房间模块方法


roomPanel.SetPlayerReadyState(targetPlayer.ActorNumber,(


bool


)result);


//


设置是否显示启动游戏按钮


roomPanel.ShowStartGameBtn();


}


public


override


void


OnRoomListUpdate(List<RoomInfo> roomList)


{


base


.OnRoomListUpdate(roomList);


roomListPannel = UIManager.Instance.GetUIModuleByName(


“RoomListPanel”


)


as


RoomListPanelModule;


//


临时存储当前的所有房间信息


roomListPannel.SetRoomInfos(roomList);


}


}


using


System.Collections;


using


System.Collections.Generic;


using


UnityEngine;


using


UIFrame;


using


Photon.Pun;


using


Photon.Realtime;


using


Photon;


using


UnityEngine.Events;


using


Hashtable = ExitGames.Client.Photon.Hashtable;


public


class


MainPanelController


: UIControllerBase


{


protected


override


void


ControllerStart()


{


base


.ControllerStart();


Debug.Log(


“MainPanel Start!”


);


BindEvent();


BaseMsgInit();


}


private


void


BaseMsgInit() {


//


随机玩家昵称


crtModule.FindCurrentModuleWidget(


“PlayerNameInputField_F”


).tmpSetInputFieldText(


“Player”


+Random.Range(101,999));


//


随机房间名称


crtModule.FindCurrentModuleWidget(


“RoomNameInputField_F”


).tmpSetInputFieldText(


“Room”


+ Random.Range(101, 999));


//


设置默认的最大人数


crtModule.FindCurrentModuleWidget(


“RoomMaxCountInputFIeld_F”


).tmpSetInputFieldText(


“5”


);


}


protected


void


BindEvent()


{


//Hero


点击事件绑定


crtModule.FindCurrentModuleWidget(


“Hero01Button_F”


).AddOnClickListener(()=> {


//


父物体


Transform parent = crtModule.FindCurrentModuleWidget(


“Hero01Button_F”


).transform;


//


设置选择框到当前模块


crtModule.FindCurrentModuleWidget(


“Select_F”


).SetParent(parent,


false


);


//


标记当前选择英雄的编号


HumanGameManager.Instance.selectedHeroIndex = 1;


});


//Hero


点击事件绑定


crtModule.FindCurrentModuleWidget(


“Hero02Button_F”


).AddOnClickListener(() => {


//


父物体


Transform parent = crtModule.FindCurrentModuleWidget(


“Hero02Button_F”


).transform;


//


设置选择框到当前模块


crtModule.FindCurrentModuleWidget(


“Select_F”


).SetParent(parent,


false


);


//


标记当前选择英雄的编号


HumanGameManager.Instance.selectedHeroIndex = 2;


});


//Hero


点击事件绑定


crtModule.FindCurrentModuleWidget(


“Hero03Button_F”


).AddOnClickListener(() => {


//


父物体


Transform parent = crtModule.FindCurrentModuleWidget(


“Hero03Button_F”


).transform;


//


设置选择框到当前模块


crtModule.FindCurrentModuleWidget(


“Select_F”


).SetParent(parent,


false


);


//


标记当前选择英雄的编号


HumanGameManager.Instance.selectedHeroIndex = 3;


});


//


绑定创建房间按钮事件


CreateButton_F


crtModule.FindCurrentModuleWidget(


“CreateButton_F”


).AddOnClickListener(CreateRoomBtnClick);


//crtModule.FindCurrentModuleWidget(“CreateButton_F”).AddOnClickListener(test);


//


随机加入房间按钮事件


CreateButton_F


crtModule.FindCurrentModuleWidget(


“RandomRoomButton_F”


).AddOnClickListener(JoinRandomRoom);


//


绑定进入游戏大厅按钮事件


CreateButton_F


crtModule.FindCurrentModuleWidget(


“ListServerButton_F”


).AddOnClickListener(JoinLobby);


}


private


void


test() {


string


playerName = crtModule.FindCurrentModuleWidget(


“PlayerNameInputField_F”


).tmpGetInputFieldText();


Debug.Log(


“Player”


+ Random.Range(101, 999));


}


private


void


CreateRoomBtnClick() {


//


已经进入房间,不能再创建房间


if


(PhotonNetwork.NetworkClientState == ClientState.Joined)


return


;


string


playerName= crtModule.FindCurrentModuleWidget(


“PlayerNameInputField_F”


).tmpGetInputFieldText();


string


roomName = crtModule.FindCurrentModuleWidget(


“RoomNameInputField_F”


).tmpGetInputFieldText();


string


roomPwd = crtModule.FindCurrentModuleWidget(


“RoomPasswordInputField_F”


).tmpGetInputFieldText();


string


roomMaxCount = crtModule.FindCurrentModuleWidget(


“RoomMaxCountInputFIeld_F”


).tmpGetInputFieldText();


if


(playerName ==


“”


) {


playerName =


“Player”


+ Random.Range(101, 999);


}


if


(roomName ==


“”


)


{


roomName =


“Room”


+ Random.Range(101, 999);


}


if


(roomMaxCount ==


“”


)


{


roomMaxCount =


“5”


;


}


//


设置玩家昵称


PhotonNetwork.NickName = playerName;


//Debug.Log(PhotonNetwork.NickName);


//


创建房间选项对象


RoomOptions roomOptions =


new


RoomOptions();


//


设置最大人数


roomOptions.MaxPlayers =


byte


.Parse(roomMaxCount);


if


(roomPwd !=


“”


) {


//


添加房间密码


//


如果


hashtable


为空


if


(roomOptions.CustomRoomProperties ==


null


) {


//


实例化


roomOptions.CustomRoomProperties =


new


Hashtable();


}


roomOptions.CustomRoomProperties.Add(


“Password”


, roomPwd);


}


//


创建房间


PhotonNetwork.CreateRoom(roomName, roomOptions);


}


private


void


JoinRandomRoom() {


//


已经进入房间,不能再创建房间


if


(PhotonNetwork.NetworkClientState == ClientState.Joined)


return


;


string


playerName = crtModule.FindCurrentModuleWidget(


“PlayerNameInputField_F”


).tmpGetInputFieldText();


if


(playerName ==


“”


)


{


playerName =


“Player”


+ Random.Range(101, 999);


}


//


设置玩家昵称


PhotonNetwork.NickName = playerName;


//


随机加入房间


PhotonNetwork.JoinRandomRoom();


}


private


void


JoinLobby() {


string


playerName = crtModule.FindCurrentModuleWidget(


“PlayerNameInputField_F”


).tmpGetInputFieldText();


if


(playerName ==


“”


)


{


playerName =


“Player”


+ Random.Range(101, 999);


}


PhotonNetwork.NickName = playerName;


if


(!PhotonNetwork.InLobby)


//


加入大厅


PhotonNetwork.JoinLobby();


}


}


using


System.Collections;


using


System.Collections.Generic;


using


UnityEngine;


using


UIFrame;


public


class


LobbyFacade


: MonoBehaviour


{


// Start is called before the first frame update


void


Start


()


{


UIManager.Instance.ShowUI(


“TopPanel”


);


UIManager.Instance.ShowUI(


“MainPanel”


);


}


// Update is called once per frame


void


Update


()


{


}


}


using


System.Collections;


using


System.Collections.Generic;


using


UnityEngine;


public


static


class


GameConst


{


#region


Player Custom Properties


public


const


string


READY_PROPERTY =


“Ready”


;


public


const


string


LOADED_PROPERTY =


“Loaded”


;


#endregion


#region


Room Custom Properties


public


const


string


INITHERO_PROPERTY =


“InitHero”


;


#endregion


#region


PlayerColors


public


static


Color[] PLAYER_COLORS;


#endregion


#region


Virtual Axis & Button


public


const


string


HEROMOVE =


“HeroMove”


;


#endregion


#region


Animator Paramters


public


static


int


SPEED_PARA;


public


static


int


PLAYERATTACK_PARA;


#endregion


#region


Custom Properties


static


GameConst()


{


PLAYER_COLORS =


new


[] {


Color.red,


Color.blue,


Color.gray,


Color.green,


Color.cyan


};


SPEED_PARA = Animator.StringToHash(


“Speed”


);


PLAYERATTACK_PARA = Animator.StringToHash(


“PlayerAttack”


);


}


#endregion


}


{


“AllData”


:[


{


“SceneName”


:


“HeroScene”


,


“Data”


: [


{


“HeroIndex”


:1,


“HeroPath”


:


“PlayerPrefabs/char_ethan”


},


{


“HeroIndex”


:2,


“HeroPath”


:


“PlayerPrefabs/char_robotGuard”


},


{


“HeroIndex”


:3,


“HeroPath”


:


“PlayerPrefabs/dragon”


}


]


}


]


}


{


“AllData”


:[


{


“SceneName”


:


“LobbyScene”


,


“Data”


: [


{


“PanelName”


:


“TopPanel”


,


“PanelPath”


:


“LobbyUIPanels/TopPanel”


},


{


“PanelName”


:


“MainPanel”


,


“PanelPath”


:


“LobbyUIPanels/MainPanel”


},


{



“PanelName”


:


“RoomPanel”


,


“PanelPath”


:


“LobbyUIPanels/RoomPanel”


},


{


“PanelName”


:


“RoomListPanel”


,


“PanelPath”


:


“LobbyUIPanels/RoomListPanel”


},


{


“PanelName”


:


“InfoPanel”


,


“PanelPath”


:


“LobbyUIPanels/InfoPanel”


}


]


}


]


}


{


“AllData”


:[


{


“SceneName”


:


“LobbyScene”


,


“Data”


: [


{


“WidgetName”


:


“RoomInfo”


,


“WidgetPath”


:


“LobbyPrefabs/RoomInfo”


},


{


“WidgetName”


:


“PlayerInfo”


,


“WidgetPath”


:


“LobbyPrefabs/PlayerInfo”


}


]


}


]


}



版权声明:本文为renwen1579原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。