Would you be interested in creating your own video game in the Red Dead Redemption style with game mechanics with montage of animals and horses? Well, I bring you good news with the review of this asset from the Unity Asset Store, you will have all the information to do so as join me to see the elements they contain as well as the interesting game mechanics that it entails, follow me.
Síguenos en nuestro canal de YouTube dedicado a tecnología, marketplace de proyectos tecnológicos, cursos online y tutoriales de desarrollo de videojuegos. Ofrecemos consultoría en desarrollo de software, marketing online, servicios de TI, hosting web, dominios web y más.
¿Te interesaría crear tu propio videojuego al estilo Red Dead Redemption con mecánica de juegos con montaje de animales y caballos? Pues te traigo buenas noticias con la revisión de éste activo de la tienda de Unity Asset Store tendrás toda la información de como hacerlo acompáñame a ver los elementos que contiene así como la interesante mecánica de juego que conlleva, sígueme.
Síguenos en nuestro canal de YouTube dedicado a tecnología, marketplace de proyectos tecnológicos, cursos online y tutoriales de desarrollo de videojuegos. Ofrecemos consultoría en desarrollo de software, marketing online, servicios de TI, hosting web, dominios web y más.
Aquí está la próxima lección sobre cómo hacer un juego multijugador en Unity usando el complemento Photon 2. Para esta lección, nos centraremos en el movimiento del jugador y sincronizaremos la transformación a través de la red utilizando la vista de transformación de Photon. Es muy importante poder sincronizar el movimiento de los jugadores a través de la red porque, sin hacerlo, los jugadores podrán verse en diferentes lugares de lo que realmente están. También es importante asegurarse de que cada jugador solo pueda controlar sus propios avatares.
Lo primero que debemos hacer es abrir nuestro prefab Avatar de Photon Player. En este prefabricado, agregaremos la Vista de transformación de Photon para que nuestro avatar jugador pueda sincronizar su movimiento. Luego, necesitaremos crear un nuevo script de C # para configurar los controles para el movimiento del objeto Avatar. Con este script C# abierto, lo primero que haremos es crear algunas variables nuevas. Luego inicializaremos todas nuestras variables. A medida que creamos las funciones de movimiento, primero debemos verificar la entrada del jugador. Según la entrada del jugador, moveremos el objeto avatar del jugador. Cuando llamamos a esta función de movimiento es la función de actualización, utilizaremos la variable Vista de Photon para verificar si este objeto es propiedad del jugador local. Esto es para asegurarse de que solo el jugador local pueda controlar su avatar y no los avatares de otras personas. Luego guardaremos nuestro script y volveremos a Unity 3D.
Si sigue el vídeo, ahora debería poder construir su proyecto. En la escena multijugador, ahora deberías poder controlar el movimiento de tu avatar de jugador local.
PlayerMovement
using Photon.Pun;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
private PhotonView PV;
private CharacterController myCC;
public float movementSpeed;
public float rotationSpeed;
// Start is called before the first frame update
void Start()
{
PV = GetComponent<PhotonView>();
myCC = GetComponent<CharacterController>();
}
// Update is called once per frame
void Update()
{
if(PV.IsMine && PhotonNetwork.IsConnected)
{
BasicMovement();
BasicRotation();
}
}
void BasicMovement()
{
if(Input.GetKey(KeyCode.W))
{
myCC.Move(transform.forward * Time.deltaTime * movementSpeed);
}
if (Input.GetKey(KeyCode.A))
{
myCC.Move(transform.right * Time.deltaTime * movementSpeed);
}
if (Input.GetKey(KeyCode.S))
{
myCC.Move(transform.forward * Time.deltaTime * movementSpeed);
}
if (Input.GetKey(KeyCode.D))
{
myCC.Move(transform.right * Time.deltaTime * movementSpeed);
}
}
void BasicRotation()
{
float mouseX = Input.GetAxis("Mouse X") * Time.deltaTime * rotationSpeed;
transform.Rotate(new Vector3(0, mouseX, 0));
}
}
PhotonLobby
using Photon.Pun;
using Photon.Realtime;
using UnityEngine;
public class PhotonLobby : MonoBehaviourPunCallbacks
{
// Start is called before the first frame update
public static PhotonLobby lobby;
public GameObject battleButton;
RoomInfo[] room;
public GameObject cancelButtom;
private void Awake()
{
lobby = this;
}
void Start()
{
PhotonNetwork.ConnectUsingSettings();
}
public override void OnConnectedToMaster()
{
Debug.Log("the conection is stablished");
PhotonNetwork.AutomaticallySyncScene = true;
battleButton.SetActive(true);
}
public void OnBattleButtonClicked()
{
Debug.Log("llego aca paso algo en la el battle button click");
battleButton.SetActive(false);
cancelButtom.SetActive(true);
PhotonNetwork.JoinRandomRoom();
}
public override void OnJoinRandomFailed(short returnCode, string message)
{
//base.OnJoinRandomFailed(returnCode, message);
Debug.Log("failed joining the room");
CreateRoom();
}
void CreateRoom()
{
Debug.Log("llego a CreateRoom");
int randomRoomName = Random.Range(0, 10000);
RoomOptions roomOps = new RoomOptions()
{
IsVisible = true,
IsOpen = true,
MaxPlayers = (byte)MultiplayerSettings.multiplayerSettings.maxPlayers
};
PhotonNetwork.CreateRoom("Room" + randomRoomName, roomOps, null);
}
public override void OnCreateRoomFailed(short returnCode, string message)
{
//base.OnCreateRoomFailed(returnCode, message);
Debug.Log("failed creating the room");
CreateRoom();
}
public void OnCancelButtonCliked()
{
Debug.Log("Llego OnCancelButtonCliked");
battleButton.SetActive(false);
cancelButtom.SetActive(true);
PhotonNetwork.LeaveRoom();
}
}
PhotonPlayer
using Photon.Pun;
using System.IO;
using UnityEngine;
public class PhotonPlayer : MonoBehaviour
{
// Start is called before the first frame update
private PhotonView PV;
public GameObject myAvatar;
public GameObject myMainCamera;
void Start()
{
PV = GetComponent<PhotonView>();
int spawnPicker = Random.Range(0, GameSetUp.GS.spawnPoints.Length);
if (PV.IsMine)
{
myAvatar = PhotonNetwork.Instantiate(Path.Combine("PhotonPrefabs", "PlayerAvatar"), GameSetUp.GS.spawnPoints[spawnPicker].position,
GameSetUp.GS.spawnPoints[spawnPicker].rotation, 0);
/*myAvatar = PhotonNetwork.Instantiate(Path.Combine("PhotonPrefabs", "Character 1"), GameSetUp.GS.spawnPoints[spawnPicker].position,
GameSetUp.GS.spawnPoints[spawnPicker].rotation, 0);*/
}
}
}
PhotonRoom
using Photon.Pun;
using Photon.Realtime;
using System.IO;
using UnityEngine;
using UnityEngine.SceneManagement;
public class PhotonRoom : MonoBehaviourPunCallbacks, IInRoomCallbacks
{
// Start is called before the first frame update
public static PhotonRoom room;
private PhotonView PV;
public bool IsGameLoaded;
public int currentScene;
private Photon.Realtime.Player[] photonPlayers;
public int playersInRoom;
public int myNumberInRoom;
public int playerInGame;
private bool readyToCount;
private bool readyToStart;
public float startingTime;
private float lessThanMaxPlayer;
private float atMaxPlayer;
private float timeToStart;
private void Awake()
{
if(PhotonRoom.room == null)
{
PhotonRoom.room = this;
}
else
{
if(PhotonRoom.room != this)
{
Destroy(PhotonRoom.room.gameObject);
PhotonRoom.room = this;
}
}
DontDestroyOnLoad(this.gameObject);
}
public override void OnEnable()
{
base.OnEnable();
PhotonNetwork.AddCallbackTarget(this);
SceneManager.sceneLoaded += OnSceneFinishedLoading;
}
public override void OnDisable()
{
base.OnDisable();
PhotonNetwork.RemoveCallbackTarget(this);
SceneManager.sceneLoaded -= OnSceneFinishedLoading;
}
void Start()
{
PV = GetComponent<PhotonView>();
readyToCount = false;
readyToStart = false;
lessThanMaxPlayer = startingTime;
atMaxPlayer = 6;
timeToStart = startingTime;
}
// Update is called once per frame
void Update()
{
if (MultiplayerSettings.multiplayerSettings.delayStart)
{
if(playersInRoom == 1)
{
RestartTimer();
}
if (!IsGameLoaded)
{
if (readyToStart)
{
atMaxPlayer -= Time.deltaTime;
lessThanMaxPlayer = atMaxPlayer;
timeToStart = atMaxPlayer;
}
else if (readyToCount)
{
lessThanMaxPlayer -= Time.deltaTime;
timeToStart = lessThanMaxPlayer;
}
Debug.Log("Displayer time to start to the players " + timeToStart );
if (timeToStart <=0)
{
StartGame();
}
}
}
}
public override void OnJoinedRoom()
{
base.OnJoinedRoom();
Debug.Log("Se Unio a OnJoinedRoom");
photonPlayers = PhotonNetwork.PlayerList;
playersInRoom = photonPlayers.Length;
myNumberInRoom = playersInRoom;
PhotonNetwork.NickName = myNumberInRoom.ToString();
if (MultiplayerSettings.multiplayerSettings.delayStart)
{
Debug.Log("Displayer players in room out of max players possible ("+playersInRoom+":"+MultiplayerSettings.multiplayerSettings.maxPlayers+")");
if(playersInRoom > 1)
{
readyToCount = true;
}
if (playersInRoom == MultiplayerSettings.multiplayerSettings.maxPlayers)
{
readyToStart = true;
if (PhotonNetwork.IsMasterClient)
{
return;
}
PhotonNetwork.CurrentRoom.IsOpen = false;
}
}
else
{
StartGame();
}
}
public override void OnPlayerEnteredRoom(Photon.Realtime.Player newPlayer)
{
base.OnPlayerEnteredRoom(newPlayer);
Debug.Log("A new player has joined the room");
photonPlayers = PhotonNetwork.PlayerList;
playersInRoom++;
if(MultiplayerSettings.multiplayerSettings.delayStart)
{
Debug.Log("Displayer players in room out of max players possible (" + playersInRoom + ":" + MultiplayerSettings.multiplayerSettings.maxPlayers + ")");
if (playersInRoom > 1)
{
readyToCount = true;
}
if (playersInRoom == MultiplayerSettings.multiplayerSettings.maxPlayers)
{
readyToStart = true;
if (!PhotonNetwork.IsMasterClient)
{
return;
}
PhotonNetwork.CurrentRoom.IsOpen = false;
}
}
}
void StartGame()
{
IsGameLoaded = true;
if (!PhotonNetwork.IsMasterClient)
return;
if(MultiplayerSettings.multiplayerSettings.delayStart)
{
PhotonNetwork.CurrentRoom.IsOpen = false;
}
PhotonNetwork.LoadLevel(MultiplayerSettings.multiplayerSettings.multiplayerScene);
}
void RestartTimer()
{
lessThanMaxPlayer = startingTime;
timeToStart = startingTime;
atMaxPlayer = 6;
readyToCount = false;
readyToStart = false;
}
void OnSceneFinishedLoading(Scene scene, LoadSceneMode mode)
{
currentScene = scene.buildIndex;
if (currentScene ==MultiplayerSettings.multiplayerSettings.multiplayerScene)
{
IsGameLoaded = true;
if (MultiplayerSettings.multiplayerSettings.delayStart)
{
PV.RPC("RPC_loadedGameScene", RpcTarget.MasterClient);
}
else
{
RPC_CreatePlayer();
}
}
}
[PunRPC]
private void RPC_LoadedGameScene()
{
playerInGame++;
if (playerInGame == PhotonNetwork.PlayerList.Length)
{
PV.RPC("RPC_CreatePlayer",RpcTarget.All);
}
}
[PunRPC]
private void RPC_CreatePlayer()
{
PhotonNetwork.Instantiate(Path.Combine("PhotonPrefabs", "PhotonNetworkPlayer"), transform.position, Quaternion
.identity, 0);
}
}
GameSetUp
using UnityEngine;
public class GameSetUp : MonoBehaviour
{
// Start is called before the first frame update
public static GameSetUp GS;
public Transform[] spawnPoints;
private void OnEnable()
{
if (GameSetUp.GS == null)
{
GameSetUp.GS = this;
}
}
}
MultiplayerSettings
using UnityEngine;
public class MultiplayerSettings : MonoBehaviour
{
// Start is called before the first frame update
public static MultiplayerSettings multiplayerSettings;
public bool delayStart;
public int maxPlayers;
public int menuScene;
public int multiplayerScene;
private void Awake()
{
if(MultiplayerSettings.multiplayerSettings == null)
{
MultiplayerSettings.multiplayerSettings = this;
}
else
{
if(MultiplayerSettings.multiplayerSettings != this)
{
Destroy(this.gameObject);
}
}
DontDestroyOnLoad(this.gameObject);
}
}
Síguenos en nuestro canal de YouTube dedicado a tecnología, marketplace de proyectos tecnológicos, cursos online y tutoriales de desarrollo de videojuegos. Ofrecemos consultoría en desarrollo de software, marketing online, servicios de TI, hosting web, dominios web y más.
Bienvenido a esta nueva serie de tutoriales sobre la creación de videojuegos multijugador en Unity usando el complemento Photon 2 PUN. Para esta lección, le mostraremos cómo descargar, instalar y configurar el complemento Photon 2 en sus proyectos de Unity. Antes de seguir con cualquiera de las otras lecciones de esta serie de tutoriales, debe completar este video. Proporcionaremos los complementos descargables para todos los demás videos de esta serie, pero estos complementos no incluirán el complemento Photon original. Debe obtenerlo del sitio web oficial de Photon.
Lo primero que deberá hacer en esta lección es crear una cuenta de Photon. Una vez que haya registrado una cuenta, deberá crear un nuevo proyecto de aplicación Photon. Luego deberás completar información sobre tu juego multijugador y luego harás clic en crear. Después de crear una nueva aplicación, deberá copiar el ID de aplicación para más adelante.
De vuelta en Unity, deberá ir a Unity Asset Store y buscar el complemento gratuito PUN 2. Deberá descargar e instalar este complemento en su proyecto. Después de importar este complemento, aparecerá una nueva ventana. Este es el asistente de PUN y debe pegar su AppID de proyecto en esta ventana y luego hará clic en configurar proyecto. Lo siguiente que haremos es establecer nuestra primera conexión con el servidor maestro Photon. Para hacer esto, necesitaremos crear un nuevo script. En este nuevo script, lo único que haremos para este tutorial es inicializar la conexión de red.
PlayerMovement
using Photon.Pun;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
private PhotonView PV;
private CharacterController myCC;
public float movementSpeed;
public float rotationSpeed;
// Start is called before the first frame update
void Start()
{
PV = GetComponent<PhotonView>();
myCC = GetComponent<CharacterController>();
}
// Update is called once per frame
void Update()
{
if(PV.IsMine && PhotonNetwork.IsConnected)
{
BasicMovement();
BasicRotation();
}
}
void BasicMovement()
{
if(Input.GetKey(KeyCode.W))
{
myCC.Move(transform.forward * Time.deltaTime * movementSpeed);
}
if (Input.GetKey(KeyCode.A))
{
myCC.Move(transform.right * Time.deltaTime * movementSpeed);
}
if (Input.GetKey(KeyCode.S))
{
myCC.Move(transform.forward * Time.deltaTime * movementSpeed);
}
if (Input.GetKey(KeyCode.D))
{
myCC.Move(transform.right * Time.deltaTime * movementSpeed);
}
}
void BasicRotation()
{
float mouseX = Input.GetAxis("Mouse X") * Time.deltaTime * rotationSpeed;
transform.Rotate(new Vector3(0, mouseX, 0));
}
}
PhotonLobby
using Photon.Pun;
using Photon.Realtime;
using UnityEngine;
public class PhotonLobby : MonoBehaviourPunCallbacks
{
// Start is called before the first frame update
public static PhotonLobby lobby;
public GameObject battleButton;
RoomInfo[] room;
public GameObject cancelButtom;
private void Awake()
{
lobby = this;
}
void Start()
{
PhotonNetwork.ConnectUsingSettings();
}
public override void OnConnectedToMaster()
{
Debug.Log("the conection is stablished");
PhotonNetwork.AutomaticallySyncScene = true;
battleButton.SetActive(true);
}
public void OnBattleButtonClicked()
{
Debug.Log("llego aca paso algo en la el battle button click");
battleButton.SetActive(false);
cancelButtom.SetActive(true);
PhotonNetwork.JoinRandomRoom();
}
public override void OnJoinRandomFailed(short returnCode, string message)
{
//base.OnJoinRandomFailed(returnCode, message);
Debug.Log("failed joining the room");
CreateRoom();
}
void CreateRoom()
{
Debug.Log("llego a CreateRoom");
int randomRoomName = Random.Range(0, 10000);
RoomOptions roomOps = new RoomOptions()
{
IsVisible = true,
IsOpen = true,
MaxPlayers = (byte)MultiplayerSettings.multiplayerSettings.maxPlayers
};
PhotonNetwork.CreateRoom("Room" + randomRoomName, roomOps, null);
}
public override void OnCreateRoomFailed(short returnCode, string message)
{
//base.OnCreateRoomFailed(returnCode, message);
Debug.Log("failed creating the room");
CreateRoom();
}
public void OnCancelButtonCliked()
{
Debug.Log("Llego OnCancelButtonCliked");
battleButton.SetActive(false);
cancelButtom.SetActive(true);
PhotonNetwork.LeaveRoom();
}
}
PhotonPlayer
using Photon.Pun;
using System.IO;
using UnityEngine;
public class PhotonPlayer : MonoBehaviour
{
// Start is called before the first frame update
private PhotonView PV;
public GameObject myAvatar;
public GameObject myMainCamera;
void Start()
{
PV = GetComponent<PhotonView>();
int spawnPicker = Random.Range(0, GameSetUp.GS.spawnPoints.Length);
if (PV.IsMine)
{
myAvatar = PhotonNetwork.Instantiate(Path.Combine("PhotonPrefabs", "PlayerAvatar"), GameSetUp.GS.spawnPoints[spawnPicker].position,
GameSetUp.GS.spawnPoints[spawnPicker].rotation, 0);
/*myAvatar = PhotonNetwork.Instantiate(Path.Combine("PhotonPrefabs", "Character 1"), GameSetUp.GS.spawnPoints[spawnPicker].position,
GameSetUp.GS.spawnPoints[spawnPicker].rotation, 0);*/
}
}
}
PhotonRoom
using Photon.Pun;
using Photon.Realtime;
using System.IO;
using UnityEngine;
using UnityEngine.SceneManagement;
public class PhotonRoom : MonoBehaviourPunCallbacks, IInRoomCallbacks
{
// Start is called before the first frame update
public static PhotonRoom room;
private PhotonView PV;
public bool IsGameLoaded;
public int currentScene;
private Photon.Realtime.Player[] photonPlayers;
public int playersInRoom;
public int myNumberInRoom;
public int playerInGame;
private bool readyToCount;
private bool readyToStart;
public float startingTime;
private float lessThanMaxPlayer;
private float atMaxPlayer;
private float timeToStart;
private void Awake()
{
if(PhotonRoom.room == null)
{
PhotonRoom.room = this;
}
else
{
if(PhotonRoom.room != this)
{
Destroy(PhotonRoom.room.gameObject);
PhotonRoom.room = this;
}
}
DontDestroyOnLoad(this.gameObject);
}
public override void OnEnable()
{
base.OnEnable();
PhotonNetwork.AddCallbackTarget(this);
SceneManager.sceneLoaded += OnSceneFinishedLoading;
}
public override void OnDisable()
{
base.OnDisable();
PhotonNetwork.RemoveCallbackTarget(this);
SceneManager.sceneLoaded -= OnSceneFinishedLoading;
}
void Start()
{
PV = GetComponent<PhotonView>();
readyToCount = false;
readyToStart = false;
lessThanMaxPlayer = startingTime;
atMaxPlayer = 6;
timeToStart = startingTime;
}
// Update is called once per frame
void Update()
{
if (MultiplayerSettings.multiplayerSettings.delayStart)
{
if(playersInRoom == 1)
{
RestartTimer();
}
if (!IsGameLoaded)
{
if (readyToStart)
{
atMaxPlayer -= Time.deltaTime;
lessThanMaxPlayer = atMaxPlayer;
timeToStart = atMaxPlayer;
}
else if (readyToCount)
{
lessThanMaxPlayer -= Time.deltaTime;
timeToStart = lessThanMaxPlayer;
}
Debug.Log("Displayer time to start to the players " + timeToStart );
if (timeToStart <=0)
{
StartGame();
}
}
}
}
public override void OnJoinedRoom()
{
base.OnJoinedRoom();
Debug.Log("Se Unio a OnJoinedRoom");
photonPlayers = PhotonNetwork.PlayerList;
playersInRoom = photonPlayers.Length;
myNumberInRoom = playersInRoom;
PhotonNetwork.NickName = myNumberInRoom.ToString();
if (MultiplayerSettings.multiplayerSettings.delayStart)
{
Debug.Log("Displayer players in room out of max players possible ("+playersInRoom+":"+MultiplayerSettings.multiplayerSettings.maxPlayers+")");
if(playersInRoom > 1)
{
readyToCount = true;
}
if (playersInRoom == MultiplayerSettings.multiplayerSettings.maxPlayers)
{
readyToStart = true;
if (PhotonNetwork.IsMasterClient)
{
return;
}
PhotonNetwork.CurrentRoom.IsOpen = false;
}
}
else
{
StartGame();
}
}
public override void OnPlayerEnteredRoom(Photon.Realtime.Player newPlayer)
{
base.OnPlayerEnteredRoom(newPlayer);
Debug.Log("A new player has joined the room");
photonPlayers = PhotonNetwork.PlayerList;
playersInRoom++;
if(MultiplayerSettings.multiplayerSettings.delayStart)
{
Debug.Log("Displayer players in room out of max players possible (" + playersInRoom + ":" + MultiplayerSettings.multiplayerSettings.maxPlayers + ")");
if (playersInRoom > 1)
{
readyToCount = true;
}
if (playersInRoom == MultiplayerSettings.multiplayerSettings.maxPlayers)
{
readyToStart = true;
if (!PhotonNetwork.IsMasterClient)
{
return;
}
PhotonNetwork.CurrentRoom.IsOpen = false;
}
}
}
void StartGame()
{
IsGameLoaded = true;
if (!PhotonNetwork.IsMasterClient)
return;
if(MultiplayerSettings.multiplayerSettings.delayStart)
{
PhotonNetwork.CurrentRoom.IsOpen = false;
}
PhotonNetwork.LoadLevel(MultiplayerSettings.multiplayerSettings.multiplayerScene);
}
void RestartTimer()
{
lessThanMaxPlayer = startingTime;
timeToStart = startingTime;
atMaxPlayer = 6;
readyToCount = false;
readyToStart = false;
}
void OnSceneFinishedLoading(Scene scene, LoadSceneMode mode)
{
currentScene = scene.buildIndex;
if (currentScene ==MultiplayerSettings.multiplayerSettings.multiplayerScene)
{
IsGameLoaded = true;
if (MultiplayerSettings.multiplayerSettings.delayStart)
{
PV.RPC("RPC_loadedGameScene", RpcTarget.MasterClient);
}
else
{
RPC_CreatePlayer();
}
}
}
[PunRPC]
private void RPC_LoadedGameScene()
{
playerInGame++;
if (playerInGame == PhotonNetwork.PlayerList.Length)
{
PV.RPC("RPC_CreatePlayer",RpcTarget.All);
}
}
[PunRPC]
private void RPC_CreatePlayer()
{
PhotonNetwork.Instantiate(Path.Combine("PhotonPrefabs", "PhotonNetworkPlayer"), transform.position, Quaternion
.identity, 0);
}
}
GameSetUp
using UnityEngine;
public class GameSetUp : MonoBehaviour
{
// Start is called before the first frame update
public static GameSetUp GS;
public Transform[] spawnPoints;
private void OnEnable()
{
if (GameSetUp.GS == null)
{
GameSetUp.GS = this;
}
}
}
MultiplayerSettings
using UnityEngine;
public class MultiplayerSettings : MonoBehaviour
{
// Start is called before the first frame update
public static MultiplayerSettings multiplayerSettings;
public bool delayStart;
public int maxPlayers;
public int menuScene;
public int multiplayerScene;
private void Awake()
{
if(MultiplayerSettings.multiplayerSettings == null)
{
MultiplayerSettings.multiplayerSettings = this;
}
else
{
if(MultiplayerSettings.multiplayerSettings != this)
{
Destroy(this.gameObject);
}
}
DontDestroyOnLoad(this.gameObject);
}
}
Síguenos en nuestro canal de YouTube dedicado a tecnología, marketplace de proyectos tecnológicos, cursos online y tutoriales de desarrollo de videojuegos. Ofrecemos consultoría en desarrollo de software, marketing online, servicios de TI, hosting web, dominios web y más.
En ésta oportunidad comenzamos con la configuración inicial y la realización de la lógica de creación de salas unión a salas, y ubicación de objeto player en la escena en ésta serie abarcaremos la creación de nuestro videojuego TPS en la modalidad Multijugador con Photon 2 en Unity 3D. La implementación multijugador es independiente del juego la haremos así para que puedas utilizarla en cualquier otro proyecto que requieras.
La baja latencia es un requisito esencial en los juegos multijugador en tiempo real. Por esta razón, Photon Cloud está alojado en todas las principales regiones del mundo para brindar a sus jugadores una latencia mínima.
Los juegos que dependen de una latencia baja, como los tipos de juegos FPS o RTS, conectan a los jugadores con la región más cercana. Los juegos que pueden manejar una mayor latencia, como los juegos por turnos, pueden conectar a todos los jugadores a la misma región.
PlayerMovement
using Photon.Pun;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
private PhotonView PV;
private CharacterController myCC;
public float movementSpeed;
public float rotationSpeed;
// Start is called before the first frame update
void Start()
{
PV = GetComponent<PhotonView>();
myCC = GetComponent<CharacterController>();
}
// Update is called once per frame
void Update()
{
if(PV.IsMine && PhotonNetwork.IsConnected)
{
BasicMovement();
BasicRotation();
}
}
void BasicMovement()
{
if(Input.GetKey(KeyCode.W))
{
myCC.Move(transform.forward * Time.deltaTime * movementSpeed);
}
if (Input.GetKey(KeyCode.A))
{
myCC.Move(transform.right * Time.deltaTime * movementSpeed);
}
if (Input.GetKey(KeyCode.S))
{
myCC.Move(transform.forward * Time.deltaTime * movementSpeed);
}
if (Input.GetKey(KeyCode.D))
{
myCC.Move(transform.right * Time.deltaTime * movementSpeed);
}
}
void BasicRotation()
{
float mouseX = Input.GetAxis("Mouse X") * Time.deltaTime * rotationSpeed;
transform.Rotate(new Vector3(0, mouseX, 0));
}
}
PhotonLobby
using Photon.Pun;
using Photon.Realtime;
using UnityEngine;
public class PhotonLobby : MonoBehaviourPunCallbacks
{
// Start is called before the first frame update
public static PhotonLobby lobby;
public GameObject battleButton;
RoomInfo[] room;
public GameObject cancelButtom;
private void Awake()
{
lobby = this;
}
void Start()
{
PhotonNetwork.ConnectUsingSettings();
}
public override void OnConnectedToMaster()
{
Debug.Log("the conection is stablished");
PhotonNetwork.AutomaticallySyncScene = true;
battleButton.SetActive(true);
}
public void OnBattleButtonClicked()
{
Debug.Log("llego aca paso algo en la el battle button click");
battleButton.SetActive(false);
cancelButtom.SetActive(true);
PhotonNetwork.JoinRandomRoom();
}
public override void OnJoinRandomFailed(short returnCode, string message)
{
//base.OnJoinRandomFailed(returnCode, message);
Debug.Log("failed joining the room");
CreateRoom();
}
void CreateRoom()
{
Debug.Log("llego a CreateRoom");
int randomRoomName = Random.Range(0, 10000);
RoomOptions roomOps = new RoomOptions()
{
IsVisible = true,
IsOpen = true,
MaxPlayers = (byte)MultiplayerSettings.multiplayerSettings.maxPlayers
};
PhotonNetwork.CreateRoom("Room" + randomRoomName, roomOps, null);
}
public override void OnCreateRoomFailed(short returnCode, string message)
{
//base.OnCreateRoomFailed(returnCode, message);
Debug.Log("failed creating the room");
CreateRoom();
}
public void OnCancelButtonCliked()
{
Debug.Log("Llego OnCancelButtonCliked");
battleButton.SetActive(false);
cancelButtom.SetActive(true);
PhotonNetwork.LeaveRoom();
}
}
PhotonPlayer
using Photon.Pun;
using System.IO;
using UnityEngine;
public class PhotonPlayer : MonoBehaviour
{
// Start is called before the first frame update
private PhotonView PV;
public GameObject myAvatar;
public GameObject myMainCamera;
void Start()
{
PV = GetComponent<PhotonView>();
int spawnPicker = Random.Range(0, GameSetUp.GS.spawnPoints.Length);
if (PV.IsMine)
{
myAvatar = PhotonNetwork.Instantiate(Path.Combine("PhotonPrefabs", "PlayerAvatar"), GameSetUp.GS.spawnPoints[spawnPicker].position,
GameSetUp.GS.spawnPoints[spawnPicker].rotation, 0);
/*myAvatar = PhotonNetwork.Instantiate(Path.Combine("PhotonPrefabs", "Character 1"), GameSetUp.GS.spawnPoints[spawnPicker].position,
GameSetUp.GS.spawnPoints[spawnPicker].rotation, 0);*/
}
}
}
PhotonRoom
using Photon.Pun;
using Photon.Realtime;
using System.IO;
using UnityEngine;
using UnityEngine.SceneManagement;
public class PhotonRoom : MonoBehaviourPunCallbacks, IInRoomCallbacks
{
// Start is called before the first frame update
public static PhotonRoom room;
private PhotonView PV;
public bool IsGameLoaded;
public int currentScene;
private Photon.Realtime.Player[] photonPlayers;
public int playersInRoom;
public int myNumberInRoom;
public int playerInGame;
private bool readyToCount;
private bool readyToStart;
public float startingTime;
private float lessThanMaxPlayer;
private float atMaxPlayer;
private float timeToStart;
private void Awake()
{
if(PhotonRoom.room == null)
{
PhotonRoom.room = this;
}
else
{
if(PhotonRoom.room != this)
{
Destroy(PhotonRoom.room.gameObject);
PhotonRoom.room = this;
}
}
DontDestroyOnLoad(this.gameObject);
}
public override void OnEnable()
{
base.OnEnable();
PhotonNetwork.AddCallbackTarget(this);
SceneManager.sceneLoaded += OnSceneFinishedLoading;
}
public override void OnDisable()
{
base.OnDisable();
PhotonNetwork.RemoveCallbackTarget(this);
SceneManager.sceneLoaded -= OnSceneFinishedLoading;
}
void Start()
{
PV = GetComponent<PhotonView>();
readyToCount = false;
readyToStart = false;
lessThanMaxPlayer = startingTime;
atMaxPlayer = 6;
timeToStart = startingTime;
}
// Update is called once per frame
void Update()
{
if (MultiplayerSettings.multiplayerSettings.delayStart)
{
if(playersInRoom == 1)
{
RestartTimer();
}
if (!IsGameLoaded)
{
if (readyToStart)
{
atMaxPlayer -= Time.deltaTime;
lessThanMaxPlayer = atMaxPlayer;
timeToStart = atMaxPlayer;
}
else if (readyToCount)
{
lessThanMaxPlayer -= Time.deltaTime;
timeToStart = lessThanMaxPlayer;
}
Debug.Log("Displayer time to start to the players " + timeToStart );
if (timeToStart <=0)
{
StartGame();
}
}
}
}
public override void OnJoinedRoom()
{
base.OnJoinedRoom();
Debug.Log("Se Unio a OnJoinedRoom");
photonPlayers = PhotonNetwork.PlayerList;
playersInRoom = photonPlayers.Length;
myNumberInRoom = playersInRoom;
PhotonNetwork.NickName = myNumberInRoom.ToString();
if (MultiplayerSettings.multiplayerSettings.delayStart)
{
Debug.Log("Displayer players in room out of max players possible ("+playersInRoom+":"+MultiplayerSettings.multiplayerSettings.maxPlayers+")");
if(playersInRoom > 1)
{
readyToCount = true;
}
if (playersInRoom == MultiplayerSettings.multiplayerSettings.maxPlayers)
{
readyToStart = true;
if (PhotonNetwork.IsMasterClient)
{
return;
}
PhotonNetwork.CurrentRoom.IsOpen = false;
}
}
else
{
StartGame();
}
}
public override void OnPlayerEnteredRoom(Photon.Realtime.Player newPlayer)
{
base.OnPlayerEnteredRoom(newPlayer);
Debug.Log("A new player has joined the room");
photonPlayers = PhotonNetwork.PlayerList;
playersInRoom++;
if(MultiplayerSettings.multiplayerSettings.delayStart)
{
Debug.Log("Displayer players in room out of max players possible (" + playersInRoom + ":" + MultiplayerSettings.multiplayerSettings.maxPlayers + ")");
if (playersInRoom > 1)
{
readyToCount = true;
}
if (playersInRoom == MultiplayerSettings.multiplayerSettings.maxPlayers)
{
readyToStart = true;
if (!PhotonNetwork.IsMasterClient)
{
return;
}
PhotonNetwork.CurrentRoom.IsOpen = false;
}
}
}
void StartGame()
{
IsGameLoaded = true;
if (!PhotonNetwork.IsMasterClient)
return;
if(MultiplayerSettings.multiplayerSettings.delayStart)
{
PhotonNetwork.CurrentRoom.IsOpen = false;
}
PhotonNetwork.LoadLevel(MultiplayerSettings.multiplayerSettings.multiplayerScene);
}
void RestartTimer()
{
lessThanMaxPlayer = startingTime;
timeToStart = startingTime;
atMaxPlayer = 6;
readyToCount = false;
readyToStart = false;
}
void OnSceneFinishedLoading(Scene scene, LoadSceneMode mode)
{
currentScene = scene.buildIndex;
if (currentScene ==MultiplayerSettings.multiplayerSettings.multiplayerScene)
{
IsGameLoaded = true;
if (MultiplayerSettings.multiplayerSettings.delayStart)
{
PV.RPC("RPC_loadedGameScene", RpcTarget.MasterClient);
}
else
{
RPC_CreatePlayer();
}
}
}
[PunRPC]
private void RPC_LoadedGameScene()
{
playerInGame++;
if (playerInGame == PhotonNetwork.PlayerList.Length)
{
PV.RPC("RPC_CreatePlayer",RpcTarget.All);
}
}
[PunRPC]
private void RPC_CreatePlayer()
{
PhotonNetwork.Instantiate(Path.Combine("PhotonPrefabs", "PhotonNetworkPlayer"), transform.position, Quaternion
.identity, 0);
}
}
GameSetUp
using UnityEngine;
public class GameSetUp : MonoBehaviour
{
// Start is called before the first frame update
public static GameSetUp GS;
public Transform[] spawnPoints;
private void OnEnable()
{
if (GameSetUp.GS == null)
{
GameSetUp.GS = this;
}
}
}
MultiplayerSettings
using UnityEngine;
public class MultiplayerSettings : MonoBehaviour
{
// Start is called before the first frame update
public static MultiplayerSettings multiplayerSettings;
public bool delayStart;
public int maxPlayers;
public int menuScene;
public int multiplayerScene;
private void Awake()
{
if(MultiplayerSettings.multiplayerSettings == null)
{
MultiplayerSettings.multiplayerSettings = this;
}
else
{
if(MultiplayerSettings.multiplayerSettings != this)
{
Destroy(this.gameObject);
}
}
DontDestroyOnLoad(this.gameObject);
}
}
Síguenos en nuestro canal de YouTube dedicado a tecnología, marketplace de proyectos tecnológicos, cursos online y tutoriales de desarrollo de videojuegos. Ofrecemos consultoría en desarrollo de software, marketing online, servicios de TI, hosting web, dominios web y más.
El nombre por defecto para New Unity Project pero puede cambiarlo siempre que quiera. Escriba el nombre con el que quiere llamar a su proyecto en el campo Project name.
La localización por defecto para su carpeta personal en su ordenador, pero puede cambiarla. BIEN POR (a) Escriba aquí dónde quiere almacenar su proyecto en su ordenador en el campo Location. O (b) Haga clic en los tres puntos azules ‘…’. Esto mostrará el Finder de su ordenador (Mac OS X) o el Explorador de Archivos (Windows).
Entonces, en el Finder o en el Explorador de Archivos, seleccione la carpeta de proyecto en la que quiera guardar su nuevo proyecto, y seleccione “Elegir”.
Seleccione 3D o 2D para su tipo de proyecto. Por defecto es 3D, resaltado en rojo para mostrar que está seleccionado. (La opción 2D hace que el editor de Unity muestre sus características, y la opción 3D muestra las características 3D. Si no está seguro de qué elegir, déjelo en 3D; puede cambiar esta configuración más tarde.)
Hay una opción para seleccionar Asset packages… para incluir en su proyecto. Los paquetes de Assets son contenido pre-elaborado, como imágenes, estilos, efectos de iluminación y y controles de personaje en juego, entre otras útiles herramientas de creación del juego y contenidos. Los paquetes de assets ofrecidos aquí son gratuitos, empaquetados con Unity, y puede usarlos para comenzar con su proyecto. BIEN PUEDE: si no quiere importar esos assets empaquetados, o no está seguro, simplemente ignore esta opción; puede añadir estos assets y muchos otros posteriormente vía el editor de Unity. O: Si no quiere importar esos assets empaquetados ahora, seleccione Asset packages…_ para mostrar la lista de assets disponible, marque los que desee, y haga clic en Done__.
Ahora seleccione Create project y ¡todo estará listo!
Síguenos en nuestro canal de YouTube dedicado a tecnología, marketplace de proyectos tecnológicos, cursos online y tutoriales de desarrollo de videojuegos. Ofrecemos consultoría en desarrollo de software, marketing online, servicios de TI, hosting web, dominios web y más.
Para renderizar cualquier objeto en la pantalla, el CPU tiene mucho trabajo que hacer: trabajar qué luces afecta ese objeto, configurar el shader y los parámetros del shader, y enviar comandos de dibujo al driver gráfico, que luego prepara los comandos para que sea enviado a la tarjeta gráfica.
Todo este uso del CPU “por objeto” es intensivo a los recursos, por lo que si usted tiene muchos objetos visibles, esto se puede agregar. Por ejemplo, si usted tiene miles de triángulos, es mucho más fácil en el CPU si todos están en un mesh, en vez de un mesh por triángulo (agregando hasta 1000 meshes). El precio de ambos escenarios en el GPU es muy similar, pero el trabajo hecho por el CPU para renderizar mil objetos (en vez de uno) es significativamente mayor.
Reduzca la cuenta visible de objetos. Para reducir la cantidad de trabajo que el CPU necesita hacer:
Combine objetos cerca juntos, ya sea manualmente, o utilizando el draw call batching de Unity.
Utilice menos materiales en sus objetos, colocando texturas en un texture atlas más grande.
Utilice menos cosas que cause que los objetos sean renderizados múltiples veces (como lo son los reflejos, sombras, y luces per-pixel).
Combine los objetos juntos para que cada mesh tenga al menos varios cientos de triángulos y utilice solo un Material para el mesh entero. Es importante que tenga en cuenta que combinar dos objetos que no compartan un material no le da a usted ningún incremento de rendimiento. La razón más común para tener múltiples materiales es que dos meshes no compartan la misma textura; entonces para optimizar el rendimiento del CPU, usted debe asegurarse que cualquier objeto que usted combine comparta las misma texturas.
Síguenos en nuestro canal de YouTube dedicado a tecnología, marketplace de proyectos tecnológicos, cursos online y tutoriales de desarrollo de videojuegos. Ofrecemos consultoría en desarrollo de software, marketing online, servicios de TI, hosting web, dominios web y más.
Ha jugado muchos videojuegos, pero mientras jugaba esos juegos vio un minimapa (o minimapa) en una de las esquinas de la pantalla del juego para guiarlo.
¿Sabes cómo se desarrollan los minimapas?
Los minimapas son una de las características importantes de los videojuegos que guían a los jugadores a encontrar el camino y los objetivos a alcanzar. Por otro lado, Reder Textures se crea y actualiza en tiempo de ejecución. En este blog, aprende el desarrollo de los minimapas con Render Texture en Unity. Echar un vistazo.
Render Texture es un tipo de textura que se puede renderizar. Las texturas de renderizado son tipos especiales de texturas que se crean y actualizan en tiempo de ejecución. Render Texture se utiliza para mejorar e implementar renderizado basado en imágenes, cámaras de vigilancia y mucho más.
Los juegos RTS a menudo requieren que el jugador realice un seguimiento de su movimiento de tropas y del enemigo, mientras microgestiona la recopilación de recursos, la construcción de bases y muchas otras facetas de su estrategia general.
Para ayudar a hacer frente a este exigente nivel de microgestión, el jugador tiene a su disposición varias herramientas, como la capacidad de crear grupos de control, guardar ubicaciones en el mapa y usar una gran cantidad de teclas de acceso rápido. Sin embargo, ninguna de estas herramientas supera la utilidad inigualable del minimapa.
Síguenos en nuestro canal de YouTube dedicado a tecnología, marketplace de proyectos tecnológicos, cursos online y tutoriales de desarrollo de videojuegos. Ofrecemos consultoría en desarrollo de software, marketing online, servicios de TI, hosting web, dominios web y más.
Hay una gran cantidad de videojuegos por ahí y en esta época de juegos móviles y en el hogar, las opciones nunca han sido tan grandes. Entonces, ¿cómo puede eliminar el ruido y encontrar lo «mejor de» para cualquier tema elegido? Bueno, estamos aquí para ayudar a celebrar y destacar algunos de los últimos, mejores e inolvidables juegos a lo largo de los años.
Para nuestra serie continua de artículos que describen los mejores videojuegos, esta vez nuestra atención se centra en los mejores juegos de disparos en tercera persona de todos los tiempos. Desde juegos de disparos caóticos hasta aventuras caprichosas, hay una buena opción para abrir el apetito.
Los juegos de disparos en tercera persona para PC se sumergen en la atmósfera del juego no tanto como sus contrapartes en la industria con una vista desde los ojos del héroe. Sin embargo, en los juegos de disparos donde la cámara está fija para el personaje principal, hay características únicas, por ejemplo, el ángulo de visión es más amplio, por lo que los enemigos a la vista son más, lo que significa que el enemigo no pasará desapercibido incluso en una situación en la que intentará acercarse sigilosamente por la espalda.
Código para habilitar opción de copiar y pegar todos los componentes de un Objeto en las opciones del Editor de Unity.
/*
Una pequeña pero muy útil extensión de editor simple para copiar
y pegar todos los componentes
author: Darwin Palma
*/
using UnityEngine;
using UnityEditor;
using System.Collections;
public class ComponentsCopier : EditorWindow
{
static Component[] copiedComponents;
[MenuItem("GameObject/Copy all components %&C")]
static void Copy()
{
copiedComponents = Selection.activeGameObject.GetComponents();
}
[MenuItem("GameObject/Paste all components %&P")]
static void Paste()
{
foreach (var targetGameObject in Selection.gameObjects)
{
if (!targetGameObject || copiedComponents == null) continue;
foreach (var copiedComponent in copiedComponents)
{
if (!copiedComponent) continue;
UnityEditorInternal.ComponentUtility.CopyComponent(copiedComponent);
UnityEditorInternal.ComponentUtility.PasteComponentAsNew(targetGameObject);
}
}
}
}
Síguenos en nuestro canal de YouTube dedicado a tecnología, marketplace de proyectos tecnológicos, cursos online y tutoriales de desarrollo de videojuegos. Ofrecemos consultoría en desarrollo de software, marketing online, servicios de TI, hosting web, dominios web y más.
El desarrollo de juegos independientes es una tendencia hoy en día. Recientemente, podemos notar que algunos de los principales desarrolladores de triple A dejan sus trabajos, donde solían liderar grandes proyectos, para comenzar sus propios estudios de juegos. O incluso los nuevos talentos, de los estudios de juegos independientes más vendidos, se niegan a mudarse a las principales editoriales, aferrándose a sus orígenes para enfocarse en expandir y mejorar sus franquicias de juegos independientes que los hicieron populares.
Con el mercado de juegos independientes como evidencia, los desarrolladores de juegos tienen cada vez más herramientas para desarrollar sus propios juegos en la actualidad. Los propios motores de juego, encargados de hacer más rápida y sencilla la tarea de creación de juegos, son aún más accesibles, sin necesidad de grandes inversiones.
Los creadores de Unity también brindan un gran mercado, Asset Store, donde es posible adquirir varios paquetes de nivel profesional a precios justos. Dichos activos pueden considerarse uno de los mejores aliados de los estudios independientes, ahorrando mucho tiempo y dinero. Incluso hay paquetes completamente gratuitos de alta calidad a considerar, que no dejan nada que desear en comparación con las alternativas pagas.
Síguenos en nuestro canal de YouTube dedicado a tecnología, marketplace de proyectos tecnológicos, cursos online y tutoriales de desarrollo de videojuegos. Ofrecemos consultoría en desarrollo de software, marketing online, servicios de TI, hosting web, dominios web y más.