Page 2 sur 6

Re: RTS

Publié : 02 Sep 2014 13:53
par axel
Excellente cette démo, qui est déjà très tactique.

Re: RTS

Publié : 02 Sep 2014 16:13
par cayou66
Je pense que du coup ceci devrait t'intéresser:

http://www.youtube.com/watch?v=bkdMIE8yoG0

Re: RTS

Publié : 02 Sep 2014 17:19
par zugsoft
Merci pour cette vidéo, je vais regarder ce soir en détail.

Dans un RTS on a besoin de connaitre si un adversaire est assez proche pour lui tirer dessus ou pour l'attaquer.
Pour ça il y a 2 solutions à mon sens

RayCast et SphereCast
J'avais utilisé SphereCast pour faire cela, ce qui fonctionne très bien avec peu d'objets et en limitant le nombre de SphereCast par seconde.
J'ai ensuite utilisé RayCast, en faisant tourner le rayon petit a petit soit en l'incrémentant, soit avec un random, pas mieux au niveaux perfs pour un grand nombre d'objet.
A savoir qu'uniquement un seul Thread est utilisé par Unity, donc en effet niveau CPU on l'exploite pas à fond.
J'ai utilisé des Coroutines et des appels dans Update et FixedUpdate.

Tableau perso d'objet
J'ai ensuite créé une méthode qui récupère tous les objets 10 fois par seconde et qui les range dans 2 tableaux(joeur1,joeur2), et au lieu d'appeler RayCast , j'appel une méthode via un Thread qui va lire tout le tableau pour trouver l'adversaire le plus proche.
Le gain de performance est spectaculaire, je suis passé de 33img/s a 48img/s.
Le problème est que chaque objet lance son propre Thread, et ce n'est pas très stable.

Apres 8H de développement, J'ai créé une Class static pour gérer tout ça dans un seul Thread.
J'ai encore gagné un peu en perf, avec 450 unités je suis maintenant en dessus des 50img/s en mode défense(detection ennemies), et surtout en fiabilité, plus aucun problème de saccade.

Image

A savoir que Unity ont aussi interdit les accès à leur objets par un autre Thread que le leur, pour ne pas rendre le moteur instable, ce qui complexifie mon code car je dois copié le contenu des objets au lieu de juste y accéder.

Re: RTS

Publié : 02 Sep 2014 23:45
par Alesk
Salut,

Si tu veux un réel gain de performances "spectaculaire" (passer de 33 à 48 img seconde c'est rien du tout dans ce cas), au lieu de traverser tout le tableau pour trouver les adversaires les plus proches, utilises un quatree / un octree, ou une simple voxelisation de l'espace, afin de répartir tes entités dedans et de ne faire une boucle de proximité que sur les entités se trouvant proches les une des autres.
Là tu vas drastiquement réduire les boucles ;)

Tu peux aussi faire un tour ici : http://jitter-physics.com/wordpress/?p=31

Pour le coup des limitations de threads, tu peux essayer de passer par un tableau d'index (donc des int) représentant les positions de tes objets dans le tableau d'origine
Ainsi tu évites de faire des copies pour rien.
Mais peux-tu préciser dans quel cas tu as ce souci plus précisément ?

Re: RTS

Publié : 03 Sep 2014 00:30
par zugsoft
Merci bien, je vais lire tout ca, j'essaye de comprendre le principe, mais je ne pense pas y gagner grand chose, meme je désactive complément ma recherche de proximité le nombre d'img/s ne monte pas.
C'est au niveau GPU que ca limite maintenant, et aussi les navmeshs qui consomment pas mal.
Mais je ne veux pas faire un RTS avec 5000 unités pour mobile :mrgreen: faudrait des écrans de 20 pouces :mrgreen:
J'ai compris le principe que tu m'as donné comme liens, je vais quand meme regarder de modifier mon code, et voir si ca ameliore encore un peu mes perfs, mais je n'y crois pas trop.


Je ne fais pas de copie de gameobject ou de transform dans mon Thread, je prends uniquement le nom de l'objet dans lequel il y a un numéro et je le colle dans un objet que je stoque dans une liste.


Petite mise à jour disponible 1800 unités, avec des corrections sur les tirs, les collisions, un super décors fait en 3 minutes :lol:

Re: RTS

Publié : 03 Sep 2014 04:02
par pated
Shogun 2 avec des cubes!

Quand tu dis avoir testé sur ipad, c'est sur ipad 1 que ça tourne à 60fps avec 300 unités? Si c'est ça chapeau!

Re: RTS

Publié : 03 Sep 2014 08:30
par Alesk
menfou a écrit :Je ne fais pas de copie de gameobject ou de transform dans mon Thread, je prends uniquement le nom de l'objet dans lequel il y a un numéro et je le colle dans un objet que je stoque dans une liste.
Pourquoi tu colles des string avec des numéros dans un objet puis dans une liste au lieu de directement stocker les numéros dans la liste ?

Re: RTS

Publié : 03 Sep 2014 11:04
par zugsoft
Je ne stock pas de String dans mon objet, je fais un substring du nom des gameobjects (ex toto1234->1234) et je stock uniquement 1234 dans un attribut de ma Class.

Je ne peux pas utiliser l'ID unique Unity, car il n'existe aucune methode Unity permettant de rechercher par ID.
Soit c'est par nom, soit par Tag, completement stupide de la part de Unity :roll:

Voila pour les perfs sur iPad1 et iPad Air, sachat que je limite le framerate a 30img/s
http://www.youtube.com/watch?v=QxIAYMwbOaQ

Re: RTS

Publié : 03 Sep 2014 13:26
par Alesk
Ok mais pourquoi tu ne stockes pas toutes tes instances de classe dans une liste statique, et ensuite tu ne bosse qu'avec les index des éléments dans cette liste.
Ainsi tu ne jongles qu'avec des int dans tes threads et non plus des classes, ça sera bien plus léger et ne fera plus aucune allocation.
Depuis le thread, du moment que tu n'ajoutes/enlève pas d'éléments à la liste de classes, tu pourras accéder à chaque instances pour modifier leurs propriétés (à partir du moment où tu ne tapes pas sur une même instance à partir de deux threads différents)

Re: RTS

Publié : 03 Sep 2014 14:32
par zugsoft
La List est deja static, il n'y a vraiment pas beacucoup a gagner en appliquant une autre methode de gestion de cette liste d'objet.
L'Update ou je fais la construction de la List consomme un temps de 0ms dans le profiler.
Ce qui consomme c'est le Camera.Render, et GUIRepaint en defense.

Dans mon Thread de gestion des distances, je ne fais que lire une liste static de mon objet avec uniquement un Vector3 pour la position , et 2 Int.
Le Thread stock 2 Pools pour gerer les demandeurs et les recepteurs d'information, je n'ai donc aucun blocage dans l'Update ou je demande la position du plus proche car au moment ou je fais ma demande, je recois le resultat precedement calculer.

Je me focalise sur ce qui consomme réellement pour l'instant, mais par soucis de bon développement, je regarderai rapidement comment optimiser ça.

C'est en mode recherche de chemin et attaque ou il y a du boulot encore a produire, si je désactive le navmesh agent lorsqu'il est en mode attaque, l'adversaire passe a travers car il n'a pas de rigidbody.
Si je rajoute un rigidbody, je me retrouve avec des objets qui passent a travers le sol meme en mettant des contraintes sur la translation Y.
Le navmesh est un peu gourmand, mais il n'y a aucun effet étrange de constaté par rapport a rigidbody.


Juste un essai avec 5000 unités :mrgreen:
5000unités

On rentre dans un autre monde, je m'aperçois que Unity est limité à 2048 éléments en Batch, ce qui pénalise grandement les performances.