この記事では、アラクニッド車両のコードを作成する例を使用して、3つのゲームエンジンで動作する機能について説明します。

「スパイダーカー」の一般的な構造は次のように想定されています。6本の足があり、制御スクリプトの各コピーは、主要構造の動きを追跡し、特定の距離で離れると足を新しい位置に移動します。
より正確な足の着地のために、レイキャストを追加することが計画されていましたが、たとえば、同じゴドットで、そのような精度が特に必要とされない上面のゲーム用のスパイダーを作りたかったのです。
したがって、タスクは、エンジン内に目的の構造を形成し、別の足のコードを書くことでした。さまざまな開発環境で起こったことは次のとおりです。

ゴドット
ここでは、すでに車とスパイダーの準備ができている 小さなプロジェクトがあり、ホイールのない車のサブクラスを含むシーンの1つ(プレハブ)に追加することにしました。
specific_baseシーン自体は、ベースにダミーノードがあり、移動せずに世界のどこかにぶら下がっていて、その中の運動体が世界中を移動するように配置されています。カメラはシーンの内側にありますが、それに従うだけで体の外側にあります。

スパイダーを作成するために、足のダミーポイント(体に取り付けられている場所ではなく、地面に配置されている場所)を含む別のノードを体の中に追加しました。

便宜上、ここ、このシーンでは、体の外側に足自体を配置しました。それらのそれぞれを制御するスクリプトは、足を転送することに加えて、常にそれを「スパイダー」の中心に拡張します。

Godotエディター内の
コードコードの記述。私はGDScriptを使用します。これは、GodotのC#で書くことにあまり意味がないためです(中括弧のファンではありません)。
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)
ゴドットスパイダー生地のカットシーン。ボーナスとして、「スパイダー」も使用されているが純粋にアニメーション化されたボクセルの世界をテラフォーミングする別のゲームの瞬間と、スパイダーの形が追加される前のプレイキャンバス上の車のデモも含まれていました。

ユニジン
Godotの実装の準備ができた後、このソリューションをUnigineエンジンに移植することにしました。そこでは車でのプロジェクトもありましたが、 過負荷にならないように別の「スパイダー」フォークを作ったので、後でホイールを完全に取り外して、どういうわけか別々に開発しました。

プレイヤーの車のボディが配置されているゲームの世界の全体のシーンがあります。ゲームの開始時に、別々に配置されたホイールがこのボディにドッキングされます。
体の中にダミーを探しています。その中に足の位置を設定するポイントがあります。

足は単にゲームの世界に配置されます。動き自体は車輪を通して実現されたままですが、それらの視覚的表現は無効になっています。

Unigineは、コード編集用の外部環境を起動します。
コード:
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;
}
}
ユニジンスパイダー生地カットシーン

PlayCanvas
PlayCanvasは、javascriptを使用するwebGLゲームエンジンです。最近、私はそれを理解し始めました。UnityとGodotのクロスのように見えますが、オンライン開発では、エディターがブラウザーで開きます。
この場合、このプラットフォームで提供されている例の1つをやり直し、車のモデルをいくつか追加し、ジャンプ、カメラの追加、マテリアル/設定の操作などの機能を少し追加しました。
元の例のベースカーの視覚的表現は、部分的に無効にしたソリッドモデルによって与えられ、制御スクリプトによってモデルの内側から引っ張られたホイールのみが残りました(つまり、シーン階層内の個別のノードによって巻き上げられていません)。このビジュアルは、ゲームプレイ中に動く物理的なホイールモデルにしがみついています。
このプロジェクト内に「スパイダー」を実装するために、私は車の視覚的表現の中に「スパイダーセンター」を作成しました。すぐに「蜘蛛の形」に切り替えて元に戻したかったので、便宜上「蜘蛛の体」を入れ子にしています。

したがって、ローカルの「スパイダー」もホイールドライブの上に配置され、ホイール自体は非表示になります。スパイダーフレームを物理ノードに接続する方が正しいかもしれませんが、フォームの切り替えは、車のビジュアルを備えたノードのスクリプトにすでにあり、他のモデルはこのノード内にあるため、簡単にするためにこのオプションを選択しました。実際、そのスクリプトのビジュアルは物理の背後に移動し、足のスクリプトはすでにビジュアルと一緒に移動するスパイダーフレームを見ています。理論的には、ここで非同期が発生する可能性があります。少なくとも、弱いデバイスでは、一部の足に位置を計算する時間がなく、一部の動きしかありません。
したがって、一般的に、解決策はもちろん、物理学や剛体に結び付けられていません。実際、脚は、力によって、または単に位置を変更することによって、メインオブジェクトをどのように動かすかを気にしません。

足はシーン自体にありますが、有効/無効にするために、足は別々のノード内に集められているため、別々のリンクでそれぞれを無効にするのではなく、簡単に無効にすることができます。

playcanvasでは、コードエディタが新しいブラウザタブ
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());
}
};
一般に、これまでのところ、4本の脚を持つ空白のスパイダーを取得しており、最適な計算ではありません。 ここで
結果のフレームをテストでき
ます。
個人的には、ChromeとDolphinを使用して、それほど強力ではないスマートフォンで実行しようとしました。グラフィックはPsOneに似ており、一部の足の計算が機能しません。レベルが画面に表示されている間、足はマップの端に表示されます。弱いラップトップでは、Chromeには非常に強いブレーキがありましたが、Firefoxではすべてが正常に機能します。ディスクリートビデオカードを搭載したラップトップとステーショナリーでは、これらの両方のブラウザーで動作します。
PCでは、スマートフォンとは異なり、このデモではジャンプ(スペースバーを押す)、ストラフの準備(QとE)、レベルのリロード(R)を実行します。
結果
ご覧のとおり、言語とエンジンは異なりますが、それでも、スクリプト言語のファミリーの多くのことは、かなり類似した方法で実行されます。新しいゲームエンジンとフレームワークをどのくらいの頻度で習得しましたか。直面した主な問題は何でしたか。