1
0
forked from cgvr/DeltaVR

on shape scanner completion, door is unlocked, shape scanner initializes empty config, quest marker moves to npc

This commit is contained in:
2026-03-01 13:15:51 +02:00
parent 95e67b9870
commit 5e6bb24c27
9 changed files with 101 additions and 30 deletions

View File

@@ -9,10 +9,13 @@
* igal pool, kus mängija peab rääkima, peaks olema: * igal pool, kus mängija peab rääkima, peaks olema:
* helilained räägitava heli amplituudi põhjal * helilained räägitava heli amplituudi põhjal
* "loading" dünaamiline ikoon kui mängija ootab protsessimise järel * "loading" dünaamiline ikoon kui mängija ootab protsessimise järel
* npc character:
* klaas on näha temast eespool
* voicelines: list listidest, mille hulgast saab valida
* shape detection: * shape detection:
* raadio nupp võiks töötada recording mode'is, mitte streamina - kui lased lahti, siis hakkab processima * raadio nupp võiks töötada recording mode'is, mitte streamina - kui lased lahti, siis hakkab processima
* professor võiks öelda "good job, continue..." pärast esimest successi * professor võiks öelda "good job, continue..." pärast esimest successi
* kui kõik configurationid tehtud, siis midagi juhtub: uks avaneb, quest marker läheb ukse juurde, professor ütleb "thank you" * kui kõik configurationid tehtud, siis professor ütleb "thank you"
* peab mängijale kuidagi selgitama, kuidas scale'ida prinditud objekte * peab mängijale kuidagi selgitama, kuidas scale'ida prinditud objekte
* prinditud objekti scale'imisele min ja max size limiit * prinditud objekti scale'imisele min ja max size limiit
* archery range: * archery range:
@@ -24,9 +27,6 @@
* cafe: * cafe:
* npc võiks olla keeratud sinu poole juba kaugelt * npc võiks olla keeratud sinu poole juba kaugelt
* toit võiks tulla kandiku peal/sees * toit võiks tulla kandiku peal/sees
* npc character:
* klaas on näha temast eespool
* voicelines: list listidest, mille hulgast saab valida
Can't/Won't Do: Can't/Won't Do:
* glTF loading: vahetada ära shader Universal render pipeline Lit, mitte panna buildi kaasa glTf oma - **ei saa, objekt on siis ilma tekstuurita, lihtsalt hall** * glTF loading: vahetada ära shader Universal render pipeline Lit, mitte panna buildi kaasa glTf oma - **ei saa, objekt on siis ilma tekstuurita, lihtsalt hall**

View File

@@ -7,13 +7,14 @@ Material:
m_CorrespondingSourceObject: {fileID: 0} m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0} m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0} m_PrefabAsset: {fileID: 0}
m_Name: Green m_Name: EmissiveGreen
m_Shader: {fileID: 4800000, guid: 933532a4fcc9baf4fa0491de14d08ed7, type: 3} m_Shader: {fileID: 4800000, guid: 933532a4fcc9baf4fa0491de14d08ed7, type: 3}
m_Parent: {fileID: 0} m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0 m_ModifiedSerializedProperties: 0
m_ValidKeywords: [] m_ValidKeywords:
- _EMISSION
m_InvalidKeywords: [] m_InvalidKeywords: []
m_LightmapFlags: 4 m_LightmapFlags: 1
m_EnableInstancingVariants: 0 m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0 m_DoubleSidedGI: 0
m_CustomRenderQueue: -1 m_CustomRenderQueue: -1
@@ -115,7 +116,7 @@ Material:
m_Colors: m_Colors:
- _BaseColor: {r: 0, g: 1, b: 0.0381248, a: 1} - _BaseColor: {r: 0, g: 1, b: 0.0381248, a: 1}
- _Color: {r: 0, g: 1, b: 0.0381248, a: 1} - _Color: {r: 0, g: 1, b: 0.0381248, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1} - _EmissionColor: {r: 0.14076614, g: 1, b: 0, a: 1}
- _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1} - _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1}
m_BuildTextureStacks: [] m_BuildTextureStacks: []
--- !u!114 &6221994712197478572 --- !u!114 &6221994712197478572

View File

@@ -20,15 +20,16 @@ Material:
m_CorrespondingSourceObject: {fileID: 0} m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0} m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0} m_PrefabAsset: {fileID: 0}
m_Name: Loading m_Name: EmissiveRed
m_Shader: {fileID: 4800000, guid: 933532a4fcc9baf4fa0491de14d08ed7, type: 3} m_Shader: {fileID: 4800000, guid: 933532a4fcc9baf4fa0491de14d08ed7, type: 3}
m_Parent: {fileID: 0} m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0 m_ModifiedSerializedProperties: 0
m_ValidKeywords: m_ValidKeywords:
- _EMISSION
- _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A - _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
- _SPECULAR_SETUP - _SPECULAR_SETUP
m_InvalidKeywords: [] m_InvalidKeywords: []
m_LightmapFlags: 4 m_LightmapFlags: 1
m_EnableInstancingVariants: 0 m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0 m_DoubleSidedGI: 0
m_CustomRenderQueue: 2000 m_CustomRenderQueue: 2000
@@ -130,6 +131,6 @@ Material:
m_Colors: m_Colors:
- _BaseColor: {r: 0, g: 0, b: 0, a: 1} - _BaseColor: {r: 0, g: 0, b: 0, a: 1}
- _Color: {r: 0, g: 0, b: 0, a: 1} - _Color: {r: 0, g: 0, b: 0, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1} - _EmissionColor: {r: 1, g: 0, b: 0, a: 1}
- _SpecColor: {r: 0, g: 0, b: 0, a: 1} - _SpecColor: {r: 0, g: 0, b: 0, a: 1}
m_BuildTextureStacks: [] m_BuildTextureStacks: []

View File

@@ -22,11 +22,11 @@ Material:
m_PrefabAsset: {fileID: 0} m_PrefabAsset: {fileID: 0}
m_Name: card reader Variant m_Name: card reader Variant
m_Shader: {fileID: 4800000, guid: 933532a4fcc9baf4fa0491de14d08ed7, type: 3} m_Shader: {fileID: 4800000, guid: 933532a4fcc9baf4fa0491de14d08ed7, type: 3}
m_Parent: {fileID: -3846018093981099296, guid: 248e38dcb931fa345a11dbf79e87036f, m_Parent: {fileID: 2100000, guid: a3ce1b39b1e52c94398a08157fda1dff, type: 2}
type: 3}
m_ModifiedSerializedProperties: 2 m_ModifiedSerializedProperties: 2
m_ValidKeywords: m_ValidKeywords:
- _EMISSION - _EMISSION
- _SPECULAR_SETUP
m_InvalidKeywords: [] m_InvalidKeywords: []
m_LightmapFlags: 1 m_LightmapFlags: 1
m_EnableInstancingVariants: 0 m_EnableInstancingVariants: 0
@@ -42,6 +42,6 @@ Material:
m_Ints: [] m_Ints: []
m_Floats: [] m_Floats: []
m_Colors: m_Colors:
- _Color: {r: 0.11653974, g: 0.90640265, b: 0, a: 1} - _Color: {r: 1, g: 0, b: 0.13618705, a: 1}
- _EmissionColor: {r: 0, g: 0.9622642, b: 0.019420544, a: 0} - _EmissionColor: {r: 0.09420719, g: 0.9607843, b: 0, a: 0}
m_BuildTextureStacks: [] m_BuildTextureStacks: []

View File

@@ -8,10 +8,10 @@ public class ShapeDetectionNPC : NPCController
public QuestMarker questMarker; public QuestMarker questMarker;
public RadioTransmitter radio; public RadioTransmitter radio;
public Transform computerKeyboardKey; public Transform computerKeyboardKey;
public ComputerPrinter computerPrinter;
public Printer3DInputHole printerInsertionHole; public Printer3DInputHole printerInsertionHole;
public Texture2D GeneratedTexture { get; private set; } public ComputerPrinter computerPrinter;
public ShapeScanner shapeScanner; public ShapeScanner shapeScanner;
public Transform questMarkerPoint;
public float radioAmount = 1f; public float radioAmount = 1f;
@@ -35,8 +35,9 @@ public class ShapeDetectionNPC : NPCController
{ {
radio.OnPlayerPickUp += OnPlayerPickedUpRadio; radio.OnPlayerPickUp += OnPlayerPickedUpRadio;
radio.OnPlayerFinishedSpeaking += OnPlayerSpokeIntoRadio; radio.OnPlayerFinishedSpeaking += OnPlayerSpokeIntoRadio;
computerPrinter.OnImagePrinted += OnPlayerPrintedImage;
printerInsertionHole.OnPlayerInsertedPrintable += OnPlayerInitiatedPrinting; printerInsertionHole.OnPlayerInsertedPrintable += OnPlayerInitiatedPrinting;
computerPrinter.OnImagePrinted += OnPlayerPrintedImage;
shapeScanner.OnShapeScannerCompleted += OnShapeScannerCompleted;
} }
protected async override void OnPlayerApproach() protected async override void OnPlayerApproach()
@@ -123,4 +124,9 @@ public class ShapeDetectionNPC : NPCController
questMarker.MoveTo(shapeScanner.transform, true); questMarker.MoveTo(shapeScanner.transform, true);
} }
} }
private void OnShapeScannerCompleted()
{
questMarker.MoveTo(questMarkerPoint);
}
} }

View File

@@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Data;
using System.Linq; using System.Linq;
using TMPro; using TMPro;
using UnityEngine; using UnityEngine;
@@ -10,6 +11,11 @@ using UnityEngine.XR.Interaction.Toolkit;
public class BoolRow public class BoolRow
{ {
public List<bool> cells = new(); public List<bool> cells = new();
public BoolRow(List<bool> cells)
{
this.cells = cells;
}
} }
[Serializable] [Serializable]
@@ -18,11 +24,21 @@ public class ShapeScannerConfiguration
public int columns = 6; public int columns = 6;
public float requiredCorrectPercentage = 80.0f; public float requiredCorrectPercentage = 80.0f;
public List<BoolRow> rows = new(); public List<BoolRow> rows = new();
public ShapeScannerConfiguration(int columns, float requiredCorrectPercentage, List<BoolRow> rows)
{
this.columns = columns;
this.requiredCorrectPercentage = requiredCorrectPercentage;
this.rows = rows;
}
} }
public class ShapeScanner : MonoBehaviour public class ShapeScanner : MonoBehaviour
{ {
public delegate void OnShapeScannerCompletedDelegate();
public event OnShapeScannerCompletedDelegate OnShapeScannerCompleted;
[Header("Static References")]
public List<ShapeScannerConfiguration> configurations = new List<ShapeScannerConfiguration>(); public List<ShapeScannerConfiguration> configurations = new List<ShapeScannerConfiguration>();
public ShapeScannerRay rayPrefab; public ShapeScannerRay rayPrefab;
public Transform raySpawnCorner1; public Transform raySpawnCorner1;
@@ -32,17 +48,28 @@ public class ShapeScanner : MonoBehaviour
public TextMeshProUGUI correctPercentageDisplay; public TextMeshProUGUI correctPercentageDisplay;
public XRInteractionManager interactionManager; public XRInteractionManager interactionManager;
[Header("Materials")]
public Material requiredAndActive; public Material requiredAndActive;
public Material requiredAndPassive; public Material requiredAndPassive;
public Material notRequiredAndActive; public Material notRequiredAndActive;
public Material notRequiredAndPassive; public Material notRequiredAndPassive;
[Header("On Completion")]
public LineRenderer lineRenderer;
public Transform lineStart;
public Transform lineEnd;
public MeshRenderer activatableRenderer;
public Material activatableActiveMaterial;
public HingeJoint doorJoint;
public Collider doorInvisibleWall;
private List<ShapeScannerRay> existingRays; private List<ShapeScannerRay> existingRays;
private float raySpawnDistanceX; private float raySpawnDistanceX;
private float raySpawnDistanceZ; private float raySpawnDistanceZ;
private int currentConfiguration; private int currentConfiguration;
private int rayCount; private int rayCount;
private int correctRayStates; private int correctRayStates;
private bool isCompleted;
// Start is called before the first frame update // Start is called before the first frame update
@@ -52,27 +79,31 @@ public class ShapeScanner : MonoBehaviour
raySpawnDistanceX = raySpawnCorner2.localPosition.x - raySpawnCorner1.localPosition.x; raySpawnDistanceX = raySpawnCorner2.localPosition.x - raySpawnCorner1.localPosition.x;
raySpawnDistanceZ = raySpawnCorner2.localPosition.z - raySpawnCorner1.localPosition.z; raySpawnDistanceZ = raySpawnCorner2.localPosition.z - raySpawnCorner1.localPosition.z;
lineRenderer.enabled = false;
isCompleted = false;
currentConfiguration = 0; currentConfiguration = 0;
InitializeConfiguration(); InitializeConfiguration(configurations[0]);
} }
// Update is called once per frame // Update is called once per frame
void Update() void Update()
{ {
if (lineRenderer.enabled)
{
lineRenderer.SetPosition(0, lineStart.position);
lineRenderer.SetPosition(1, lineEnd.position);
}
} }
private void InitializeConfiguration() private void InitializeConfiguration(ShapeScannerConfiguration configuration)
{ {
// Delete all colliding objects and then all existing rays // Recreate all existing rays
DestroyCollidingObjects();
foreach (ShapeScannerRay ray in existingRays) foreach (ShapeScannerRay ray in existingRays)
{ {
Destroy(ray.gameObject); Destroy(ray.gameObject);
} }
existingRays.Clear(); existingRays.Clear();
ShapeScannerConfiguration configuration = configurations[currentConfiguration];
int rayRowCount = configuration.rows.Count; int rayRowCount = configuration.rows.Count;
for (int i = 0; i < rayRowCount; i++) for (int i = 0; i < rayRowCount; i++)
{ {
@@ -137,21 +168,31 @@ public class ShapeScanner : MonoBehaviour
{ {
correctRayStates++; correctRayStates++;
float correctPercentage = calculateCorrectPercentage(); float correctPercentage = calculateCorrectPercentage();
UpdateDisplay(correctPercentage);
if (isCompleted)
{
return;
}
if (correctPercentage >= configurations[currentConfiguration].requiredCorrectPercentage) if (correctPercentage >= configurations[currentConfiguration].requiredCorrectPercentage)
{ {
UpdateCurrentConfigurationDisplay(currentConfiguration + 1); UpdateCurrentConfigurationDisplay(currentConfiguration + 1);
if (currentConfiguration + 1 < configurations.Count) if (currentConfiguration + 1 < configurations.Count)
{ {
currentConfiguration++;
InitializeConfiguration();
AudioManager.Instance.PlayAttachedInstance(FMODEvents.Instance.ShapeScannerSuccess, gameObject); AudioManager.Instance.PlayAttachedInstance(FMODEvents.Instance.ShapeScannerSuccess, gameObject);
DestroyCollidingObjects();
currentConfiguration++;
InitializeConfiguration(configurations[currentConfiguration]);
} else } else
{ {
Debug.Log("Shape checker completed");
AudioManager.Instance.PlayAttachedInstance(FMODEvents.Instance.ShapeScannerSuccess, gameObject); AudioManager.Instance.PlayAttachedInstance(FMODEvents.Instance.ShapeScannerSuccess, gameObject);
DestroyCollidingObjects();
// Initialize configuration with all rays requiring collision
List<BoolRow> rows = Enumerable.Repeat(new BoolRow(Enumerable.Repeat(false, 6).ToList()), 6).ToList();
ShapeScannerConfiguration configuration = new ShapeScannerConfiguration(6, 100, rows);
InitializeConfiguration(configuration);
OnCompleteAll();
} }
} }
UpdateDisplay(correctPercentage);
} }
public void DecrementCorrectRayCount() public void DecrementCorrectRayCount()
@@ -169,4 +210,26 @@ public class ShapeScanner : MonoBehaviour
{ {
currentConfigurationDisplay.text = confNumber.ToString() + " / " + configurations.Count; currentConfigurationDisplay.text = confNumber.ToString() + " / " + configurations.Count;
} }
private void OnCompleteAll()
{
isCompleted = true;
// Change card reader color to green
activatableRenderer.material = activatableActiveMaterial;
// Enable door to be opened
JointLimits doorJointLimits = doorJoint.limits;
doorJointLimits.min = -90f;
doorJointLimits.max = 90f;
doorJoint.limits = doorJointLimits;
// Disable invisible wall
doorInvisibleWall.enabled = false;
// Create line renderer from shape scanner to door card reader
lineRenderer.enabled = true;
OnShapeScannerCompleted?.Invoke();
}
} }