-
Notifications
You must be signed in to change notification settings - Fork 38
/
Copy pathSafeStateMachine.cs
125 lines (110 loc) · 4.36 KB
/
SafeStateMachine.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
// Copyright (c) Meta Platforms, Inc. and affiliates.
using CrypticCabinet.Utils;
using Fusion;
using Oculus.Interaction;
using UnityEngine;
using UnityEngine.Events;
namespace CrypticCabinet.Puzzles.Safe
{
/// <summary>
/// Represents the state machine for the safe puzzle.
/// </summary>
[RequireComponent(typeof(Animator))]
public class SafeStateMachine : NetworkBehaviour, IStateAuthorityChanged
{
[SerializeField] private NetworkMecanimAnimator m_mecanimAnimator;
[Header("Events")]
[Space(10)]
[Tooltip("Fired when the safe door opened")]
[SerializeField] private UnityEvent m_onDoorOpened;
[Tooltip("Fired when the safe drawer opened")]
[SerializeField] private UnityEvent m_onDrawerOpened;
[Tooltip("Fired when the safe drawer closed")]
[SerializeField] private UnityEvent m_onDrawerClosed;
private static readonly int s_openDoor = Animator.StringToHash("OpenDoor");
private static readonly int s_openDrawer = Animator.StringToHash("OpenDrawer");
private static readonly int s_closeDrawer = Animator.StringToHash("CloseDrawer");
private readonly PendingTasksHandler m_pendingTasksHandler = new();
private void Start()
{
if (m_mecanimAnimator == null)
{
m_mecanimAnimator = GetComponent<NetworkMecanimAnimator>();
}
this.AssertField(m_mecanimAnimator, nameof(m_mecanimAnimator));
if (m_mecanimAnimator.Animator == null)
{
m_mecanimAnimator.Animator = GetComponent<Animator>();
}
this.AssertField(m_mecanimAnimator.Animator, nameof(m_mecanimAnimator.Animator));
if (m_mecanimAnimator == null)
{
Debug.LogError("Mecanim animator not set!");
}
else
{
if (m_mecanimAnimator.Animator == null)
{
Debug.LogError("Mecanim animator has no animator set!");
}
}
}
/// <summary>
/// Opens the safe door, once this user is the state authority.
/// </summary>
[ContextMenu("Open Door")]
public void OpenDoor()
{
m_pendingTasksHandler.TryExecuteAction(RPC_OpenDoor, m_mecanimAnimator.Object.HasStateAuthority);
}
/// <summary>
/// Opens the safe drawer, once this user is the state authority.
/// </summary>
[ContextMenu("Open Drawer")]
public void OpenDrawer()
{
m_pendingTasksHandler.TryExecuteAction(RPC_OpenDrawer, m_mecanimAnimator.Object.HasStateAuthority);
}
/// <summary>
/// Closes the safe drawer, once this user is the state authority.
/// </summary>
[ContextMenu("Close Drawer")]
public void CloseDrawer()
{
m_pendingTasksHandler.TryExecuteAction(RPC_CloseDrawer, m_mecanimAnimator.Object.HasStateAuthority);
}
/// <summary>
/// Opens the door for all connected players via RPC, if the state machine allows that.
/// </summary>
[Rpc(RpcSources.All, RpcTargets.All)]
private void RPC_OpenDoor()
{
m_mecanimAnimator.Animator.SetBool(s_openDoor, true);
m_onDoorOpened?.Invoke();
}
/// <summary>
/// Opens the drawer for all connected players via RPC, if the state machine allows that.
/// </summary>
[Rpc(RpcSources.All, RpcTargets.All)]
private void RPC_OpenDrawer()
{
m_mecanimAnimator.Animator.SetBool(s_openDrawer, true);
m_mecanimAnimator.Animator.SetBool(s_closeDrawer, false);
m_onDrawerOpened?.Invoke();
}
/// <summary>
/// Closes the drawer for all connected players via RPC, if the state machine allows that.
/// </summary>
[Rpc(RpcSources.All, RpcTargets.All)]
private void RPC_CloseDrawer()
{
m_mecanimAnimator.Animator.SetBool(s_openDrawer, false);
m_mecanimAnimator.Animator.SetBool(s_closeDrawer, true);
m_onDrawerClosed?.Invoke();
}
public void StateAuthorityChanged()
{
m_pendingTasksHandler.ExecuteAllOrClear(m_mecanimAnimator.Object.HasStateAuthority);
}
}
}