63 lines
2.0 KiB
C#
63 lines
2.0 KiB
C#
using UnityEngine;
|
|
|
|
[RequireComponent(typeof(Rigidbody))]
|
|
public class SpringyButtonPhysics : MonoBehaviour {
|
|
public Transform buttonDirectionRoot;
|
|
|
|
public float minX = 0f;
|
|
public float maxX = 0f;
|
|
public float minY = 0f;
|
|
public float maxY = 0f;
|
|
public float minZ = 0.005f;
|
|
public float maxZ = 0f;
|
|
|
|
|
|
[Header("Spring Settings")]
|
|
public float springForce = 300f; // how strong it returns
|
|
public float damping = 8f; // prevents vibration
|
|
|
|
private Rigidbody rb;
|
|
private Vector3 restLocalPos;
|
|
|
|
void Start()
|
|
{
|
|
rb = GetComponent<Rigidbody>();
|
|
rb.useGravity = false;
|
|
|
|
// initial local rest position
|
|
restLocalPos = buttonDirectionRoot.InverseTransformPoint(transform.position);
|
|
}
|
|
|
|
void FixedUpdate()
|
|
{
|
|
// 1. Local pos
|
|
Vector3 localPos = buttonDirectionRoot.InverseTransformPoint(transform.position);
|
|
|
|
// 2. Spring in LOCAL space
|
|
Vector3 spring = (restLocalPos - localPos) * springForce;
|
|
|
|
// 3. Damping also must be in LOCAL space!!
|
|
Vector3 localVelocity = buttonDirectionRoot.InverseTransformDirection(rb.velocity);
|
|
localVelocity *= damping;
|
|
spring -= localVelocity;
|
|
|
|
// 4. Convert spring to WORLD space
|
|
Vector3 worldSpring = buttonDirectionRoot.TransformDirection(spring);
|
|
|
|
// 5. Apply
|
|
rb.AddForce(worldSpring, ForceMode.Acceleration);
|
|
|
|
// --- 3. Compute new local pos after physics ---
|
|
Vector3 newLocalPos = buttonDirectionRoot.InverseTransformPoint(transform.position);
|
|
//Debug.Log(spring);
|
|
// --- 4. Clamp to allowed ranges ---
|
|
newLocalPos.x = Mathf.Clamp(newLocalPos.x, minX, maxX);
|
|
newLocalPos.y = Mathf.Clamp(newLocalPos.y, minY, maxY);
|
|
newLocalPos.z = Mathf.Clamp(newLocalPos.z, minZ, maxZ);
|
|
|
|
// --- 5. Convert back to world and move via Rigidbody ---
|
|
Vector3 worldPos = buttonDirectionRoot.TransformPoint(newLocalPos);
|
|
rb.MovePosition(worldPos);
|
|
}
|
|
}
|