Buenas a todos, me gustaría saber cual es la mejor forma de optimizar el guardado de objetos contenido en el servidor, es decir si suelto un objeto sobre el terreno, si mato un npc, ect que este objeto aparezca cuando vuelva a entrar al juego.
He pensado que lo mejor sería crear un método el cual guarde la referencia de dicho objeto (con su posicion, cantidad,tipo,ect) en mi base de datos y una vez vuelva a iniciar el juego que cargue todos los objetos contenidos en mi base de datos (servidor).
Me gustaría saber que opinan ya que no sé si esto conlleva mucho gasto de memoria o si relentizará mucho el inicio de sesión y si a la larga puede darme algún problema ya que es un juego online el cual soportaría gran cantidad de objetos.Por otra parte también me gustaría saber como harían para guardar la posición de cada personaje ya que si lo hago de forma que vaya mandádole sentencias de guardado de posición sobre mi base de datos, esto seguramente sería una sobrecarga bestial.
Muchas gracias de antemano.
asi es como se hace no se q mas quieres... para el manejo de memoria y BD busca paged terrain
Primero quería darte las gracias por la respuesta, entiendo que no tendré problemas entonces al cargar toda la lista de objetos existentes en el servidor cuando inicie sesión aunque se trate de un número de objetos como por ej 1000? me gustaría saber aunque sea el tiempo aprox que conlleva este proceso ya que cada objeto tendré que crearlo con Instantiate(Resources.Load("Ruta Objeto", posicion, rotacion)) + modificación de características de dicho objeto (cantidad, durabilidad, ect).
Por otro lado mencionas paged terrain, estoy buscando algo en internet pero no entiendo muy bien en que consiste, me podrías explicar por encima en que consiste y para que?
Y por último para guardar los objetos en mi bd he leido que lo mejor es guardarlos como binario ya que consumen menos memoria, de ser así imagino que tendré que llamar a cada objeto prefab con el mismo número binario que el asignado a la bd, ej Recibo desde la BD el ID: 1101, posicion: XXX, rotación: XXX y con estos datos realizo Instantiate(Resources.Load("1101",posicion, rotacion));
muchas gracias.
Bueno he de decir que he estado haciendo pruebas creando hasta 10.000 objetos al iniciar el juego por primera vez y la verdad que la carga es prácticamente inmediata, el único problema es que aumenta muchísimo la cpu haciéndolo injugable...Pienso que tiene que haber alguna manera de controlar la carga de objetos por área o algún modo, si alguien sabe cual sería el remedio mas aconsejable le estaría muy agradecido.
no has buscado bien terrain paging no? xD investiga hombre... investiga
Tras haber realizado algunas pruebas he de decir que ya conseguí cargar 10.000 objetos de forma instantánea sin aumentar la cpu.Por lo tanto el único problema que me queda por resolver es el guardado de posiciones en tiempo real de mi base de datos, por ahora pienso que la mejor solución sería guardar las posiciones en un txt cada 10 segundos haciendo un foreach de todos los jugadores del servidor (estos jugadores están almacenados en un objeto padre "Jugadores" siendo por lo tanto hijos de dicho padre ) guardando su posición y código de jugador, y por último si se cae el servidor retomo las posiciones de todos los jugadores importando dicho txt en la base de datos antes de arrancar el servidor.Expongo esta posible solución ya que pienso que si en lugar de almacenar la información en un txt la almacenase directamente en la base de datos podría tener serios problemas de sobrecarga.Gracias y escucho opiniones
O sea te estás montando todo por si cae el servidor? Por qué va a corrom*** la bbdd si se cae el servidor, si son transacciones abiertas/cerradas? Tal vez la última, pero lo dudo mucho. Tienen sistemas de recuperación muy avanzados sin entrar en detalles. Es más probable que se corrompa el archivo de texto que la bbdd, sobretodo como lo pille abierto. Si ves más seguro un fichero de texto que una bbdd, pues guárdalo todo en el fichero de texto.Si realmente ésta es tu preocupación, utiliza redundancia, copias espejo de la bbdd, hay mil cosas. Tampoco conozco los motivos de porqué habría de caerse el servidor.Es como diseñar un coche partiendo de la base qué seguro va a despeñarse por un barranco. Le ponemos un paracaídas por si se cae.Creo que es un ejemplo de crear algo partiendo de la excepción.
iRobb te agradezco tu punto de vista y lo tendré en consideración, actualmente estoy usando mi base de datos conectada por php, la cual interactua entre UNITY->PHP->MYSQL->UNITY de esta forma no tendré problemas? pienso que lo mejor ahora sería que conectase con mysql a través de unity diréctamente, teniendo en cuenta sólo y únicamente el php para recibir los datos del servidor de la base de datos (Para evitar posibles hackeos).
He intentado conectarme a la BD através de unity con el siguiente código en Java:
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
import System;
import System.Data;
import System.Data.SqlClient;
// Datos servidor
public var server:String = "localhost";
public var database:String = "juego";
public var user:String = "root";
public var password:String = "privado";
var dbcon : IDbConnection;
private var connectionString : String;
function Start () {
connectionString ="Server=" + server + ";Database=" + database + ";Uid=" + user + ";Pwd=" + password + ";";
//"Server=" + server + "; Database=" + database + "; User ID=" + user + "; Password=" + password + ";";
//SqlConnection()
dbcon = new SqlConnection(connectionString);
dbcon.Open();
resultado(); // Aquí se ejecuta todas las sql
dbcon.Close();
dbcon = null;
}
function SQLQuery(command:String):IDataReader{
// Creamos la vbl ejecutora que ejecutará el comando
var dbcmd : IDbCommand = dbcon .CreateCommand();
// Guardamos el comando que vamos a ejecutar
var cmdSql : String = command;
// Añadimos el comando a la vbl que lo ejecuta
dbcmd.CommandText = cmdSql;
var reader : IDataReader = dbcmd.ExecuteReader();
return reader;
}
function resultado(){
var query:IDataReader = SQLQuery("SELECT * FROM " + database+".HABILIDADES");
while(query.Read){
var id:String = query["CodigoHabilidad"].ToString();
var nombre:String = query["CodigoCuenta"].ToString();
//var edad:String = query["edad"].ToString();
print("ID: " + id + "NOMBRE: " + nombre + "EDAD: " + ".");
query .Close();
query = null;
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Pero al conectarme me da el siguieinte Error dado en el procedimiento dbcon.Open:
SocketException: No se puede establecer una conexión ya que el equipo de destino denegó expresamente dicha conexión.
System.Net.Sockets.Socket.Connect (System.Net.EndPoint remoteEP, Boolean requireSocketPolicy)
/////////////////////////
[/quote]
Al conectarme por php no tengo ningún problema de conexión pero al intentarlo através de unity directamente me es imposible... alguien sabe como solucionar dicho error?
Muchas gracias a todos (//Smileys/invision/default_smile.png)
Entiendo que el código de PHP está en el servidor y el de Unity en el cliente. Si es así, es totalmente diferente el tipo de acceso.Si mysql no tiene habilitado el remote mysql desde el servidor (cpanel) para tu ip específica, no te va a dejar conectarte.
Tras investigar un tiempo he conseguido conectar la BD a través de unity directamente usando .Net 2.0 en lugar de .Net 2.0 Subset.Ahora que tengo configurada las 2 posibles formas de acceder a mi BD (por PHP y por Unity), me doy cuenta que no merece la pena interactuar con mi BD através de Unity ya que puede ser hackeada facilmente... pongo un ej:Creo un script el cual contiene un procedimiento de incremento de habilidad de 1 punto sobre el personaje del cliente, si logra acceder el hackeador a este script puede observar perfectamente la sentencia (INTO TO tabla (CodigoHabilidad, ValorHabilidad) VALUES (4, 1)), lo cual el hackeador modifica el valor 1 por un 100 y ya tendría la habilidad al máximo...Actualmente tengo todos los métodos de este tipo creados en el fichero PHP el cual es mas dificil de hackear, por lo tanto lo único que realizo desde unity es una llamada a este fichero y a ese determinado método y ya el se encarga de modificar los datos sobre la BD.Me gustaría saber si hay alguna forma de hacerlo seguro através de Unity directamente ya que muchas veces necesito obtener información de la BD de forma rápida y sin tener que realizar un parseInt, parseFloat, ect ya que php me devuelve la información por String... lo que conlleva un coste de rendimiento mayor.
Mira conceptos como JSON, encriptación y payload. Y respecto a los ficheros PHP, ya te digo que son más fáciles de obtener que el código que pongas en Unity. Pero bueno, como eres investigador, investiga y luego nos lo cuentas.