Comment assembler une araignée dans Godot, Unigine ou PlayCanvas

Bonne 21e année du 21e siècle.



Dans cet article, je vais passer en revue les fonctionnalités de travail dans trois moteurs de jeu, en utilisant l'exemple d'écriture de code pour un véhicule arachnide.







La structure générale de la "voiture araignée" a été supposée comme suit - il y a 6 pattes, chaque copie du script de contrôle, qui suit le mouvement de la structure principale et déplace la patte vers une nouvelle position lorsqu'elle s'éloigne à une certaine distance.

Pour un atterrissage plus précis des pattes, il était prévu d'ajouter des raycasts, mais, par exemple, dans le même Godot, je voulais faire une araignée pour un jeu avec une vue de dessus, dans lequel une telle précision n'est pas particulièrement nécessaire.



Ainsi, la tâche était de former la structure souhaitée à l'intérieur du moteur et d'écrire le code pour un pied séparé. Voici ce qui s'est passé dans différents environnements de développement:







Godot



Ici j'avais déjà un petit projet avec des voitures et une araignée prête, j'ai décidé de l'ajouter à l'une des scènes (prefabs) contenant une sous-classe de voitures qui n'ont pas de roues.



La scène specific_base elle-même est agencée de telle manière qu'à la base se trouve un nœud factice, qui est simplement suspendu quelque part dans le monde, sans mouvement, et le corps cinématique à l'intérieur se déplace dans le monde entier. La caméra est à l'intérieur de la scène, mais à l'extérieur du corps, simplement en la suivant.







Pour créer l'araignée, j'ai ajouté un nœud séparé à l'intérieur du corps, contenant les points factices pour les pattes (où ils sont placés sur le sol, pas là où ils sont attachés au corps).







Pour plus de commodité, j'ai placé les pattes elles-mêmes ici, dans cette scène, mais à l'extérieur du corps. Le script contrôlant chacun d'eux, en plus de transférer la patte, l'étendra constamment au centre de «l'araignée».





Code à l'intérieur de l'éditeur Godot



Ecriture du code. J'utilise GDScript, car je ne vois pas grand chose à écrire en C # dans Godot (pas tellement fan des accolades):



extends Spatial

export var distance = 2.5# ,    
export var step = 1#     ( )

#        ,      
export (NodePath) var spidercenter = null
var trg_center

export (NodePath) var spiderleg = null
var trg_leg

#     x  z
var x_dis = 0.0
var z_dis = 0.0

#-,   
var time_lag = -1.0

# 
func _ready():
	self.hide()# 
	trg_center = get_node(spidercenter)# 
	trg_leg = get_node(spiderleg)
	LegPlace()#      

#  
func _process(delta):
        #     .   ,      
	self.look_at(trg_center.global_transform.origin, Vector3(0,1,0))
	
        # ,    .    ,    ,         (             ,      ).              LegPlace
	if self.visible == false: self.show()

	if time_lag>=0:# - ,    
		time_lag +=1*delta 
		if time_lag>0.06:#       
			time_lag = -1.0
			LegPlace()
	else:#            
		x_dis = abs(trg_leg.global_transform.origin.x - self.global_transform.origin.x)
		z_dis = abs(trg_leg.global_transform.origin.z - self.global_transform.origin.z)
	
		if (x_dis + z_dis) > distance:#   ,  
			time_lag = 0.0
	
	pass
	
func LegPlace():#,    
	self.hide()
	step = step*(-1)
	self.global_transform.origin = trg_leg.global_transform.origin+Vector3(0,0,0.5*step)

      
      







Scène de la pâte d'araignée Godot. En prime, il comprenait également des moments d'un jeu séparé avec la terraformation du monde des voxels, où une "araignée" est également utilisée, mais purement animée, ainsi qu'une démo avec des voitures sur des toiles de jeu, avant que la forme d'araignée n'y soit ajoutée.







Unigine



Une fois la mise en œuvre de Godot prête, j'ai décidé de transférer cette solution sur le moteur Unigine. Là, j'ai aussi eu un projet avec des voitures , mais pour ne pas la surcharger, j'ai fait une fourche séparée "spider", de sorte que plus tard, probablement, en retirer complètement les roues et la développer séparément.







Il y a toute la scène du monde du jeu, dans laquelle se trouve le corps de la voiture du joueur. Au début du jeu, des roues situées séparément sont amarrées à ce corps.

Je cherche un mannequin à l'intérieur du corps, à l'intérieur duquel il y aura des points qui définissent les positions des pattes.







Les pattes sont simplement placées dans le monde du jeu. Le mouvement lui-même est laissé réalisé à travers les roues, mais leur représentation visuelle est désactivée.





Unigine lance un environnement externe pour l'édition de code



Code:



using System;// ""
using System.Collections;
using System.Collections.Generic;
using Unigine;

//  ,    
[Component(PropertyGuid = "5a8dd6f85781adf7567432eae578c5414581ddac")]
public class theLegBehavior : Component
{

	[ShowInEditor][Parameter(Tooltip = "CenterSpider")]//   
	private Node spiderCenter = null;
	[ShowInEditor][Parameter(Tooltip = "Target Leg Point")]//   
	private Node legPoint = null;

	//     
	private float x_dis= 0.0f;
	private float z_dis= 0.0f;

	private float ifps;//  
	private float time_lag = -1.0f;//-

	private void Init()//
	{
		node.Enabled = false;// 
		LegPlace();//  
		
	}
	
	private void Update()// 
	{
		ifps = Game.IFps;// 

		if (time_lag>=0.0f){//   
			time_lag += 1.0f*ifps;

			if (time_lag>=0.6f) {
				time_lag = -1.0f;
				LegPlace();
			}
		
		}else{
			x_dis = MathLib.Abs(legPoint.WorldPosition.x - node.WorldPosition.x);
			z_dis = MathLib.Abs(legPoint.WorldPosition.z - node.WorldPosition.z);
            	
			if (x_dis + z_dis > 0.8f){
				time_lag = 0.0f;
			}
			
		}

	}

        //   .        .         .       ,  ,    ,     - .         ,      Update.
	private void LegPlace()
	{
		node.Enabled = false;

		vec3 targetDirection = vec3.ZERO;
		targetDirection = (legPoint.WorldPosition - node.WorldPosition);

		quat targetRot = new quat(MathLib.LookAt(vec3.ZERO, targetDirection, vec3.UP, MathLib.AXIS.Y));

		quat delta = MathLib.Inverse(targetRot);
		delta.z = 0;
		delta.Normalize();

		node.WorldPosition = legPoint.WorldPosition;

        targetDirection = (spiderCenter.WorldPosition - node.WorldPosition);
		node.SetWorldDirection(targetDirection, vec3.UP, MathLib.AXIS.Y);

		node.Enabled = true;		
	}
}

      
      







Scène cinématique Unigine Spider Dough







PlayCanvas



PlayCanvas est un moteur de jeu webGL utilisant javascript. Récemment, j'ai commencé à le comprendre. Cela ressemble à un croisement entre Unity et Godot, mais avec le développement en ligne - l'éditeur s'ouvre dans le navigateur.



Dans ce cas, j'ai refait l'un des exemples proposés par cette plateforme, en y ajoutant quelques modèles de voitures, une petite fonctionnalité supplémentaire comme sauter, ajouter une caméra et jouer avec les matériaux / réglages.



La représentation visuelle de la voiture de base dans l'exemple d'origine a été donnée par un modèle solide, que j'ai partiellement désactivé, ne laissant que les roues, qui sont tirées de l'intérieur du modèle par son script de contrôle (c'est-à-dire qu'elles ne sont pas enroulées par des nœuds séparés dans la hiérarchie de la scène). Ce visuel s'accroche à un modèle de roue physique en mouvement pendant le jeu.

Pour implémenter "l'araignée" dans ce projet, j'ai créé un "centre de l'araignée" à l'intérieur de la représentation visuelle de la voiture. Pour plus de commodité, le "corps de l'araignée" est imbriqué à l'intérieur, car je voulais immédiatement passer à la "forme d'araignée" et inversement.







Ainsi, l '«araignée» locale est également placée au-dessus de la traction, et les roues elles-mêmes sont cachées. Il serait peut-être plus correct d'attacher le cadre d'araignée au nœud de physique, mais le passage d'une forme à l'autre est déjà situé dans le script du nœud avec le visuel de la voiture, et d'autres modèles se trouvent à l'intérieur de ce nœud, j'ai donc choisi cette option pour plus de simplicité. En fait, il s'avère que le visuel dans son script se déplace derrière la physique, et les scripts des pattes regardent déjà le cadre de l'araignée se déplacer avec le visuel. En théorie, il peut y avoir une certaine désynchronisation ici, au moins j'ai remarqué que sur les appareils faibles certaines pattes n'ont pas le temps de calculer les positions et seulement quelques mouvements.

Et donc, en général, la solution, bien sûr, n'est pas liée à la physique ou au corps rigide, les jambes, en fait, ne se soucient pas de la façon dont vous déplacez l'objet principal - par des forces ou simplement en changeant de position.







Les pattes sont situées dans la scène elle-même, mais pour faciliter leur activation / désactivation, elles sont collectées dans un nœud séparé, de sorte que vous pouvez simplement le désactiver, et non chacun par un lien séparé.





Dans playcanvas, l'éditeur de code est lancé dans un nouvel onglet de navigateur



Code:



var TheLegBehavior = pc.createScript('theLegBehavior');

//   
TheLegBehavior.attributes.add('N_spiderCenter', { type: 'entity' });
//     
TheLegBehavior.attributes.add('N_legPoint', { type: 'entity' });

//    
this.x_dis = 0.0;
this.z_dis = 0.0;

this.time_lag = -1.0;//-

//  ,     , -     
TheLegBehavior.prototype.initialize = function() {    
};

// 
TheLegBehavior.prototype.update = function(dt) {
    if (this.N_spiderCenter) {//  -    
        this.entity.lookAt(this.N_spiderCenter.getPosition());// ,     
    }
};

//.       ,     , , ,   .
TheLegBehavior.prototype.postUpdate = function(dt) {
    //,      
    if (time_lag>=0.0){
        time_lag+=1.0*dt;
        if (time_lag>=0.06){
            time_lag=-1.0;
            this.LegUpdate();
        }
        
    } else {
        
        x_dis = Math.abs(this.entity.getPosition().x-this.N_legPoint.getPosition().x);
        z_dis = Math.abs(this.entity.getPosition().z-this.N_legPoint.getPosition().z);
        
        if ((x_dis+z_dis)>3.0){
         time_lag=0.0;
        }
        
        
    }
};

//      ,        ", , ",       
TheLegBehavior.prototype.LegUpdate = function() {
    
    if (this.N_legPoint) {// ,   ,     
        this.entity.setPosition(this.N_legPoint.getPosition());
    }
      
};

      
      





En général, jusqu'à présent, nous avons obtenu une araignée vierge à quatre pattes et des calculs pas tout à fait optimaux.



Vous pouvez tester l'image résultante

ici .



J'ai personnellement essayé de courir sur un smartphone pas trop puissant via Chrome et Dolphin, les graphismes deviennent similaires à PsOne et les calculs pour certaines pattes ne fonctionnent pas, alors que le niveau est visible à l'écran, des pattes apparaissent au bord de la carte. Sur un ordinateur portable faible, il y avait des freins très puissants dans Chrome, mais tout va bien dans Firefox. Sur un ordinateur portable avec une carte vidéo discrète et sur un ordinateur fixe, il vole dans ces deux navigateurs.



Sur un PC, contrairement aux smartphones, cette démo fonctionne avec un saut (en appuyant sur la barre d'espace), en préparant un strafe (Q et E) et en rechargeant un niveau (sur R).



Résultat



Comme vous pouvez le voir, les langages et les moteurs sont différents, mais néanmoins, beaucoup de choses dans la famille des langages de script se font de manière assez similaire. À quelle fréquence avez-vous maîtrisé de nouveaux moteurs et frameworks de jeu, quelles ont été les principales difficultés rencontrées?



All Articles