Added complete lift interaction. Might need some debugging later.
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public enum ElevatorMoveState
|
||||
{
|
||||
NotMoving,
|
||||
Ascending,
|
||||
Decending
|
||||
}
|
||||
|
||||
public class ElevatorStatusPlate : MonoBehaviour
|
||||
{
|
||||
[System.Serializable]
|
||||
public struct FloorNumbers
|
||||
{
|
||||
public int floorNumber;
|
||||
public GameObject floorNumberSprite;
|
||||
}
|
||||
|
||||
public List<FloorNumbers> floorNumbers;
|
||||
|
||||
public GameObject upArrow;
|
||||
public GameObject downArrow;
|
||||
|
||||
private ElevatorMoveState moveState;
|
||||
|
||||
|
||||
// Start is called before the first frame update
|
||||
void Start()
|
||||
{
|
||||
SetMoveState(ElevatorMoveState.NotMoving);
|
||||
}
|
||||
|
||||
public void SetMoveState(ElevatorMoveState newState)
|
||||
{
|
||||
if (newState == ElevatorMoveState.NotMoving)
|
||||
{
|
||||
upArrow.SetActive(false);
|
||||
downArrow.SetActive(false);
|
||||
}
|
||||
else if (newState == ElevatorMoveState.Ascending)
|
||||
{
|
||||
upArrow.SetActive(true);
|
||||
downArrow.SetActive(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
upArrow.SetActive(false);
|
||||
downArrow.SetActive(true);
|
||||
}
|
||||
this.moveState = newState;
|
||||
|
||||
}
|
||||
|
||||
public void UpdateDisplayFloorNumber(int newValue)
|
||||
{
|
||||
foreach (var f in floorNumbers)
|
||||
{
|
||||
if (f.floorNumber != newValue)
|
||||
f.floorNumberSprite.SetActive(false);
|
||||
else
|
||||
f.floorNumberSprite.SetActive(true);
|
||||
}
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void Update()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b0a42248826403b4290be3c9eaf0cd8a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
381
Assets/_PROJECT/Components/Elevator/Scripts/Elevator box.cs
Normal file
381
Assets/_PROJECT/Components/Elevator/Scripts/Elevator box.cs
Normal file
@@ -0,0 +1,381 @@
|
||||
using _PROJECT.NewHandPresence;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Unity.XR.CoreUtils;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
public enum ElevatorState
|
||||
{
|
||||
Stationary,
|
||||
OpeningDoors,
|
||||
AwaitingPassengers,
|
||||
ClosingDoors,
|
||||
Moving
|
||||
}
|
||||
|
||||
|
||||
public class ElevatorBox : MonoBehaviour
|
||||
{
|
||||
public List<ElevatorOuter> callers = new List<ElevatorOuter>();
|
||||
|
||||
public GameObject leftDoor;
|
||||
public Transform leftDoorOpenPos;
|
||||
public Transform leftDoorClosedPos;
|
||||
|
||||
public GameObject rightDoor;
|
||||
public Transform rightDoorOpenPos;
|
||||
public Transform rightDoorClosedPos;
|
||||
|
||||
public float doorOpenTime = 4f;
|
||||
public float doorCloseTime = 5.6f;
|
||||
public float floorMoveTime = 5f;
|
||||
public float doorStayOpenTime = 2f;
|
||||
|
||||
[System.Serializable]
|
||||
public struct FloorData
|
||||
{
|
||||
public int floorNumber; // can be -1, 0, 1, 2 ...
|
||||
public Transform floorPoint; // reference to the transform in scene
|
||||
}
|
||||
|
||||
// Unity can display arrays/lists of this struct in Inspector
|
||||
public FloorData[] floors;
|
||||
|
||||
// Runtime dictionary for quick lookup
|
||||
private Dictionary<int, Transform> floorDict = new Dictionary<int, Transform>();
|
||||
[System.Serializable]
|
||||
public struct FloorNumbers
|
||||
{
|
||||
public int floorNumber;
|
||||
public GameObject floorNumberSprite;
|
||||
}
|
||||
|
||||
public List<FloorNumbers> floorDisplayNumbers;
|
||||
|
||||
public AudioSource audioSource;
|
||||
|
||||
public AudioClip[] openDoorsClips;
|
||||
public AudioClip[] closeDoorsClips;
|
||||
public AudioClip[] moveElevatorClips;
|
||||
|
||||
private int currentFloor = 2;
|
||||
private int targetFloor = 2;
|
||||
|
||||
private ElevatorState state = ElevatorState.Stationary;
|
||||
|
||||
void Awake()
|
||||
{
|
||||
|
||||
foreach (var f in floors)
|
||||
{
|
||||
if (!floorDict.ContainsKey(f.floorNumber))
|
||||
floorDict.Add(f.floorNumber, f.floorPoint);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
private void Start()
|
||||
{
|
||||
updateDisplayFloorNumber(currentFloor);
|
||||
|
||||
foreach (ElevatorOuter caller in callers)
|
||||
caller.statusPlate.UpdateDisplayFloorNumber(currentFloor);
|
||||
}
|
||||
|
||||
|
||||
public IEnumerator callElevator(int floor)
|
||||
{
|
||||
//Debug.Log("Calling Elevator");
|
||||
Debug.Log(state);
|
||||
if (state == ElevatorState.Stationary || state == ElevatorState.ClosingDoors)
|
||||
{
|
||||
Debug.Log(floor);
|
||||
|
||||
if (floor != currentFloor)
|
||||
{
|
||||
//Debug.Log("Started moving lift");
|
||||
yield return StartCoroutine(CloseDoors());
|
||||
targetFloor = floor;
|
||||
yield return StartCoroutine(MoveToFloor(targetFloor));
|
||||
}
|
||||
else
|
||||
|
||||
StartCoroutine(OpenDoors());
|
||||
|
||||
SetState(ElevatorState.AwaitingPassengers);
|
||||
}
|
||||
}
|
||||
|
||||
public void interestExpired()
|
||||
{
|
||||
if (state == ElevatorState.AwaitingPassengers)
|
||||
{
|
||||
if (IsElevatorEmpty())
|
||||
{
|
||||
StartCoroutine(CloseAndStationary());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool IsElevatorEmpty()
|
||||
{
|
||||
return this.GetComponentInChildren<XROrigin>() == null;
|
||||
}
|
||||
|
||||
private void SetState(ElevatorState newstate)
|
||||
{
|
||||
Debug.Log("Setting new state of " + newstate);
|
||||
this.state = newstate;
|
||||
}
|
||||
private void OnTriggerEnter(Collider other)
|
||||
{
|
||||
XROrigin enteredPlayerVR = other.GetComponent<XROrigin>();
|
||||
KbmController enteredPlayerKbm = other.GetComponent<KbmController>();
|
||||
|
||||
Debug.Log("Player Entered box");
|
||||
if (enteredPlayerVR != null)
|
||||
{
|
||||
addChild(enteredPlayerVR);
|
||||
}
|
||||
else if (enteredPlayerKbm != null)
|
||||
{
|
||||
enteredPlayerKbm.transform.SetParent(this.transform);
|
||||
}
|
||||
else
|
||||
return;
|
||||
|
||||
|
||||
switch (targetFloor)
|
||||
{
|
||||
case int f when f == floors[0].floorNumber:
|
||||
targetFloor = floors[1].floorNumber;
|
||||
break;
|
||||
|
||||
case int f when f == floors[1].floorNumber:
|
||||
targetFloor = floors[0].floorNumber;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
StartCoroutine(LiftTransferSequence());
|
||||
}
|
||||
|
||||
|
||||
private void OnTriggerExit(Collider other)
|
||||
{
|
||||
|
||||
// Was it a player, that exited?
|
||||
XROrigin exitedPlayerVR = other.GetComponent<XROrigin>();
|
||||
KbmController exitedPlayerKbm = other.GetComponent<KbmController>();
|
||||
if (exitedPlayerVR != null)
|
||||
{
|
||||
removeChild(exitedPlayerVR);
|
||||
}
|
||||
else if (exitedPlayerKbm != null)
|
||||
{
|
||||
exitedPlayerKbm.transform.SetParent(null);
|
||||
}
|
||||
else
|
||||
return;
|
||||
|
||||
Debug.Log("Player exited box, state is: " + this.state);
|
||||
|
||||
if (this.state == ElevatorState.AwaitingPassengers)
|
||||
{
|
||||
if (IsElevatorEmpty())
|
||||
{
|
||||
//Debug.Log("Elevator is empty");
|
||||
StartCoroutine(CloseAndStationary());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private ElevatorOuter findTargetCaller()
|
||||
{
|
||||
//Debug.Log("finding target caller");
|
||||
foreach (ElevatorOuter caller in this.callers)
|
||||
{
|
||||
//Debug.Log(caller.floor);
|
||||
//Debug.Log(targetFloor);
|
||||
if (caller.floor == targetFloor)
|
||||
{
|
||||
//Debug.Log("found caller");
|
||||
return caller;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
private ElevatorOuter findCurrentCaller()
|
||||
{
|
||||
//Debug.Log("finding target caller");
|
||||
foreach (ElevatorOuter caller in this.callers)
|
||||
{
|
||||
//Debug.Log(caller.floor);
|
||||
//Debug.Log(targetFloor);
|
||||
if (caller.floor == this.currentFloor)
|
||||
{
|
||||
//Debug.Log("found caller");
|
||||
return caller;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void SetCurrentFloor(int floor) {
|
||||
this.currentFloor = floor;
|
||||
|
||||
updateDisplayFloorNumber(floor);
|
||||
|
||||
foreach (ElevatorOuter caller in callers)
|
||||
caller.statusPlate.UpdateDisplayFloorNumber(floor);
|
||||
}
|
||||
|
||||
private void updateDisplayFloorNumber(int newValue)
|
||||
{
|
||||
foreach (var f in floorDisplayNumbers)
|
||||
{
|
||||
if (f.floorNumber != newValue)
|
||||
f.floorNumberSprite.SetActive(false);
|
||||
else
|
||||
f.floorNumberSprite.SetActive(true);
|
||||
}
|
||||
}
|
||||
public void addChild(XROrigin player)
|
||||
{
|
||||
player.transform.SetParent(this.transform);
|
||||
}
|
||||
public void removeChild(XROrigin player)
|
||||
{
|
||||
player.transform.SetParent(null);
|
||||
}
|
||||
|
||||
private void playRandomAudioClipFrom(AudioClip[] list)
|
||||
{
|
||||
if (list.Length == 0) return;
|
||||
|
||||
int index = Random.Range(0, list.Length);
|
||||
audioSource.clip = list[index];
|
||||
audioSource.Play();
|
||||
}
|
||||
|
||||
private IEnumerator LiftTransferSequence()
|
||||
{
|
||||
yield return StartCoroutine(CloseDoors());
|
||||
yield return StartCoroutine(MoveToFloor(targetFloor));
|
||||
}
|
||||
public IEnumerator MoveToFloor(int floorNumber)
|
||||
{
|
||||
Debug.Log("Moving to floor " + floorNumber);
|
||||
|
||||
if (floorDict.TryGetValue(floorNumber, out Transform target))
|
||||
{
|
||||
yield return StartCoroutine(MoveElevator(target.position));
|
||||
SetCurrentFloor(targetFloor);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning($"No floor defined for number {floorNumber}");
|
||||
}
|
||||
|
||||
yield return StartCoroutine(OpenDoors());
|
||||
}
|
||||
private IEnumerator CloseAndStationary()
|
||||
{
|
||||
Debug.Log("Close and set stationary");
|
||||
// Wait for CloseDoors() to finish
|
||||
yield return StartCoroutine(CloseDoors());
|
||||
|
||||
// After doors have closed, set state
|
||||
SetState(ElevatorState.Stationary);
|
||||
}
|
||||
|
||||
private IEnumerator CloseDoors()
|
||||
{
|
||||
//if (state == ElevatorState.AwaitingPassengers) {
|
||||
//Debug.Log("Closing doors");
|
||||
|
||||
if (Vector3.Distance(leftDoor.transform.position, leftDoorClosedPos.position) < 0.01f)
|
||||
yield break;
|
||||
|
||||
SetState(ElevatorState.ClosingDoors);
|
||||
playRandomAudioClipFrom(closeDoorsClips);
|
||||
|
||||
ElevatorOuter currentCaller = findCurrentCaller();
|
||||
|
||||
if (currentCaller != null) currentCaller.CloseDoors();
|
||||
|
||||
yield return StartCoroutine(MoveDoors(leftDoor, leftDoorClosedPos, rightDoor, rightDoorClosedPos, doorCloseTime));
|
||||
//}
|
||||
|
||||
}
|
||||
|
||||
private IEnumerator OpenDoors()
|
||||
{
|
||||
if (state != ElevatorState.AwaitingPassengers) {
|
||||
//Debug.Log("Opening doors");
|
||||
SetState(ElevatorState.OpeningDoors);
|
||||
playRandomAudioClipFrom(openDoorsClips);
|
||||
ElevatorOuter targetCaller = findTargetCaller();
|
||||
//Debug.Log("Target caller is: " + targetCaller);
|
||||
if (targetCaller != null)
|
||||
targetCaller.OpenDoors();
|
||||
|
||||
yield return StartCoroutine(MoveDoors(leftDoor, leftDoorOpenPos, rightDoor, rightDoorOpenPos, doorOpenTime));
|
||||
|
||||
|
||||
SetState(ElevatorState.AwaitingPassengers);
|
||||
yield return new WaitForSeconds(doorStayOpenTime); // wait for passengers
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerator MoveDoors(GameObject left, Transform targetLeft, GameObject right, Transform targetRight, float moveTime)
|
||||
{
|
||||
Debug.Log("Moving doors");
|
||||
Vector3 startL = left.transform.position;
|
||||
Vector3 startR = right.transform.position;
|
||||
float t = 0;
|
||||
|
||||
while (t < 1f)
|
||||
{
|
||||
t += Time.deltaTime / moveTime;
|
||||
float easedT = Mathf.SmoothStep(0f, 1f, t); // ease in/out
|
||||
left.transform.position = Vector3.Lerp(startL, targetLeft.position, easedT);
|
||||
right.transform.position = Vector3.Lerp(startR, targetRight.position, easedT);
|
||||
yield return null;
|
||||
}
|
||||
//Debug.Log("Inner Doors moved");
|
||||
}
|
||||
|
||||
|
||||
|
||||
private IEnumerator MoveElevator(Vector3 targetPos)
|
||||
{
|
||||
if (targetFloor > currentFloor)
|
||||
foreach (ElevatorOuter caller in callers)
|
||||
caller.statusPlate.SetMoveState(ElevatorMoveState.Ascending);
|
||||
|
||||
else
|
||||
foreach (ElevatorOuter caller in callers)
|
||||
caller.statusPlate.SetMoveState(ElevatorMoveState.Decending);
|
||||
|
||||
Vector3 startPos = transform.position;
|
||||
float t = 0;
|
||||
|
||||
SetState(ElevatorState.Moving);
|
||||
playRandomAudioClipFrom(moveElevatorClips);
|
||||
|
||||
while (t < 1f)
|
||||
{
|
||||
t += Time.deltaTime / floorMoveTime;
|
||||
float easedT = Mathf.SmoothStep(0f, 1f, t); // ease in/out
|
||||
transform.position = Vector3.Lerp(startPos, targetPos, easedT);
|
||||
yield return null;
|
||||
}
|
||||
|
||||
foreach (ElevatorOuter caller in callers)
|
||||
caller.statusPlate.SetMoveState(ElevatorMoveState.NotMoving);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 73ccfdd4c926d054ba4f2e96fcb15082
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,80 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Unity.XR.CoreUtils;
|
||||
using UnityEngine;
|
||||
|
||||
public class ElevatorOuter : MonoBehaviour
|
||||
{
|
||||
public ElevatorBox box;
|
||||
|
||||
public int floor;
|
||||
public Transform boxPos;
|
||||
|
||||
public GameObject leftDoor;
|
||||
public Transform leftDoorOpenPos;
|
||||
public Transform leftDoorClosedPos;
|
||||
|
||||
public GameObject rightDoor;
|
||||
public Transform rightDoorOpenPos;
|
||||
public Transform rightDoorClosedPos;
|
||||
|
||||
private float doorOpenTime = 4f;
|
||||
private float doorCloseTime = 5.6f;
|
||||
|
||||
public ElevatorStatusPlate statusPlate;
|
||||
public AudioSource arrivalBeeper;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
doorOpenTime = box.doorOpenTime;
|
||||
doorCloseTime = box.doorCloseTime;
|
||||
}
|
||||
private void OnTriggerEnter(Collider other)
|
||||
{
|
||||
Debug.Log("Something entered call area");
|
||||
if (other.GetComponent<XROrigin>() == null && other.GetComponent<KbmController>() == null) return;
|
||||
StartCoroutine(box.callElevator(floor));
|
||||
Debug.Log("Player entered call area");
|
||||
}
|
||||
|
||||
private void OnTriggerExit(Collider other)
|
||||
{
|
||||
Debug.Log("Something entered call area");
|
||||
if (other.GetComponent<XROrigin>() == null && other.GetComponent<KbmController>() == null) return;
|
||||
box.interestExpired();
|
||||
Debug.Log("Player exited call area");
|
||||
}
|
||||
public void CloseDoors()
|
||||
{
|
||||
StartCoroutine(MoveDoors(leftDoor, leftDoorClosedPos, rightDoor, rightDoorClosedPos, doorCloseTime));
|
||||
|
||||
|
||||
}
|
||||
public void OpenDoors()
|
||||
{
|
||||
arrivalBeeper.Play();
|
||||
Debug.Log("Outer Doors opened");
|
||||
StartCoroutine(MoveDoors(leftDoor, leftDoorOpenPos, rightDoor, rightDoorOpenPos, doorOpenTime));
|
||||
|
||||
}
|
||||
|
||||
private IEnumerator MoveDoors(GameObject left, Transform targetLeft, GameObject right, Transform targetRight, float moveTime)
|
||||
{
|
||||
Vector3 startL = left.transform.position;
|
||||
Vector3 startR = right.transform.position;
|
||||
float t = 0;
|
||||
|
||||
while (t < 1f)
|
||||
{
|
||||
t += Time.deltaTime / moveTime;
|
||||
float easedT = Mathf.SmoothStep(0f, 1f, t); // ease in/out
|
||||
left.transform.position = Vector3.Lerp(startL, targetLeft.position, easedT);
|
||||
right.transform.position = Vector3.Lerp(startR, targetRight.position, easedT);
|
||||
yield return null;
|
||||
}
|
||||
Debug.Log("Outer Doors moved");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5ef47691d9311604abf356d87aa8e028
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user