DetectorLogicGate.cs
5.01 KB
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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
/******************************************************************************
* Copyright (C) Leap Motion, Inc. 2011-2017. *
* Leap Motion proprietary and confidential. *
* *
* Use subject to the terms of the Leap Motion SDK Agreement available at *
* https://developer.leapmotion.com/sdk_agreement, or another agreement *
* between Leap Motion and you, your company or other organization. *
******************************************************************************/
using UnityEngine;
using UnityEngine.Events;
using System.Collections.Generic;
namespace Leap.Unity {
/**
* The DetectorLogicGate detector observes other detectors and activates when
* these other detectors match the specified logic.
*
* A DetectorLogicGate can be configured as an AND gate or an OR gate. You can also
* negate the output (creating a NAND or NOR gate).
*
* Since a DetectorLogicGate is a Detector, it can observe other DetectorLogicGate instances.
* However, before constructing complex logic chains, you should consider whether it is better
* to put such logic into a normal script.
*
* @since 4.1.2
*/
public class DetectorLogicGate : Detector {
[SerializeField]
[Tooltip("The list of observed detectors.")]
private List<Detector> Detectors;
/**
* When true, all Detector components of the same game object
* are added to the list of watched detectors on Awake. When false,
* you must manually add the desired detectors.
*
* If you have more than one DetectorLogicGate component on a game object,
* do not enable this option on both.
* @since 4.1.2
*/
[Tooltip("Add all detectors on this object automatically.")]
public bool AddAllSiblingDetectorsOnAwake = true;
/**
* The type of logic for this gate: AND or OR.
* @since 4.1.2
*/
[Tooltip("The type of logic used to combine detector state.")]
public LogicType GateType = LogicType.AndGate;
/**
* Whether to negate the output of the gate. AND becomes NAND; OR becomes NOR.
* @since 4.1.2
*/
[Tooltip("Whether to negate the gate output.")]
public bool Negate = false;
/**
* Adds the specified detector to the list of observed detectors.
*
* The same detector cannot be added more than once.
* @param Detector the detector to watch.
* @since 4.1.2
*/
public void AddDetector(Detector detector){
if(!Detectors.Contains(detector)){
Detectors.Add(detector);
activateDetector(detector);
}
}
/**
* Removes the specified detector from the list of observed detectors;
*
* @param Detector the detector to remove.
* @since 4.1.2
*/
public void RemoveDetector(Detector detector){
detector.OnActivate.RemoveListener(CheckDetectors);
detector.OnDeactivate.RemoveListener(CheckDetectors);
Detectors.Remove(detector);
}
/**
* Adds all the other detectors on the same GameObject to the list of observed detectors.
*
* Note: If you have more than one DetectorLogicGate instance on a game object, make sure that
* both objects don't observe each other.
* @since 4.1.2
*/
public void AddAllSiblingDetectors(){
Detector[] detectors = GetComponents<Detector>();
for(int g = 0; g < detectors.Length; g++){
if ( detectors[g] != this && detectors[g].enabled) {
AddDetector(detectors[g]);
}
}
}
private void Awake(){
for (int d = 0; d < Detectors.Count; d++) {
activateDetector(Detectors[d]);
}
if (AddAllSiblingDetectorsOnAwake) {
AddAllSiblingDetectors();
}
}
private void activateDetector(Detector detector){
detector.OnActivate.RemoveListener(CheckDetectors); //avoid double subscription
detector.OnDeactivate.RemoveListener(CheckDetectors);
detector.OnActivate.AddListener(CheckDetectors);
detector.OnDeactivate.AddListener(CheckDetectors);
}
private void OnEnable() {
CheckDetectors();
}
private void OnDisable () {
Deactivate();
}
/**
* Checks all the observed detectors, combines them with the specified type of logic
* and calls the Activate() or Deactivate() function as appropriate.
* @since 4.1.2
*/
protected void CheckDetectors(){
if (Detectors.Count < 1)
return;
bool state = Detectors[0].IsActive;
for(int a = 1; a < Detectors.Count; a++){
if(GateType == LogicType.AndGate){
state = state && Detectors[a].IsActive;
} else {
state = state || Detectors[a].IsActive;
}
}
if(Negate){
state = !state;
}
if(state){
Activate();
} else {
Deactivate();
}
}
}
/** The type of logic used to combine the watched detectors. */
public enum LogicType{ AndGate, OrGate }
}