Part I: Week 12: Temple Of Fortune (Part I)
Part II: Week 13: Temple Of Fortune (Part II)
Partners: Queenie Hsiao and Michelle Xu
We relocated to a dimly-lit room to ensure accurate projection mapping on the cabinets using TouchDesigner. Last week, we confirmed that TouchDesigner successfully received the correct cabinet value from Unity. This week, we learned to utilize the OSC library to activate the corresponding components with the TouchDesigner interface and basic Python scripting.
The video below demonstrates the complete user interaction flow — starting from the activation of seat pressure sensors, followed by the user selecting and placing their chosen offering on the RFID reader, and concluding with the projector illuminating the cabinet containing the user’s fortune.
We discovered a specific edge case where, if the system selects the same cabinet value as the previous interaction, the onValueChange()
function in TouchDesigner would fail to trigger because the stored value doesn't change. This is due to TouchDesigner’s behavior of only responding to actual value changes.
To resolve this, I refactored the code to include a step where, during the reset process, a null value (e.g., -1
) is sent to TouchDesigner — osc.SendInteger(-1);
. This effectively clears the previously stored value. Consequently, when the next cabinet value is sent—even if it matches the previous value—the onValueChange()
function still triggers, ensuring consistent behavior for all interactions.
##
# TouchDesigner Script that receives the cabinet value (index) and switches the alpha value of that cabinet to 1, hence turning the light "on".
##
# constant12 will always be empty/ 0
# This is the only cabinet that is not associated with any offering/ fortune
constantsArr = ['constant1','constant2','constant3','constant4','constant5','constant6','constant7','constant8','constant9','constant10','constant11','constant12','constant13','constant14','constant15','constant16']
def onValueChange(channel, sampleIndex, val, prev):
index = int(op('oscin1')['switch/toggle'])
timer = op('timer2')
if index == -1:
pass
else:
for constant in constantsArr:
constantNum = int(constant[8:len(constant)])
op(constant).par.alpha.val = 0
if constantNum == index:
op(constant).par.alpha.val = 1
timer.par.start.pulse()
break
With the necessary components successfully communicating, we shifted our focus to evaluating the feasibility and overall quality of the user experience from the perspective of a potential user. What does this mean?
I chose to delay sending the cabinet value to TouchDesigner, thus postponing the light trigger. This was the simplest approach with minimal code.