【千锋合集】史上最全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”
}
]
}
]
}