Noticias

¡RECUERDA QUE SI ERES UN NUEVO USUARIO, DEBES PRESENTARTE PARA PODER PUBLICAR MENSAJES! | TENEMOS CANAL OFICIAL DE TELEGRAM: t.me/unity3dspain

Temas recientes

Habilidades!! Como las gestiono??

Iniciado por Stradmann, Febrero 04, 2019, 10:16:09 PM

Tema anterior - Siguiente tema
Hola! Esta es la situacion, tengo unos personajes con una serie de habilidades. De esas habilidades hay de dos tipos, las de combate i las de lider. Las de combate no me preocupan porque se activan al hacer click, pero las de lider afectan diferentes partes del combate, por ejemplo.. una aumenta el daño de los ataques de todos, otro reduce el coste de activar las habilidades de todos... Quisiera evitar escribir el combate con un if en cada parrafo para ver si hay este lider u este otro para hacer esto de una manera u otra. Me gustaria tener un objeto habilidad que hiciera las modificaciones y asi si quiero añadir mas personajes con sus nuevas habilidades solo tenga que programar eso... hay alguna manera de hacer un override de una funcion que pertenece a otra clase? o algo parecido... que herramienta podria usar? Gracias!

Por lo que entiendo, las habilidades de líder son "buffers" que modifican temporalmente los stats de toda la party de personajes...
 
 
 
Es un tema complicado porque, dependiendo del nivel que tengas en programación, te puede parecer muy difícil de programar. La idea es crear un árbol o sistema de atributos.
 
@Eskema tiene conocimiento para impartir esa materia...

Cita de: pioj date=1549325189Por lo que entiendo, las habilidades de líder son "buffers" que modifican temporalmente los stats de toda la party de personajes...
   
   
       
   
   
      Es un tema complicado porque, dependiendo del nivel que tengas en programación, te puede parecer muy difícil de programar. La idea es crear un árbol o sistema de atributos.
   
   
      @Eskema tiene conocimiento para impartir esa materia...
   


Venía a decir lo mismo, el sistema de atributos de  @Eskema es una pasada. Ahora no sé si estará por algún sitio, yo lo vi en sus directos y luego luego en youtube pero ya no está.  

Pues como han dicho por aqui, tienes que escribir un sistema de attributos y que tus personajes lo usen. Mi sistema ya no es publico dada la cantidad de emails negativos y feedback que recibi, tome la decision de que no valia la pena tener cosas publicas.
 
 
 
Por ejemplo mis personajes NO tienen la tipica clase:
 

class Personaje{
int fuerza = 5;
int defensa = 0;
}

 
etc,etc.
 
En su lugar tengo una clase attributo de la que heredo cada stat y el personaje tiene una lista de esos atributos:
 

class BaseAtributo{
float value = 0f;
float minValue = 0f;
float maxValue = 0f;
}

 
y Sobre esa clase heredo
 

class Attack : BaseAtributo{
}
class Defense : BaseAtributo{
}
class Movement : BaseAtributo{
}

 
 
 
Ahora mi personaje es 
 

class Personaje{
List<BaseAtributo> atributos = new List<BaseAtributos>();
}

 
 
 
Con lo cual solo debo loopear la lista y ver que atributo tengo y cual quiero gastar.
 
 
 
A esto solo le añades un sistema de modificadores, que no son mas que los atributos que modificas.
 

class Modifiers{
List<BaseAtributo> modificadores = new List<BaseAtributo>();
  //bla bla metodos aqui para devolver un valor basado en el tipo con reflection
}

 
Tu personaje ahora tiene:
 

class Personaje{
List<BaseAtributo> atributos = new List<BaseAtributo>();
Modifiers modifers = new Modifiers();
}

 
 
 
 
 
Y cualquier modificador lo pones en la lista. Luego recorres la lista de atributos del personaje y los comparas con los modificadores para ir sumando su valor actual y saber que su fuerza original era 10, y la modificada (por cualquier modificador) es ahora por ejemplo 13.
 
Los modificadores les pones tiempo o turnos segun tu juego para que se desactiven pasado un tiempo, o permanezcan activos siempre, por ejemplo un anillo que me da +1 de ataque y estara activo hasta que me deshaga del anillo.
 
 
 
En algun sitio de tu codigo de clase personaje o controller tipico tendras algo como
 

float GetCurrentAttack(){
float value = 0f;
foreach (BaseAtribute attr in atributos){
foreach(BaseAtribute modifier in modifiers){
 
if (modifier.typeof(Attack) && attr.typeof(Attack)){
value = attr.Value += modifier.Value;
}
}
 
return value;
}

 
 
 
Y asi devolveras el valor que sea que tenga el atributo Attack. La clase Modifiers es la que se encarga de mantener una lista de los modificadores, con lo cual haces funciones en esa clase para devolver el valor del tipo que quieras pasado por reflection, y luego se lo sumas a tu valor y sabes que tienen sus stats.
 
Lo mismo vale para si un estado es veneno, veneno solo quitaria vida durante X tiempo, con lo cual es un modificador del atributo Vida, y sera tipo value -= 2;
 
Asi en este caso tu atributo vida iria bajando de valor cada vez que lo compruebes hasta que el veneno se desactive porque termine su tiempo.
 
 
 
Todo esto es pseudo codigo, no copies y pegues tal cual.....
 
 
 
Espero que te de una idea mas o menos de como hacerlo.
 
 
 
 
 
 

Cita de: Eskema date=1549368185Pues como han dicho por aqui, tienes que escribir un sistema de attributos y que tus personajes lo usen. Mi sistema ya no es publico dada la cantidad de emails negativos y feedback que recibi, tome la decision de que no valia la pena tener cosas publicas.
   


Pues que pena que haya pasado eso, desde mi humilde posición te doy las gracias por este sistema que me pareció muy práctico y versátil. Gracias por haber compartido este conocimiento y aunque seguro que mi implementación es mil veces mejorable lo he usado en el proyecto que estoy realizando, y me ha servido de mucho. 


Saludos, 

Febrero 05, 2019, 03:50:00 PM #5 Ultima modificación: Febrero 05, 2019, 04:58:51 PM por Stradmann
Gracias!!! Voy a intentarlo a ver si lo he entendido bien y vuelvo, porque me parece que estoy aprendiendo un poco desordenadamente y esos huecos hacen que no entienda bien algunas cosas. Por ejemplo, me surgen dudas como si todos los personajes tienen la lista de atributos, todos acceden a la clase fuerza por ejemplo y es la misma para todos? o cuando haga la lista de atributos en la clase personaje, cada referencia me creara una instancia de ese atributo? si es asi, entonces la classe modifiers tambien creara sus propias instancias de atributos no? entonces, la clase personaje se crea su propia instancia de modifiers no? entonces la clase midifiers tiene todas las modificaciones posibles, y en cada personaje, las que no use valdran 0...y si son scriptableObjects tambien hace instancias? no, no? no se, voy a intentar hacerme un ejemplo practico con lo que Eskema ha escrito, a ver si logro que funcione.. os dire que tal o que nuevas dudas surgen.. Gracias!!

 
 
Cita de: Ufita date=1549369554Pues que pena que haya pasado eso, desde mi humilde posición te doy las gracias por este sistema que me pareció muy práctico y versátil. Gracias por haber compartido este conocimiento y aunque seguro que mi implementación es mil veces mejorable lo he usado en el proyecto que estoy realizando, y me ha servido de mucho. 


      Saludos, 
   


Hay gente para todo, a mi no me gusta que me envien un correo diciendome que el video es una mierda porque la implementacion es muy chapucera y el sistema tal o cual la implementa mejor, o emails pidiendome el codigo como si yo tuviera alguna obligacion de compartir nada.... Es frustrante....
 
 
 
Cita de: Stradmann date=1549378200Gracias!!! Voy a intentarlo a ver si lo he entendido bien y vuelvo, porque me parece que estoy aprendiendo un poco desordenadamente y esos huecos hacen que no entienda bien algunas cosas. Por ejemplo, me surgen dudas como si todos los personajes tienen la lista de atributos, todos acceden a la clase fuerza por ejemplo y es la misma para todos? o cuando haga la lista de atributos en la clase personaje, cada referencia me creara una instancia de ese atributo? si es asi, entonces la classe modifiers tambien creara sus propias instancias de atributos no? entonces, la clase personaje se crea su propia instancia de modifiers no? entonces la clase midifiers tiene todas las modificaciones posibles, y en cada personaje, las que no use valdran 0...y si son scriptableObjects tambien hace instancias? no, no? no se, voy a intentar hacerme un ejemplo practico con lo que Eskema ha escrito, a ver si logro que funcione.. os dire que tal o que nuevas dudas surgen.. Gracias!!
   


Cada personaje tiene su clase, con lo cual cada clase es para cada personaje y no se comparten datos. Yo NO uso scriptable objects, me gusta mas hacerlo con ficheros json que se parsean muy bien y los tengo agrupados y mejor organizados que los scriptables. Ademas asi me son "multiplataforma" y me los llevo a otro engine que usa C# sin depender de un scriptable.
 
Volviendo al tema.
 
Tu tienes tu gameobject con su clase personajeManolo y asi con el resto de personajes, cada uno es su gameobject y su clase. Y cada uno accede a SUS datos, nadie ve los datos de nadie.
 
Lo que se suele hacer es tener un controller/manager que gestiona esos personajes/enemigos y los tiene en una lista
 
 
 
Un ejemplo de fichero json seria este:
 

{
"Characters": [
   {
      "NameId": "Knight_Blue",
      "Name": "",
      "PortraitName": "portrait_1",
      "ClassName": "Archer",
      "Race": "HUMAN",
      "Gender": "MALE",
      "ChanceToDieInQuestOrTravels": 70,
      "Attributes": [
         {
            "Value": 2,
            "MinValue": 1,
            "MaxValue": 20,
            "IncreaseStep": 1,
            "AttributeType": "Addition",
            "ClassName": "AttackAttr"
         },
         {
            "Value": 3,
            "MinValue": 1,
            "MaxValue": 20,
            "IncreaseStep": 1,
            "AttributeType": "Addition",
            "ClassName": "ConstitutionAttr"
         },
         {
            "Value": 4,
            "MinValue": 1,
            "MaxValue": 100,
            "IncreaseStep": 1,
            "AttributeType": "Addition",
            "ClassName": "MovementAttr"
         },
         {
            "Value": 80,
            "MinValue": 1,
            "MaxValue": 100,
            "IncreaseStep": 1,
            "AttributeType": "Addition",
            "ClassName": "AgeAttr"
         },
         {
            "Value": 10,
            "MinValue": 1,
            "MaxValue": 100,
            "IncreaseStep": 1,
            "AttributeType": "Addition",
            "ClassName": "DefenseAttr"
         },
         {
            "Value": 20,
            "MinValue": 1,
            "MaxValue": 100,
            "IncreaseStep": 1,
            "AttributeType": "Addition",
            "ClassName": "MagicAttr"
         },
         {
            "Value": 1,
            "MinValue": 1,
            "MaxValue": 100,
            "IncreaseStep": 1,
            "AttributeType": "Addition",
            "ClassName": "MoraleAttr"
         },
         {
            "Value": 4,
            "MinValue": 1,
            "MaxValue": 100,
            "IncreaseStep": 1,
            "AttributeType": "Addition",
            "ClassName": "StealthAttr"
         },
         {
            "Value": 4,
            "MinValue": 1,
            "MaxValue": 100,
            "IncreaseStep": 1,
            "AttributeType": "Addition",
            "ClassName": "MovementAttr"
         },
         {
            "Value": 100,
            "MinValue": 1,
            "MaxValue": 100,
            "IncreaseStep": 1,
            "AttributeType": "Addition",
            "ClassName": "HealthAttr"
         }
      ],
      "Skills": [
         {
            "Value": 2,
            "MinValue": 1,
            "MaxValue": 20,
            "IncreaseStep": 1,
            "AttributeType": "Addition",
            "ClassName": "PerceptionSkill"
         },
         {
            "Value": 3,
            "MinValue": 1,
            "MaxValue": 20,
            "IncreaseStep": 1,
            "AttributeType": "Addition",
            "ClassName": "ArmorWeaponSkill"
         }
      ]
   }
]
}

 
Ahi dentro defino TODOS los personajes de mi juego y les pongo los stats/atributos que me da la gana. No configuro nada desde unity. Todo se hace via fichero, asi el designer o quien sea solo modifica este fichero y no me afecta al proyecto.
 
En cualquier caso, lo dicho, cada personaje tiene su lista de atributos y la clase modifiers que guarda una lista de atributos modificados.
 
Si te fijas hasta la salud es un atributo (HealthAttr) y cada vez que me pegan le añado un modificador de Health con daño negativo porque es la "salud" que me quitan. Una vez recibido el golpe y añadido el modificador lo que hago es recorrer la lista para saber cual es mi nivel actual de salud, por si el personaje ha muerto.
 
Y lo mismo con cualquier otro modificador o atributo.
 
 
 
Esto es un sistema que requiere tiempo para interiorizarlo y entenderlo, pero una vez le pillas el truco te das cuenta que no puedes vivir sin esto XD
 
Porque tu codigo deja de depender de ifs, haces un if en tu funcion
 

void RecibeDaño(int daño){
//creo un modificador de salud con el parametro negativo del golpe que me dan
//recorro mi lista de modificadores para que me diga el total de salud que tengo
//si el personaje muere pq no tiene salud me encargo de llamar desde aqui a quien corresponda
}

 
 
 
asi no hay if (salud < 0) etc, etc, etc en el sentido de que no tengo una variable llamada salud, tengo un atributo que tendra modificadores o no

Gracias!! Tardare unos dias en investigar y aprender un poco todo esto...  ya cuando tenga las ideas mas claras vuelvo a por mas;)

Etiquetas: