Files
Click-PointRPG/Assets/Scripts/PushableObject.cs

123 lines
3.7 KiB
C#

using UnityEngine;
/// <summary>
/// Script for objects that can be pushed over when interacted with (right-click).
/// Applies torque to tip the object and falls under physics gravity.
/// Integrates with the interaction system.
/// </summary>
public class PushableObject : InteractiveObjectBase
{
[Header("Push Settings")]
[SerializeField]
[Tooltip("Force applied to push the object over.")]
private float pushForce = 10f;
[SerializeField]
[Tooltip("Rotation angle (in degrees) the object tips to when pushed.")]
private Vector3 tipRotation = new Vector3(90f, 0f, 0f);
[SerializeField]
[Tooltip("Speed at which the object rotates to the tip angle.")]
private float tipSpeed = 5f;
[Header("Physics")]
[SerializeField]
[Tooltip("Whether to use gravity for falling.")]
private bool useGravity = true;
[SerializeField]
[Tooltip("Mass of the object (affects how it falls).")]
private float mass = 1f;
private Rigidbody rb;
private bool hasTipped = false;
private Vector3 originalRotation;
private Quaternion targetRotation;
private void Awake()
{
rb = GetComponent<Rigidbody>();
if (rb == null)
{
rb = gameObject.AddComponent<Rigidbody>();
Log("No Rigidbody found. Added one automatically.");
}
// Configure physics
rb.useGravity = useGravity;
rb.mass = mass;
rb.constraints = RigidbodyConstraints.FreezeRotation; // Start frozen until pushed
originalRotation = transform.eulerAngles;
objectDisplayName = "Pushable Object";
Log($"Initialized on layer '{LayerMask.LayerToName(gameObject.layer)}'. Make sure this layer is in ClickToMoveInputSystem's selectionLayers!");
}
public override bool CanInteract()
{
return !hasTipped;
}
public override void Interact(GameObject player)
{
Log("Interact method called");
Push();
}
public void Push()
{
Log("Push method called");
if (hasTipped)
{
Log("Object already tipped, cannot push again.");
return;
}
hasTipped = true;
Log("Object pushed! Tipping over...");
// Unfreeze rotation to allow physics
rb.constraints = RigidbodyConstraints.FreezePosition;
// Apply upward impulse to simulate loss of balance
rb.linearVelocity = Vector3.up * (pushForce * 0.5f);
// Calculate target rotation
targetRotation = Quaternion.Euler(originalRotation + tipRotation);
// Use AnimationUtilities to rotate toward tip angle
float duration = 1f / tipSpeed;
AnimationUtilities.RotateTo(this, transform, targetRotation, duration);
rb.constraints = RigidbodyConstraints.FreezeAll; // Freeze all rotation after tipping to prevent wobbling
TryGetComponent<QuestTrigger>(out var questTrigger);
Debug.Log($"QuestTrigger found: {questTrigger != null}");
if (questTrigger != null)
{
questTrigger.TryTrigger(gameObject);
Log("Triggered quest event on push!");
}
}
/// <summary>
/// Reset the object to its original state
/// </summary>
public void Reset()
{
hasTipped = false;
rb.linearVelocity = Vector3.zero;
rb.angularVelocity = Vector3.zero;
rb.constraints = RigidbodyConstraints.FreezeRotation;
transform.eulerAngles = originalRotation;
Log("Object reset to original position.");
}
private void OnDrawGizmosSelected()
{
// Draw push direction indicator
Gizmos.color = Color.green;
Gizmos.DrawRay(transform.position, Vector3.up * 2f);
}
}