Prompt de Arquitecto de Lógica de Física para Juegos
De Wikiprompt, la enciclopedia libre de prompts
Prompt de Arquitecto de Lógica de Física para Juegos Un mensaje de sistema para generar implementaciones técnicas de física de juegos, incluyendo fórmulas, diagramas de estado y código.
Contenido del PromptGuardar
🌐
Implementación de mecánica de gancho de agarre con tensión elástica y fuerza centrífuga.
**1. Fórmulas matemáticas (LaTeX) para física:**
- Posición del jugador: `\vec{p}(t)`
- Punto de anclaje del gancho: `\vec{a}`
- Vector de cuerda: `\vec{r}(t) = \vec{p}(t) - \vec{a}`
- Longitud natural de la cuerda: `L_0`
- Constante elástica: `k`
- Longitud actual: `L(t) = |\vec{r}(t)|`
- Tensión elástica (fuerza restauradora): `\vec{F}_{tension} = -k \cdot (L(t) - L_0) \cdot \hat{r}(t)` donde `\hat{r}(t) = \frac{\vec{r}(t)}{L(t)}`
- Fuerza centrífuga (componente perpendicular): `\vec{F}_{cent} = m \cdot \frac{|\vec{v}_{tang}|^2}{L(t)} \cdot \hat{n}(t)` donde `\vec{v}_{tang} = \vec{v} - (\vec{v} \cdot \hat{r})\hat{r}` y `\hat{n}(t)` es el vector unitario perpendicular a `\hat{r}` en el plano de oscilación.
- Aceleración total: `\vec{a}(t) = \frac{\vec{F}_{tension} + \vec{F}_{cent} + \vec{F}_{gravity} + \vec{F}_{input}}{m}`
- Amortiguación: `\vec{F}_{damp} = -c \cdot \vec{v}_{tang}` (constante `c` para disipación de energía).
- Integración numérica (semi-implícita Euler): `\vec{v}(t+\Delta t) = \vec{v}(t) + \vec{a}(t) \cdot \Delta t`, luego `\vec{p}(t+\Delta t) = \vec{p}(t) + \vec{v}(t+\Delta t) \cdot \Delta t`.
- Corrección de restricción de longitud (proyección): Si `L(t+\Delta t) > L_{max}`, proyectar `\vec{p}` de vuelta a la esfera de radio `L_{max}` centrada en `\vec{a}`.
**2. Diagrama de transición de estados (Markdown):**
```mermaid
stateDiagram-v2
[*] --> Idle: No input
Idle --> Aiming: Press Fire1 (hold)
Aiming --> Grappling: Release Fire1 (raycast hit)
Aiming --> Idle: Release Fire1 (miss) / Cancel
Grappling --> Grappling: Rope attached (elastic force active)
Grappling --> Swinging: Player velocity tangential > threshold
Swinging --> Grappling: Tangential velocity < threshold (damping)
Grappling --> Released: Press Fire2 / Press Fire1 again
Swinging --> Released: Press Fire2 / Press Fire1 again
Released --> Idle: Rope detached, no collision
Released --> Grappling: New anchor (cooldown period, min 0.2s)
Grappling --> Idle: Anchor destroyed / Rope length > max (break)
Swinging --> Idle: Player hits ground (collision with floor)
```
**3. Código de producción (C# para Unity):**
```csharp
using UnityEngine;
public class GrappleHookController : MonoBehaviour
{
[Header("Rope Physics")]
[SerializeField] private float ropeNaturalLength = 5f;
[SerializeField] private float maxRopeLength = 20f;
[SerializeField] private float springConstant = 50f;
[SerializeField] private float dampingCoeff = 2f;
[SerializeField] private float gravityScale = 1f;
[Header("Input")]
[SerializeField] private KeyCode fireKey = KeyCode.Mouse0;
[SerializeField] private KeyCode releaseKey = KeyCode.Mouse1;
[SerializeField] private float inputCooldown = 0.2f;
[Header("Player")]
[SerializeField] private Rigidbody playerRigidbody;
[SerializeField] private float playerMass = 1f;
private Vector3 anchorPoint;
private bool isGrappling = false;
private float cooldownTimer = 0f;
private RaycastHit hitInfo;
private void Update()
{
cooldownTimer -= Time.deltaTime;
if (Input.GetKeyDown(fireKey) && cooldownTimer <= 0f)
{
TryFireGrapple();
}
if (Input.GetKeyDown(releaseKey) && isGrappling)
{
ReleaseGrapple();
}
}
private void FixedUpdate()
{
if (isGrappling)
{
ApplyRopePhysics();
}
}
private void TryFireGrapple()
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out hitInfo, maxRopeLength))
{
anchorPoint = hitInfo.point;
isGrappling = true;
cooldownTimer = inputCooldown;
}
}
private void ReleaseGrapple()
{
isGrappling = false;
cooldownTimer = inputCooldown;
}
private void ApplyRopePhysics()
{
Vector3 position = playerRigidbody.position;
Vector3 velocity = playerRigidbody.velocity;
Vector3 r = position - anchorPoint;
float currentLength = r.magnitude;
if (currentLength > maxRopeLength)
{
// Break rope
isGrappling = false;
return;
}
Vector3 rNormalized = r / currentLength;
Vector3 gravityForce = Physics.gravity * playerMass * gravityScale;
// Elastic tension
float stretch = currentLength - ropeNaturalLength;
Vector3 tensionForce = -springConstant * stretch * rNormalized;
// Clamp to avoid infinite stretch
tensionForce = Vector3.ClampMagnitude(tensionForce, 1000f);
// Tangential velocity (for centrifugal)
Vector3 tangentialVelocity = velocity - Vector3.Dot(velocity, rNormalized) * rNormalized;
float tangentialSpeed = tangentialVelocity.magnitude;
// Centrifugal force (outward from anchor, perpendicular to rope)
Vector3 centrifugalForce = playerMass * (tangentialSpeed * tangentialSpeed / currentLength) * rNormalized;
// Damping (linear and tangential)
Vector3 dampingForce = -dampingCoeff * tangentialVelocity;
// Input force (optional: player can add radial or tangential input)
Vector3 inputForce = Vector3.zero;
float verticalInput = Input.GetAxis("Vertical");
float horizontalInput = Input.GetAxis("Horizontal");
Vector3 cameraForward = Camera.main.transform.forward;
Vector3 cameraRight = Camera.main.transform.right;
Vector3 tangentialDir = Vector3.Cross(rNormalized, Vector3.up).normalized;
// Convert input to tangential plane
Vector3 inputVec = (cameraForward * verticalInput + cameraRight * horizontalInput);
float dotR = Vector3.Dot(inputVec, rNormalized);
Vector3 inputTangential = inputVec - dotR * rNormalized;
inputForce = inputTangential * 10f * playerMass;
// Net acceleration
Vector3 acceleration = (tensionForce + centrifugalForce + gravityForce + dampingForce + inputForce) / playerMass;
// Semi-implicit Euler integration
velocity += acceleration * Time.fixedDeltaTime;
position += velocity * Time.fixedDeltaTime;
// Position constraint (project back to rope length)
Vector3 newR = position - anchorPoint;
float newLength = newR.magnitude;
if (newLength > maxRopeLength)
{
position = anchorPoint + (newR / newLength) * maxRopeLength;
// Reflect velocity component along rope to avoid compression
Vector3 rNewNormal = (position - anchorPoint).normalized;
float radialVelocity = Vector3.Dot(velocity, rNewNormal);
if (radialVelocity < 0f)
{
velocity -= radialVelocity * rNewNormal;
}
}
playerRigidbody.position = position;
playerRigidbody.velocity = velocity;
}
private void OnDrawGizmos()
{
if (isGrappling)
{
Gizmos.color = Color.green;
Gizmos.DrawLine(playerRigidbody.position, anchorPoint);
}
}
}
```
Iniciá sesión para ver el prompt completo
Continuar con:
Al iniciar sesión, aceptás nuestros Términos de uso y Política de privacidad
Uso
Este prompt está diseñado para usarse con coding. Copiá el contenido de arriba y pegalo en tu herramienta de IA preferida.
Para mejores resultados, personalizá los marcadores (indicados con corchetes o mayúsculas) con tus requisitos específicos.
Discusión
0 comentarios