El efecto y la estructura se muestran en la figura:
Puntos técnicos principales: use la tecnología Photon para realizar la parte de la red, la interfaz usa Photoshop para usar un poco de desenfoque gaussiano, trazo, luz interna y externa, superposición de degradado para lograr el efecto de la figura, y utilice la carga asincrónica de la escena.
Cargue la animación usando efectos de partículas.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using Photon.Realtime;
using UnityEngine.SceneManagement;
using System;
namespace WalkingHero
{
public class StartGame : Photon.PunBehaviour
{
public Button QuitBtn;
public Button PlayNextSceneBtn;
public InputField UserName;
public LoaderAnime loaderAnime;
public GameObject controlPanel;
bool isConnecting;
string _gameVersion = "1";
void Awake()
{
UserName.text = "玩家:" + UnityEngine.Random.Range(1000, 10000);
//开始不加入游戏大厅
PhotonNetwork.autoJoinLobby = false;
}
public void PlayNextScene()
{
if (!UserName.text.Equals("") && !UserName.text.Trim().Equals(""))
{
PhotonNetwork.player.NickName = UserName.text;
}
isConnecting = true;
controlPanel.SetActive(false);
if (loaderAnime != null)
{
loaderAnime.StartLoaderAnimation();
}
if (PhotonNetwork.connected)
{
Debug.Log("Joining Room...");
//加载下一个场景
StartCoroutine(LoadScene());
}
else
{
Debug.Log("Connecting...");
// #Critical, we must first and foremost connect to Photon Online Server.
PhotonNetwork.ConnectUsingSettings(_gameVersion);
}
}
IEnumerator LoadScene()
{
AsyncOperation op = SceneManager.LoadSceneAsync("SelectHero");
yield return new WaitForEndOfFrame();
op.allowSceneActivation = true;
}
/// <summary>
/// 退出游戏
/// </summary>
public void QuitApp()
{
Application.Quit();
}
#region Photon.PunBehaviour CallBacks
// below, we implement some callbacks of PUN
// you can find PUN's callbacks in the class PunBehaviour or in enum PhotonNetworkingMessage
/// <summary>
/// Called after the connection to the master is established and authenticated but only when PhotonNetwork.autoJoinLobby is false.
/// </summary>
public override void OnConnectedToMaster()
{
Debug.Log("Region:" + PhotonNetwork.networkingPeer.CloudRegion);
// we don't want to do anything if we are not attempting to join a room.
// this case where isConnecting is false is typically when you lost or quit the game, when this level is loaded, OnConnectedToMaster will be called, in that case
// we don't want to do anything.
if (isConnecting)
{
Debug.Log("OnConnectedToMaster");
StartCoroutine(LoadScene());
}
}
/// <summary>
/// Called after disconnecting from the Photon server.
/// </summary>
/// <remarks>
/// In some cases, other callbacks are called before OnDisconnectedFromPhoton is called.
/// Examples: OnConnectionFail() and OnFailedToConnectToPhoton().
/// </remarks>
public override void OnDisconnectedFromPhoton()
{
Debug.Log("<Color=Red>OnDisconnectedFromPhoton</Color>");
Debug.LogError("DemoAnimator/Launcher:Disconnected");
// #Critical: we failed to connect or got disconnected. There is not much we can do. Typically, a UI system should be in place to let the user attemp to connect again.
loaderAnime.StopLoaderAnimation();
isConnecting = false;
controlPanel.SetActive(true);
}
#endregion
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace WalkingHero
{
public class LoaderAnime : MonoBehaviour
{
#region Public Variables
[Tooltip("Angular Speed in degrees per seconds")]
public float speed = 180f;
[Tooltip("Radius os the loader")]
public float radius = 1f;
public GameObject particles;
#endregion
#region Private Variables
Vector3 _offset;
Transform _transform;
Transform _particleTransform;
bool _isAnimating;
#endregion
#region MonoBehaviour CallBacks
/// <summary>
/// MonoBehaviour method called on GameObject by Unity during early initialization phase.
/// </summary>
void Awake()
{
// cache for efficiency
_particleTransform = particles.GetComponent<Transform>();
_transform = GetComponent<Transform>();
}
/// <summary>
/// MonoBehaviour method called on GameObject by Unity on every frame.
/// </summary>
void Update()
{
// only care about rotating particles if we are animating
if (_isAnimating)
{
// we rotate over time. Time.deltaTime is mandatory to have a frame rate independant animation,
_transform.Rotate(0f, 0f, speed * Time.deltaTime);
// we move from the center to the desired radius to prevent the visual artifacts of particles jumping from their current spot, it's not very nice visually
// so the particle is centered in the scene so that when it starts rotating, it doesn't jump and slowy we animate it to its final radius giving a smooth transition.
_particleTransform.localPosition = Vector3.MoveTowards(_particleTransform.localPosition, _offset, 0.5f * Time.deltaTime);
}
}
#endregion
#region Public Methods
/// <summary>
/// Starts the loader animation. Becomes visible
/// </summary>
public void StartLoaderAnimation()
{
_isAnimating = true;
_offset = new Vector3(radius, 0f, 0f);
particles.SetActive(true);
}
/// <summary>
/// Stops the loader animation. Becomes invisible
/// </summary>
public void StopLoaderAnimation()
{
particles.SetActive(false);
}
#endregion
}
}