Files
DeltaVR/Assets/_PROJECT/Components/Elevator/Scripts/Springy Button.cs

177 lines
5.3 KiB
C#

using UnityEngine;
[RequireComponent(typeof(Rigidbody))]
public class ElevatorSpringyButton : MonoBehaviour {
public Transform buttonDirectionRoot;
public ElevatorOuter ElevatorOuter;
public ElevatorBox box;
[Header("Movement limits")]
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("Visuals")]
public Renderer[] targetRenderers;
public Material defaultMaterial;
public Material pressedMaterial;
[Header("Spring Settings")]
public float springForce = 300f; // how strong it returns
public float damping = 8f; // prevents vibration
[Header("Button Type Settings")]
public bool isFloorButton;
public bool isInsideButton;
public bool isCloseDoorsButton;
public int designatedFloor;
private Rigidbody rb;
private Vector3 restLocalPos;
public bool disabled;
private bool isAwaitingResponse = false;
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);
//Keeping the buttons firing until their needs have been met
if (!isAwaitingResponse || disabled) return;
if (!isInsideButton && box != null)
{
if (box.currentFloor == designatedFloor) StartCoroutine(DeactivateAfterDelay(0.5f));
else Pressed();
return;
}
if (isInsideButton && box != null)
{
if (isFloorButton)
{
if (designatedFloor == box.currentFloor) StartCoroutine(DeactivateAfterDelay(0.5f));
else Pressed();
return;
}
if (isCloseDoorsButton)
{
if (box.state == ElevatorState.ClosingDoors|| box.state == ElevatorState.Moving) StartCoroutine(DeactivateAfterDelay(0.5f));
else Pressed();
return;
}
else
{
if (box.state == ElevatorState.OpeningDoors || box.state == ElevatorState.Moving) StartCoroutine(DeactivateAfterDelay(0.5f));
else Pressed();
return;
}
}
}
public void Pressed()
{
isAwaitingResponse = true;
foreach (Renderer renderer in targetRenderers)
{
renderer.material = pressedMaterial;
}
//Debug.Log("Button is pressed");
if (ElevatorOuter != null && !isInsideButton) ElevatorOuter.CallElevator();
if (disabled)
{
StartCoroutine(DeactivateAfterDelay(0.5f));
return;
}
if (box != null && isInsideButton)
{
if (isFloorButton)
{
box.targetFloor = designatedFloor;
if (box.targetFloor != box.currentFloor) {
Debug.Log("Lift transfer sequence");
StartCoroutine(box.LiftTransferSequence());
}
else StartCoroutine(box.OpenDoors());
return;
}
if (isCloseDoorsButton)
{
//Debug.Log("Closing Doors");
StartCoroutine(box.CloseDoors());
return;
}
else
{
StartCoroutine(box.OpenDoors());
//Debug.Log("Opening Doors");
return;
}
}
}
public void Deactivate()
{
Debug.Log("Deactivating");
//if (isAwaitingResponse) return;
isAwaitingResponse = false;
foreach (Renderer renderer in targetRenderers)
{
renderer.material = defaultMaterial;
}
}
private System.Collections.IEnumerator DeactivateAfterDelay(float delay)
{
yield return new WaitForSeconds(delay);
//isAwaitingResponse = false;
Deactivate();
}
}