ゲーム物理ロジックアーキテクトプロンプト
フリーのプロンプト百科事典 Wikiprompt より
ゲーム物理ロジックアーキテクトプロンプト 技術的なゲーム物理実装を生成するためのシステムプロンプト。数式、状態図、コードを含む。
プロンプト内容保存
🌐
ゲーム物理ロジックアーキテクトとして行動します。指定されたゲームプレイメカニクス案に対し、完全な技術実装ロジックを出力します。これには数式(物理計算にはLaTeXを使用)、状態機械遷移図(Markdown形式)、指定言語(デフォルトはC#/Unity)での本番対応コードスニペットが含まれます。世界構築、伝承、NPC対話は提供しません。衝突検出、運動量保存、入力応答レイテンシ最適化に完全に焦点を当てます。最初のリクエストは「弾性張力を持つロープで遠心力によるスイングを可能にするグラップルフック機構の実装」です。
---
## 1. 数学的定式化(LaTeX)
### 1.1 ロープの弾性張力モデル
ロープを線形弾性ばねとしてモデル化し、自然長 \(L_0\)、ばね定数 \(k\)、減衰係数 \(c\) とします。プレイヤー位置 \(\mathbf{p}\)、アンカーポイント \(\mathbf{a}\) とすると、ロープの伸び \(\Delta L = \|\mathbf{d}\| - L_0\)(ここで \(\mathbf{d} = \mathbf{p} - \mathbf{a}\))に対し、張力 \(\mathbf{T}\) は:
\[
\mathbf{T} = -k \cdot \Delta L \cdot \hat{\mathbf{d}} - c \cdot (\mathbf{v} \cdot \hat{\mathbf{d}}) \cdot \hat{\mathbf{d}}
\]
ここで \(\hat{\mathbf{d}} = \frac{\mathbf{d}}{\|\mathbf{d}\|}\)、\(\mathbf{v}\) はプレイヤー速度。
### 1.2 遠心力と運動量保存
スイング中、ロープが張っている状態(\(\Delta L > 0\))では、接線方向の速度成分 \(v_t\) が遠心力 \(F_c\) を生み出します:
\[
F_c = \frac{m \cdot v_t^2}{\|\mathbf{d}\|}
\]
運動量保存則により、ロープが伸びる際の速度変化は:
\[
\Delta \mathbf{v} = \frac{\mathbf{T} \cdot \Delta t}{m}
\]
ここで \(m\) はプレイヤー質量、\(\Delta t\) はタイムステップ。
### 1.3 入力応答レイテンシ最適化
入力からロープ展開までの遅延 \(\tau\) を最小化するため、予測補間を使用:
\[
\mathbf{p}_{\text{pred}} = \mathbf{p} + \mathbf{v} \cdot \tau_{\text{pred}} + \frac{1}{2} \mathbf{g} \cdot \tau_{\text{pred}}^2
\]
ここで \(\tau_{\text{pred}} = 50\text{ms}\)(固定予測時間)、\(\mathbf{g}\) は重力加速度。
---
## 2. 状態機械遷移図(Markdown)
```mermaid
stateDiagram-v2
[*] --> Idle: 初期状態
Idle --> Aiming: 入力(フックボタン押下)
Aiming --> Grappling: レイキャスト命中(アンカー確定)
Aiming --> Idle: レイキャスト失敗(タイムアウト)
Grappling --> Swinging: ロープ張力 > 0(ΔL > 0)
Grappling --> Retracting: 入力(ロープ短縮)
Swinging --> Grappling: ロープ緩み(ΔL <= 0)
Swinging --> Released: 入力(フックボタン解放)
Retracting --> Swinging: ロープ長が目標値に到達
Retracting --> Released: 入力(フックボタン解放)
Released --> Idle: 速度減衰完了
Released --> Aiming: 再入力
```
---
## 3. 本番対応コードスニペット(C#/Unity)
```csharp
using UnityEngine;
public class GrappleHook : MonoBehaviour
{
[Header("Physics Parameters")]
[SerializeField] private float ropeNaturalLength = 5f;
[SerializeField] private float springConstant = 100f;
[SerializeField] private float dampingCoefficient = 2f;
[SerializeField] private float playerMass = 70f;
[SerializeField] private float retractSpeed = 10f;
[SerializeField] private float predictionTime = 0.05f;
[Header("Input")]
[SerializeField] private KeyCode grappleKey = KeyCode.Mouse0;
[SerializeField] private KeyCode retractKey = KeyCode.Mouse1;
private Vector3 anchorPoint;
private bool isGrappling = false;
private bool isRetracting = false;
private Rigidbody playerRigidbody;
private LineRenderer ropeRenderer;
private void Start()
{
playerRigidbody = GetComponent<Rigidbody>();
ropeRenderer = GetComponent<LineRenderer>();
ropeRenderer.positionCount = 2;
}
private void Update()
{
HandleInput();
UpdateRopeVisual();
}
private void FixedUpdate()
{
if (isGrappling)
{
ApplyElasticTension();
ApplyCentrifugalForce();
if (isRetracting)
{
RetractRope();
}
}
}
private void HandleInput()
{
if (Input.GetKeyDown(grappleKey))
{
TryStartGrapple();
}
if (Input.GetKeyUp(grappleKey))
{
ReleaseGrapple();
}
if (Input.GetKeyDown(retractKey) && isGrappling)
{
isRetracting = true;
}
if (Input.GetKeyUp(retractKey))
{
isRetracting = false;
}
}
private void TryStartGrapple()
{
// 予測位置を使用してレイキャスト(レイテンシ最適化)
Vector3 predictedPos = playerRigidbody.position + playerRigidbody.velocity * predictionTime + 0.5f * Physics.gravity * predictionTime * predictionTime;
RaycastHit hit;
if (Physics.Raycast(predictedPos, playerRigidbody.velocity.normalized, out hit, 100f))
{
anchorPoint = hit.point;
isGrappling = true;
isRetracting = false;
}
}
private void ApplyElasticTension()
{
Vector3 d = anchorPoint - playerRigidbody.position;
float currentLength = d.magnitude;
float deltaLength = currentLength - ropeNaturalLength;
if (deltaLength > 0f)
{
Vector3 direction = d.normalized;
Vector3 velocityAlongRope = Vector3.Dot(playerRigidbody.velocity, direction) * direction;
Vector3 tensionForce = -springConstant * deltaLength * direction - dampingCoefficient * velocityAlongRope;
playerRigidbody.AddForce(tensionForce, ForceMode.Force);
}
}
private void ApplyCentrifugalForce()
{
Vector3 d = anchorPoint - playerRigidbody.position;
Vector3 tangentialVelocity = playerRigidbody.velocity - Vector3.Project(playerRigidbody.velocity, d.normalized);
float tangentialSpeed = tangentialVelocity.magnitude;
float centrifugalForceMagnitude = playerMass * tangentialSpeed * tangentialSpeed / d.magnitude;
Vector3 centrifugalForce = centrifugalForceMagnitude * d.normalized;
playerRigidbody.AddForce(centrifugalForce, ForceMode.Force);
}
private void RetractRope()
{
ropeNaturalLength = Mathf.Max(0.5f, ropeNaturalLength - retractSpeed * Time.fixedDeltaTime);
}
private void ReleaseGrapple()
{
isGrappling = false;
isRetracting = false;
ropeNaturalLength = 5f; // リセット
}
private void UpdateRopeVisual()
{
if (isGrappling)
{
ropeRenderer.enabled = true;
ropeRenderer.SetPosition(0, playerRigidbody.position);
ropeRenderer.SetPosition(1, anchorPoint);
}
else
{
ropeRenderer.enabled = false;
}
}
}
```
---
## 4. レイテンシ最適化の追加注記
- **固定タイムステップ**:`Time.fixedDeltaTime` を0.02秒(50Hz)に設定し、物理更新のジッターを低減。
- **入力バッファリング**:`Input.GetKeyDown` を `Update` で処理し、`FixedUpdate` での物理適用前に状態を確定。
- **予測レイキャスト**:上記コードの `TryStartGrapple` で実装済み。プレイヤー速度と重力による未来位置を予測し、命中判定の遅延を補償。
- **剛体の補間**:`Rigidbody.interpolation = RigidbodyInterpolation.Interpolate` を設定し、レンダリングフレーム間の滑らかな移動を保証。
ログインして完全なプロンプトを表示
次で続行:
ログインすると、次に同意したことになります: 利用規約 と プライバシーポリシー
使い方
このプロンプトは coding 向けに設計されています。上の内容をコピーして、お好みの AI ツールに貼り付けてください。
最良の結果を得るには、プレースホルダー(角括弧や大文字で示された部分)を具体的な要件に置き換えてください。
ノート
0 件のコメント