123 lines
3.7 KiB
C#
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);
|
|
}
|
|
}
|
|
|