Added speaker and power modules

This commit is contained in:
Christen
2026-03-03 00:51:12 -05:00
parent 6b2270381d
commit 20480f6eaf
65 changed files with 14788 additions and 718 deletions

View File

@@ -5,38 +5,47 @@ using UnityEngine.UI;
public class ControlPanel : MonoBehaviour public class ControlPanel : MonoBehaviour
{ {
[Header("Core UI (assign in Inspector)")] [Header("Core UI (assign in Inspector)")]
public TMP_InputField inputField; // was DegreesInputField public TMP_InputField inputField;
public TMP_Dropdown directionDropdown; // was DirectionDropdown public TMP_Dropdown directionDropdown;
public Button button; // was RotateButton public Button button; // existing Send/Rotate button in hierarchy
private enum Mode { None, DC, Display } private enum Mode { None, DC, Display, Speaker }
private Mode _mode = Mode.None; private Mode _mode = Mode.None;
private DCMotorModule _dc; private DCMotorModule _dc;
private DisplayModule _display; private DisplayModule _display;
private SpeakerModule _speaker;
// Keep separate inputs so they don't interfere
private string _savedDCInput = ""; private string _savedDCInput = "";
private int _savedDirectionIndex = 0; private int _savedDirectionIndex = 0;
private string _savedDisplayInput = ""; private string _savedDisplayInput = "";
// Found automatically (no new UI objects) // Found automatically (no hierarchy edits)
private TextMeshProUGUI _caption; // DegreesCaption text private TextMeshProUGUI _caption; // child "DegreesCaption"
private TextMeshProUGUI _buttonText; // RotateButton/Text (TMP) private TextMeshProUGUI _buttonText; // child "RotateButton/Text (TMP)"
private GameObject _directionCaptionGO; // DirectionCaption private GameObject _directionCaptionGO;
private GameObject _directionDropdownGO; // DirectionDropdown GameObject private GameObject _directionDropdownGO;
// Created in code (Speaker mode only)
private Button _uploadButton;
private TextMeshProUGUI _uploadButtonText;
private Button _playButton;
private TextMeshProUGUI _playButtonText;
private void Awake() private void Awake()
{ {
CacheUIFromHierarchy(); CacheUIFromHierarchy();
// Create these once; hide unless Speaker mode
CreateUploadButtonIfNeeded();
CreatePlayButtonIfNeeded();
if (button != null) if (button != null)
{ {
button.onClick.RemoveAllListeners(); button.onClick.RemoveAllListeners();
button.onClick.AddListener(OnButtonClicked); button.onClick.AddListener(OnMainButtonClicked);
} }
// Cache typed values so switching modules restores what you typed
if (inputField != null) if (inputField != null)
{ {
inputField.onValueChanged.AddListener(_ => CacheCurrentInput()); inputField.onValueChanged.AddListener(_ => CacheCurrentInput());
@@ -52,29 +61,17 @@ public class ControlPanel : MonoBehaviour
} }
} }
/// <summary>
/// Call this whenever a DC or Display module is selected.
/// </summary>
public void Initialize(ModuleBase module) public void Initialize(ModuleBase module)
{ {
CacheCurrentInput(); CacheCurrentInput();
_dc = module as DCMotorModule; _dc = module as DCMotorModule;
_display = module as DisplayModule; _display = module as DisplayModule;
_speaker = module as SpeakerModule;
if (_dc != null) if (_dc != null) { SwitchMode(Mode.DC); gameObject.SetActive(true); return; }
{ if (_display != null) { SwitchMode(Mode.Display); gameObject.SetActive(true); return; }
SwitchMode(Mode.DC); if (_speaker != null) { SwitchMode(Mode.Speaker); gameObject.SetActive(true); return; }
gameObject.SetActive(true);
return;
}
if (_display != null)
{
SwitchMode(Mode.Display);
gameObject.SetActive(true);
return;
}
HidePanel(); HidePanel();
} }
@@ -86,11 +83,13 @@ public class ControlPanel : MonoBehaviour
_mode = Mode.None; _mode = Mode.None;
_dc = null; _dc = null;
_display = null; _display = null;
_speaker = null;
SetUploadVisible(false);
SetPlayVisible(false);
} }
private void CacheUIFromHierarchy() private void CacheUIFromHierarchy()
{ {
// Assumes this script is on the parent that contains these children
var captionT = transform.Find("DegreesCaption"); var captionT = transform.Find("DegreesCaption");
if (captionT != null) _caption = captionT.GetComponent<TextMeshProUGUI>(); if (captionT != null) _caption = captionT.GetComponent<TextMeshProUGUI>();
@@ -111,31 +110,65 @@ public class ControlPanel : MonoBehaviour
if (_mode == Mode.DC) if (_mode == Mode.DC)
{ {
if (_caption != null) _caption.text = "Degrees"; SetCaption("Degrees");
if (_buttonText != null) _buttonText.text = "Rotate"; SetCaptionVisible(true);
SetMainButtonText("Rotate");
SetDirectionVisible(true); SetDirectionVisible(true);
SetInputVisible(true);
SetUploadVisible(false);
SetPlayVisible(false);
if (inputField != null) if (inputField != null)
{
inputField.readOnly = false;
inputField.SetTextWithoutNotify(_savedDCInput); inputField.SetTextWithoutNotify(_savedDCInput);
}
if (directionDropdown != null) if (directionDropdown != null)
directionDropdown.SetValueWithoutNotify(_savedDirectionIndex); directionDropdown.SetValueWithoutNotify(_savedDirectionIndex);
} }
else if (_mode == Mode.Display) else if (_mode == Mode.Display)
{ {
if (_caption != null) _caption.text = "Text"; SetCaption("Text");
if (_buttonText != null) _buttonText.text = "Send"; SetCaptionVisible(true);
SetMainButtonText("Send");
SetDirectionVisible(false); SetDirectionVisible(false);
SetInputVisible(true);
SetUploadVisible(false);
SetPlayVisible(false);
// Prefer module's current displayText; fallback to last typed text if (inputField != null)
{
inputField.readOnly = false;
string toShow = _savedDisplayInput; string toShow = _savedDisplayInput;
if (_display != null && !string.IsNullOrEmpty(_display.displayText)) if (_display != null && !string.IsNullOrEmpty(_display.displayText))
toShow = _display.displayText; toShow = _display.displayText;
if (inputField != null)
inputField.SetTextWithoutNotify(toShow); inputField.SetTextWithoutNotify(toShow);
} }
} }
else if (_mode == Mode.Speaker)
{
// Speaker UI: no input field (removes the white box behind buttons)
SetMainButtonText("Send Audio");
SetCaptionVisible(false);
SetDirectionVisible(false);
SetInputVisible(false);
// Show speaker buttons
SetUploadVisible(true);
SetPlayVisible(true);
}
}
private void SetCaption(string text)
{
if (_caption != null) _caption.text = text;
}
private void SetMainButtonText(string text)
{
if (_buttonText != null) _buttonText.text = text;
}
private void SetDirectionVisible(bool visible) private void SetDirectionVisible(bool visible)
{ {
@@ -143,6 +176,12 @@ public class ControlPanel : MonoBehaviour
if (_directionDropdownGO != null) _directionDropdownGO.SetActive(visible); if (_directionDropdownGO != null) _directionDropdownGO.SetActive(visible);
} }
private void SetInputVisible(bool visible)
{
if (inputField != null && inputField.gameObject.activeSelf != visible)
inputField.gameObject.SetActive(visible);
}
private void CacheCurrentInput() private void CacheCurrentInput()
{ {
if (inputField == null) return; if (inputField == null) return;
@@ -150,8 +189,7 @@ public class ControlPanel : MonoBehaviour
if (_mode == Mode.DC) if (_mode == Mode.DC)
{ {
_savedDCInput = inputField.text; _savedDCInput = inputField.text;
if (directionDropdown != null) if (directionDropdown != null) _savedDirectionIndex = directionDropdown.value;
_savedDirectionIndex = directionDropdown.value;
} }
else if (_mode == Mode.Display) else if (_mode == Mode.Display)
{ {
@@ -159,15 +197,11 @@ public class ControlPanel : MonoBehaviour
} }
} }
private void OnButtonClicked() private void OnMainButtonClicked()
{ {
if (_mode == Mode.DC) if (_mode == Mode.DC)
{ {
if (_dc == null) if (_dc == null) return;
{
Debug.LogWarning("ControlPanel: No DC module selected.");
return;
}
if (!float.TryParse(inputField.text, out float degrees)) if (!float.TryParse(inputField.text, out float degrees))
{ {
@@ -180,14 +214,206 @@ public class ControlPanel : MonoBehaviour
} }
else if (_mode == Mode.Display) else if (_mode == Mode.Display)
{ {
if (_display == null) if (_display == null) return;
_display.SetDisplayText(inputField != null ? inputField.text : "");
}
else if (_mode == Mode.Speaker)
{ {
Debug.LogWarning("ControlPanel: No Display module selected."); if (_speaker == null) return;
return; _speaker.SendAudioToHardware(); // Send Audio = upload to hardware (your implementation)
}
} }
string text = inputField != null ? inputField.text : ""; // -------------------------
_display.SetDisplayText(text); // <- THIS is where Display module gets the text // Styling helpers (copy Send button look)
// -------------------------
private void CopyButtonStyle(Button source, Button target)
{
if (source == null || target == null) return;
// Button settings
target.transition = source.transition;
target.colors = source.colors;
target.spriteState = source.spriteState;
target.navigation = source.navigation;
target.interactable = source.interactable;
// Image settings
var srcImg = source.GetComponent<Image>();
var dstImg = target.GetComponent<Image>();
if (srcImg != null && dstImg != null)
{
dstImg.sprite = srcImg.sprite;
dstImg.type = srcImg.type;
dstImg.pixelsPerUnitMultiplier = srcImg.pixelsPerUnitMultiplier;
dstImg.material = srcImg.material;
dstImg.color = srcImg.color;
dstImg.raycastTarget = srcImg.raycastTarget;
} }
} }
private void CopyTMPStyle(TextMeshProUGUI source, TextMeshProUGUI target)
{
if (source == null || target == null) return;
target.font = source.font;
target.fontSharedMaterial = source.fontSharedMaterial;
target.fontStyle = source.fontStyle;
target.fontSize = source.fontSize;
target.enableAutoSizing = source.enableAutoSizing;
target.color = source.color;
target.enableVertexGradient = source.enableVertexGradient;
target.alignment = source.alignment;
target.enableWordWrapping = source.enableWordWrapping;
target.richText = source.richText;
}
// -------------------------
// Upload button (code-created)
// -------------------------
private void CreateUploadButtonIfNeeded()
{
if (_uploadButton != null) return;
var go = new GameObject("UploadButton");
go.transform.SetParent(transform, false);
var img = go.AddComponent<Image>();
img.raycastTarget = true;
_uploadButton = go.AddComponent<Button>();
_uploadButton.onClick.AddListener(OnUploadClicked);
// Copy Send button look
CopyButtonStyle(button, _uploadButton);
var textGo = new GameObject("Text (TMP)");
textGo.transform.SetParent(go.transform, false);
_uploadButtonText = textGo.AddComponent<TextMeshProUGUI>();
_uploadButtonText.text = "Upload Audio";
// Copy Send text look
CopyTMPStyle(_buttonText, _uploadButtonText);
_uploadButtonText.alignment = TextAlignmentOptions.Center;
// Layout: above Play
var rt = go.GetComponent<RectTransform>();
rt.anchorMin = new Vector2(0.5f, 0f);
rt.anchorMax = new Vector2(0.5f, 0f);
rt.pivot = new Vector2(0.5f, 0f);
rt.sizeDelta = button != null ? button.GetComponent<RectTransform>().sizeDelta : new Vector2(180f, 40f);
rt.anchoredPosition = new Vector2(0f, 110f);
var trt = textGo.GetComponent<RectTransform>();
trt.anchorMin = Vector2.zero;
trt.anchorMax = Vector2.one;
trt.offsetMin = Vector2.zero;
trt.offsetMax = Vector2.zero;
go.SetActive(false);
}
private void SetUploadVisible(bool visible)
{
if (_uploadButton != null && _uploadButton.gameObject.activeSelf != visible)
_uploadButton.gameObject.SetActive(visible);
}
private void OnUploadClicked()
{
if (_speaker == null) return;
string path = OpenAudioFilePicker();
if (string.IsNullOrEmpty(path)) return;
_speaker.SetAudioFile(path);
// If you want to display filename somewhere without the input field,
// we can put it in the caption temporarily or add a TMP label in code.
}
// -------------------------
// Play button (code-created)
// -------------------------
private void CreatePlayButtonIfNeeded()
{
if (_playButton != null) return;
var go = new GameObject("PlayButton");
go.transform.SetParent(transform, false);
var img = go.AddComponent<Image>();
img.raycastTarget = true;
_playButton = go.AddComponent<Button>();
_playButton.onClick.AddListener(OnPlayClicked);
// Copy Send button look
CopyButtonStyle(button, _playButton);
var textGo = new GameObject("Text (TMP)");
textGo.transform.SetParent(go.transform, false);
_playButtonText = textGo.AddComponent<TextMeshProUGUI>();
_playButtonText.text = "Play Audio";
// Copy Send text look
CopyTMPStyle(_buttonText, _playButtonText);
_playButtonText.alignment = TextAlignmentOptions.Center;
// Layout: between Upload and Send
var rt = go.GetComponent<RectTransform>();
rt.anchorMin = new Vector2(0.5f, 0f);
rt.anchorMax = new Vector2(0.5f, 0f);
rt.pivot = new Vector2(0.5f, 0f);
rt.sizeDelta = button != null ? button.GetComponent<RectTransform>().sizeDelta : new Vector2(180f, 40f);
rt.anchoredPosition = new Vector2(0f, 60f);
var trt = textGo.GetComponent<RectTransform>();
trt.anchorMin = Vector2.zero;
trt.anchorMax = Vector2.one;
trt.offsetMin = Vector2.zero;
trt.offsetMax = Vector2.zero;
go.SetActive(false);
}
private void SetPlayVisible(bool visible)
{
if (_playButton != null && _playButton.gameObject.activeSelf != visible)
_playButton.gameObject.SetActive(visible);
}
private void OnPlayClicked()
{
if (_speaker == null) return;
_speaker.PlayAudioOnHardware();
}
// -------------------------
// File Picker (Editor + builds via SFB)
// -------------------------
private string OpenAudioFilePicker()
{
#if UNITY_EDITOR
return UnityEditor.EditorUtility.OpenFilePanel("Select audio file", "", "wav,mp3,ogg");
#else
var extensions = new[]
{
new SFB.ExtensionFilter("Audio Files", "wav", "mp3", "ogg"),
new SFB.ExtensionFilter("All Files", "*")
};
string[] paths = SFB.StandaloneFileBrowser.OpenFilePanel("Select audio file", "", extensions, false);
return (paths != null && paths.Length > 0) ? paths[0] : "";
#endif
}
private void SetCaptionVisible(bool visible)
{
if (_caption != null && _caption.gameObject.activeSelf != visible)
_caption.gameObject.SetActive(visible);
}
} }

View File

@@ -272,7 +272,7 @@ public class InverseKinematicsController : MonoBehaviour
ModuleBase module = child.GetComponent<ModuleBase>(); ModuleBase module = child.GetComponent<ModuleBase>();
if (module != null) if (module != null)
{ {
BatteryModule battery = child.GetComponent<BatteryModule>(); PowerModule battery = child.GetComponent<PowerModule>();
HubModule hub = child.GetComponent<HubModule>(); HubModule hub = child.GetComponent<HubModule>();
if (battery != null || hub != null) if (battery != null || hub != null)

View File

@@ -23,7 +23,6 @@ public class LiveViewModulePanel : MonoBehaviour
private bool _sliderDragging; private bool _sliderDragging;
private ControlPanel panel; private ControlPanel panel;
private ModuleBase _lastSelected;
private GameObject sensorTextContainer; private GameObject sensorTextContainer;
private readonly System.Collections.Generic.List<TextMeshProUGUI> sensorTextLines = new System.Collections.Generic.List<TextMeshProUGUI>(); private readonly System.Collections.Generic.List<TextMeshProUGUI> sensorTextLines = new System.Collections.Generic.List<TextMeshProUGUI>();
@@ -67,7 +66,6 @@ public class LiveViewModulePanel : MonoBehaviour
if (selected == null) if (selected == null)
{ {
_lastSelected = null;
SetModuleInfo("No module selected"); SetModuleInfo("No module selected");
SetServoSectionActive(false); SetServoSectionActive(false);
SetModuleControlSectionActive(false); SetModuleControlSectionActive(false);
@@ -85,6 +83,7 @@ public class LiveViewModulePanel : MonoBehaviour
var display = selected as DisplayModule; var display = selected as DisplayModule;
var distance = selected as DistanceSensorModule; var distance = selected as DistanceSensorModule;
var imu = selected as IMUSensorModule; var imu = selected as IMUSensorModule;
var speaker = selected as SpeakerModule;
if (servo != null) if (servo != null)
{ {
@@ -119,18 +118,12 @@ public class LiveViewModulePanel : MonoBehaviour
} }
// DC or Display both use the same control section // DC or Display both use the same control section
if (dc != null || display != null) if (dc != null || display != null || speaker != null)
{ {
SetServoSectionActive(false); SetServoSectionActive(false);
SetModuleControlSectionActive(true); SetModuleControlSectionActive(true);
SetSensorTextActive(false);
if (selected != _lastSelected)
{
_lastSelected = selected;
panel?.Initialize(selected); panel?.Initialize(selected);
}
return; return;
} }
@@ -257,11 +250,12 @@ public class LiveViewModulePanel : MonoBehaviour
if (m is DCMotorModule) return "DC"; if (m is DCMotorModule) return "DC";
if (m is DisplayModule) return "Display"; if (m is DisplayModule) return "Display";
if (m is HubModule) return "Hub"; if (m is HubModule) return "Hub";
if (m is BatteryModule) return "Battery"; if (m is PowerModule) return "Power";
if (m is GripperModule) return "Gripper"; if (m is GripperModule) return "Gripper";
if (m is DisplayModule) return "Display"; if (m is DisplayModule) return "Display";
if (m is DistanceSensorModule) return "Distance Sensor"; if (m is DistanceSensorModule) return "Distance Sensor";
if (m is IMUSensorModule) return "IMU Sensor"; if (m is IMUSensorModule) return "IMU Sensor";
if (m is SpeakerModule) return "Speaker";
return m.GetType().Name; return m.GetType().Name;
} }

View File

@@ -0,0 +1,223 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &266408585238236575
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 4821719273987100255}
m_Layer: 0
m_Name: FemaleSocket
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &4821719273987100255
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 266408585238236575}
serializedVersion: 2
m_LocalRotation: {x: 0.006214511, y: 0.006214511, z: 0.70707947, w: 0.70707947}
m_LocalPosition: {x: -0.0219, y: -0.005, z: 0.02312}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 2917815422892282183}
m_LocalEulerAnglesHint: {x: 0, y: 1.007, z: 90}
--- !u!1 &345754696597093027
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 2121160668400849063}
m_Layer: 0
m_Name: MaleSocket
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &2121160668400849063
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 345754696597093027}
serializedVersion: 2
m_LocalRotation: {x: 0.7071068, y: 0.7071068, z: -0, w: 0}
m_LocalPosition: {x: -0.0232, y: 0.0399, z: 0.02402}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 2917815422892282183}
m_LocalEulerAnglesHint: {x: 180, y: 0, z: -90}
--- !u!1 &5681477249120589453
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 2917815422892282183}
- component: {fileID: -8777375893921437079}
m_Layer: 0
m_Name: PowerModule
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &2917815422892282183
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5681477249120589453}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: -0.7071068, w: 0.7071068}
m_LocalPosition: {x: -0.89659035, y: -0.003384322, z: 0}
m_LocalScale: {x: 20, y: 20, z: 20}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 2640250676474912634}
- {fileID: 4821719273987100255}
- {fileID: 2121160668400849063}
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: -90}
--- !u!114 &-8777375893921437079
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5681477249120589453}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 49a8b93f7e3164531b9e4b2818846a49, type: 3}
m_Name:
m_EditorClassIdentifier: '::'
--- !u!1 &8268068020519066474
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 2640250676474912634}
- component: {fileID: 7771497960902486818}
- component: {fileID: 6922944829566013587}
- component: {fileID: 95829305916229069}
m_Layer: 0
m_Name: Body1
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &2640250676474912634
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8268068020519066474}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 10, y: 10, z: 10}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 2917815422892282183}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!33 &7771497960902486818
MeshFilter:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8268068020519066474}
m_Mesh: {fileID: 8604045607132181640, guid: b8a656ee45f5c4b31b1abf520cd3e327, type: 3}
--- !u!23 &6922944829566013587
MeshRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8268068020519066474}
m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_StaticShadowCaster: 0
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RayTracingMode: 2
m_RayTraceProcedural: 0
m_RayTracingAccelStructBuildFlagsOverride: 0
m_RayTracingAccelStructBuildFlags: 1
m_SmallMeshCulling: 1
m_ForceMeshLod: -1
m_MeshLodSelectionBias: 0
m_RenderingLayerMask: 1
m_RendererPriority: 0
m_Materials:
- {fileID: 7397659539795428015, guid: b8a656ee45f5c4b31b1abf520cd3e327, type: 3}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0
m_StaticBatchRoot: {fileID: 0}
m_ProbeAnchor: {fileID: 0}
m_LightProbeVolumeOverride: {fileID: 0}
m_ScaleInLightmap: 1
m_ReceiveGI: 1
m_PreserveUVs: 0
m_IgnoreNormalsForChartDetection: 0
m_ImportantGI: 0
m_StitchLightmapSeams: 1
m_SelectedEditorRenderState: 3
m_MinimumChartSize: 4
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_GlobalIlluminationMeshLod: 0
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
m_MaskInteraction: 0
m_AdditionalVertexStreams: {fileID: 0}
--- !u!65 &95829305916229069
BoxCollider:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8268068020519066474}
m_Material: {fileID: 0}
m_IncludeLayers:
serializedVersion: 2
m_Bits: 0
m_ExcludeLayers:
serializedVersion: 2
m_Bits: 0
m_LayerOverridePriority: 0
m_IsTrigger: 0
m_ProvidesContacts: 0
m_Enabled: 1
serializedVersion: 3
m_Size: {x: 0.0045000003, y: 0.0045915223, z: 0.0048}
m_Center: {x: -0.0022500001, y: 0.0017957613, z: 0.0024}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 2d0654bf410fb459196f824c861fff6b
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,194 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &2129132915235679198
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 4518296261177981408}
m_Layer: 0
m_Name: FemaleSocket
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &4518296261177981408
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2129132915235679198}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0.7071068, z: 0, w: 0.7071068}
m_LocalPosition: {x: -0.0202, y: 0.01977, z: 0.03219}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 6865122621445020434}
m_LocalEulerAnglesHint: {x: 0, y: 90, z: 0}
--- !u!1 &7364806464279017071
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 6865122621445020434}
- component: {fileID: 6165004530198508495}
m_Layer: 0
m_Name: SpeakerModule
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &6865122621445020434
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7364806464279017071}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 20, y: 20, z: 20}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 3476968620267983768}
- {fileID: 4518296261177981408}
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &6165004530198508495
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7364806464279017071}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 20afe4b54fe7b42cb97881ff62dd6797, type: 3}
m_Name:
m_EditorClassIdentifier: '::'
audioFilePath:
audioFileName:
audioBytes:
--- !u!1 &8692649955752510689
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 3476968620267983768}
- component: {fileID: 4175202012497613128}
- component: {fileID: 4754481417108555804}
- component: {fileID: 2797191861453826670}
m_Layer: 0
m_Name: Body3
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &3476968620267983768
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8692649955752510689}
serializedVersion: 2
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 10, y: 10, z: 10}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 6865122621445020434}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!33 &4175202012497613128
MeshFilter:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8692649955752510689}
m_Mesh: {fileID: 6679289703562662588, guid: 394e8674d183843c0a846fc96e6f793a, type: 3}
--- !u!23 &4754481417108555804
MeshRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8692649955752510689}
m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_StaticShadowCaster: 0
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RayTracingMode: 2
m_RayTraceProcedural: 0
m_RayTracingAccelStructBuildFlagsOverride: 0
m_RayTracingAccelStructBuildFlags: 1
m_SmallMeshCulling: 1
m_ForceMeshLod: -1
m_MeshLodSelectionBias: 0
m_RenderingLayerMask: 1
m_RendererPriority: 0
m_Materials:
- {fileID: 7397659539795428015, guid: 394e8674d183843c0a846fc96e6f793a, type: 3}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0
m_StaticBatchRoot: {fileID: 0}
m_ProbeAnchor: {fileID: 0}
m_LightProbeVolumeOverride: {fileID: 0}
m_ScaleInLightmap: 1
m_ReceiveGI: 1
m_PreserveUVs: 0
m_IgnoreNormalsForChartDetection: 0
m_ImportantGI: 0
m_StitchLightmapSeams: 1
m_SelectedEditorRenderState: 3
m_MinimumChartSize: 4
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_GlobalIlluminationMeshLod: 0
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
m_MaskInteraction: 0
m_AdditionalVertexStreams: {fileID: 0}
--- !u!65 &2797191861453826670
BoxCollider:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8692649955752510689}
m_Material: {fileID: 0}
m_IncludeLayers:
serializedVersion: 2
m_Bits: 0
m_ExcludeLayers:
serializedVersion: 2
m_Bits: 0
m_LayerOverridePriority: 0
m_IsTrigger: 0
m_ProvidesContacts: 0
m_Enabled: 1
serializedVersion: 3
m_Size: {x: 0.004, y: 0.004, z: 0.0032000002}
m_Center: {x: -0.002, y: 0.002, z: 0.0016000001}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 8bcdcbcb5a03245248cb7f883e80d948
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -118,6 +118,7 @@ public class TopologyBuilder : MonoBehaviour
case "Display": return ModuleType.DISPLAY; case "Display": return ModuleType.DISPLAY;
case "Distance": return ModuleType.DISTANCE_SENSOR; case "Distance": return ModuleType.DISTANCE_SENSOR;
case "IMU": return ModuleType.IMU; case "IMU": return ModuleType.IMU;
case "Speaker": return ModuleType.SPEAKER;
default: return ModuleType.SPLITTER; default: return ModuleType.SPLITTER;
} }
} }

View File

@@ -100,7 +100,7 @@ PrefabInstance:
objectReference: {fileID: 0} objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: c9bb9c26ce95f4c38b0975e4796d7c84, type: 3} - target: {fileID: -8679921383154817045, guid: c9bb9c26ce95f4c38b0975e4796d7c84, type: 3}
propertyPath: m_LocalRotation.x propertyPath: m_LocalRotation.x
value: -0 value: 0
objectReference: {fileID: 0} objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: c9bb9c26ce95f4c38b0975e4796d7c84, type: 3} - target: {fileID: -8679921383154817045, guid: c9bb9c26ce95f4c38b0975e4796d7c84, type: 3}
propertyPath: m_LocalRotation.y propertyPath: m_LocalRotation.y
@@ -108,7 +108,7 @@ PrefabInstance:
objectReference: {fileID: 0} objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: c9bb9c26ce95f4c38b0975e4796d7c84, type: 3} - target: {fileID: -8679921383154817045, guid: c9bb9c26ce95f4c38b0975e4796d7c84, type: 3}
propertyPath: m_LocalRotation.z propertyPath: m_LocalRotation.z
value: 0.7071068 value: -0.7071068
objectReference: {fileID: 0} objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: c9bb9c26ce95f4c38b0975e4796d7c84, type: 3} - target: {fileID: -8679921383154817045, guid: c9bb9c26ce95f4c38b0975e4796d7c84, type: 3}
propertyPath: m_LocalEulerAnglesHint.x propertyPath: m_LocalEulerAnglesHint.x
@@ -140,9 +140,6 @@ PrefabInstance:
insertIndex: -1 insertIndex: -1
addedObject: {fileID: 6174788492104592851} addedObject: {fileID: 6174788492104592851}
m_AddedComponents: m_AddedComponents:
- targetCorrespondingSourceObject: {fileID: 919132149155446097, guid: c9bb9c26ce95f4c38b0975e4796d7c84, type: 3}
insertIndex: -1
addedObject: {fileID: 8539805925341693153}
- targetCorrespondingSourceObject: {fileID: 919132149155446097, guid: c9bb9c26ce95f4c38b0975e4796d7c84, type: 3} - targetCorrespondingSourceObject: {fileID: 919132149155446097, guid: c9bb9c26ce95f4c38b0975e4796d7c84, type: 3}
insertIndex: -1 insertIndex: -1
addedObject: {fileID: 1972764005790451530} addedObject: {fileID: 1972764005790451530}
@@ -155,18 +152,6 @@ GameObject:
m_CorrespondingSourceObject: {fileID: 919132149155446097, guid: c9bb9c26ce95f4c38b0975e4796d7c84, type: 3} m_CorrespondingSourceObject: {fileID: 919132149155446097, guid: c9bb9c26ce95f4c38b0975e4796d7c84, type: 3}
m_PrefabInstance: {fileID: 4547805183318821893} m_PrefabInstance: {fileID: 4547805183318821893}
m_PrefabAsset: {fileID: 0} m_PrefabAsset: {fileID: 0}
--- !u!114 &8539805925341693153
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3736973296473420116}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: f0d44e50b94d44bf6b87f9db5a07981c, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!65 &1972764005790451530 --- !u!65 &1972764005790451530
BoxCollider: BoxCollider:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0

Binary file not shown.

View File

@@ -0,0 +1,110 @@
fileFormatVersion: 2
guid: b8a656ee45f5c4b31b1abf520cd3e327
ModelImporter:
serializedVersion: 24200
internalIDToNameTable: []
externalObjects: {}
materials:
materialImportMode: 2
materialName: 0
materialSearch: 1
materialLocation: 1
animations:
legacyGenerateAnimations: 4
bakeSimulation: 0
resampleCurves: 1
optimizeGameObjects: 0
removeConstantScaleCurves: 0
motionNodeName:
animationImportErrors:
animationImportWarnings:
animationRetargetingWarnings:
animationDoRetargetingWarnings: 0
importAnimatedCustomProperties: 0
importConstraints: 0
animationCompression: 1
animationRotationError: 0.5
animationPositionError: 0.5
animationScaleError: 0.5
animationWrapMode: 0
extraExposedTransformPaths: []
extraUserProperties: []
clipAnimations: []
isReadable: 0
meshes:
lODScreenPercentages: []
globalScale: 1
meshCompression: 0
addColliders: 0
useSRGBMaterialColor: 1
sortHierarchyByName: 1
importPhysicalCameras: 1
importVisibility: 1
importBlendShapes: 1
importCameras: 1
importLights: 1
nodeNameCollisionStrategy: 1
fileIdsGeneration: 2
swapUVChannels: 0
generateSecondaryUV: 0
useFileUnits: 1
keepQuads: 0
weldVertices: 1
bakeAxisConversion: 0
preserveHierarchy: 0
skinWeightsMode: 0
maxBonesPerVertex: 4
minBoneWeight: 0.001
optimizeBones: 1
generateMeshLods: 0
meshLodGenerationFlags: 0
maximumMeshLod: -1
meshOptimizationFlags: -1
indexFormat: 0
secondaryUVAngleDistortion: 8
secondaryUVAreaDistortion: 15.000001
secondaryUVHardAngle: 88
secondaryUVMarginMethod: 1
secondaryUVMinLightmapResolution: 40
secondaryUVMinObjectScale: 1
secondaryUVPackMargin: 4
useFileScale: 1
strictVertexDataChecks: 0
tangentSpace:
normalSmoothAngle: 60
normalImportMode: 0
tangentImportMode: 3
normalCalculationMode: 4
legacyComputeAllNormalsFromSmoothingGroupsWhenMeshHasBlendShapes: 0
blendShapeNormalImportMode: 1
normalSmoothingSource: 0
referencedClips: []
importAnimation: 1
humanDescription:
serializedVersion: 3
human: []
skeleton: []
armTwist: 0.5
foreArmTwist: 0.5
upperLegTwist: 0.5
legTwist: 0.5
armStretch: 0.05
legStretch: 0.05
feetSpacing: 0
globalScale: 1
rootMotionBoneName:
hasTranslationDoF: 0
hasExtraRoot: 0
skeletonHasParents: 1
lastHumanDescriptionAvatarSource: {instanceID: 0}
autoGenerateAvatarMappingIfUnspecified: 1
animationType: 2
humanoidOversampling: 1
avatarSetup: 0
addHumanoidExtraRootOnlyWhenUsingAvatar: 1
importBlendShapeDeformPercent: 1
remapMaterialsIfMaterialImportModeIsNone: 0
additionalBone: 0
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -13,6 +13,7 @@ public class ModuleSpawner : MonoBehaviour
public GameObject displayModulePrefab; public GameObject displayModulePrefab;
public GameObject distanceSensorModulePrefab; public GameObject distanceSensorModulePrefab;
public GameObject imuSensorModulePrefab; public GameObject imuSensorModulePrefab;
public GameObject speakerModulePrefab;
public GameObject GetPrefabForType(ModuleType type) public GameObject GetPrefabForType(ModuleType type)
{ {
@@ -37,6 +38,8 @@ public class ModuleSpawner : MonoBehaviour
return distanceSensorModulePrefab; return distanceSensorModulePrefab;
case ModuleType.IMU: case ModuleType.IMU:
return imuSensorModulePrefab; return imuSensorModulePrefab;
case ModuleType.SPEAKER:
return speakerModulePrefab;
default: default:
Debug.LogError("Unknown module type: " + type); Debug.LogError("Unknown module type: " + type);
return null; return null;

View File

@@ -2,6 +2,6 @@ using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;
public class BatteryModule : ModuleBase public class PowerModule : ModuleBase
{ {
} }

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 49a8b93f7e3164531b9e4b2818846a49

View File

@@ -1 +1 @@
{"Modules":[{"Id":"battery1","Type":"Battery","Degree":null},{"Id":"servo1","Type":"Servo1","Degree":45},{"Id":"servo2","Type":"Servo2","Degree":60},{"Id":"servo3","Type":"Servo1","Degree":90},{"Id":"servo4","Type":"Servo2","Degree":0},{"Id":"endModule","Type":"Gripper","Degree":null}],"Connections":[{"FromModuleId":"battery1","ToModuleId":"servo1","FromSocket":"MaleSocket","ToSocket":"BodySocket","Orientation":0},{"FromModuleId":"servo1","ToModuleId":"servo2","FromSocket":"MaleSocket","ToSocket":"FemaleSocket","Orientation":90},{"FromModuleId":"servo2","ToModuleId":"servo3","FromSocket":"MaleSocket","ToSocket":"FemaleSocket","Orientation":0},{"FromModuleId":"servo3","ToModuleId":"servo4","FromSocket":"MaleSocket","ToSocket":"FemaleSocket","Orientation":90},{"FromModuleId":"servo4","ToModuleId":"endModule","FromSocket":"MaleSocket","ToSocket":"FemaleSocket","Orientation":0}]} {"Modules":[{"Id":"battery1","Type":"Battery","Degree":null},{"Id":"servo1","Type":"Servo1","Degree":45},{"Id":"servo2","Type":"Servo2","Degree":60},{"Id":"servo3","Type":"Servo1","Degree":90},{"Id":"servo4","Type":"Servo2","Degree":0},{"Id":"endModule","Type":"Speaker","Degree":null}],"Connections":[{"FromModuleId":"battery1","ToModuleId":"servo1","FromSocket":"MaleSocket","ToSocket":"BodySocket","Orientation":0},{"FromModuleId":"servo1","ToModuleId":"servo2","FromSocket":"MaleSocket","ToSocket":"FemaleSocket","Orientation":90},{"FromModuleId":"servo2","ToModuleId":"servo3","FromSocket":"MaleSocket","ToSocket":"FemaleSocket","Orientation":0},{"FromModuleId":"servo3","ToModuleId":"servo4","FromSocket":"MaleSocket","ToSocket":"FemaleSocket","Orientation":90},{"FromModuleId":"servo4","ToModuleId":"endModule","FromSocket":"MaleSocket","ToSocket":"FemaleSocket","Orientation":0}]}

View File

@@ -946,7 +946,7 @@ MonoBehaviour:
spawner: {fileID: 2021810911} spawner: {fileID: 2021810911}
useJsonFile: 1 useJsonFile: 1
skipControlLibraryCalls: 0 skipControlLibraryCalls: 0
jsonFileName: mockDataSimple jsonFileName: mockData
--- !u!4 &387671720 --- !u!4 &387671720
Transform: Transform:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@@ -4223,10 +4223,7 @@ PrefabInstance:
objectReference: {fileID: 0} objectReference: {fileID: 0}
m_RemovedComponents: [] m_RemovedComponents: []
m_RemovedGameObjects: [] m_RemovedGameObjects: []
m_AddedGameObjects: m_AddedGameObjects: []
- targetCorrespondingSourceObject: {fileID: 4077927847297772526, guid: 46058ab5ebab64d548b4008f54df1f6d, type: 3}
insertIndex: -1
addedObject: {fileID: 0}
m_AddedComponents: [] m_AddedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: 46058ab5ebab64d548b4008f54df1f6d, type: 3} m_SourcePrefab: {fileID: 100100000, guid: 46058ab5ebab64d548b4008f54df1f6d, type: 3}
--- !u!1 &943453643 --- !u!1 &943453643
@@ -6021,119 +6018,6 @@ PrefabInstance:
m_AddedGameObjects: [] m_AddedGameObjects: []
m_AddedComponents: [] m_AddedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: 5c6ff9c85cb0b4e54a56a4714e2245e7, type: 3} m_SourcePrefab: {fileID: 100100000, guid: 5c6ff9c85cb0b4e54a56a4714e2245e7, type: 3}
--- !u!1001 &1309657867
PrefabInstance:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Modification:
serializedVersion: 3
m_TransformParent: {fileID: 447450379}
m_Modifications:
- target: {fileID: 3506715766167772924, guid: 7731927cf621844b6aad08f3b4f9e278, type: 3}
propertyPath: m_LocalPosition.x
value: 0.0024008183
objectReference: {fileID: 0}
- target: {fileID: 3506715766167772924, guid: 7731927cf621844b6aad08f3b4f9e278, type: 3}
propertyPath: m_LocalPosition.y
value: -0.0059973295
objectReference: {fileID: 0}
- target: {fileID: 3506715766167772924, guid: 7731927cf621844b6aad08f3b4f9e278, type: 3}
propertyPath: m_LocalPosition.z
value: 0.0005073524
objectReference: {fileID: 0}
- target: {fileID: 3506715766167772924, guid: 7731927cf621844b6aad08f3b4f9e278, type: 3}
propertyPath: m_LocalRotation.w
value: 0.6974705
objectReference: {fileID: 0}
- target: {fileID: 3506715766167772924, guid: 7731927cf621844b6aad08f3b4f9e278, type: 3}
propertyPath: m_LocalRotation.x
value: 0.7166136
objectReference: {fileID: 0}
- target: {fileID: 3506715766167772924, guid: 7731927cf621844b6aad08f3b4f9e278, type: 3}
propertyPath: m_LocalRotation.y
value: 0.0000031748782
objectReference: {fileID: 0}
- target: {fileID: 3506715766167772924, guid: 7731927cf621844b6aad08f3b4f9e278, type: 3}
propertyPath: m_LocalRotation.z
value: -0.000025998797
objectReference: {fileID: 0}
- target: {fileID: 3506715766167772924, guid: 7731927cf621844b6aad08f3b4f9e278, type: 3}
propertyPath: m_LocalEulerAnglesHint.x
value: 91.550995
objectReference: {fileID: 0}
- target: {fileID: 3506715766167772924, guid: 7731927cf621844b6aad08f3b4f9e278, type: 3}
propertyPath: m_LocalEulerAnglesHint.y
value: 0.069000244
objectReference: {fileID: 0}
- target: {fileID: 3506715766167772924, guid: 7731927cf621844b6aad08f3b4f9e278, type: 3}
propertyPath: m_LocalEulerAnglesHint.z
value: 0.06700134
objectReference: {fileID: 0}
- target: {fileID: 3563533490444010952, guid: 7731927cf621844b6aad08f3b4f9e278, type: 3}
propertyPath: m_Name
value: DCMotorModule
objectReference: {fileID: 0}
- target: {fileID: 5278868739616043210, guid: 7731927cf621844b6aad08f3b4f9e278, type: 3}
propertyPath: m_LocalScale.x
value: 1
objectReference: {fileID: 0}
- target: {fileID: 5278868739616043210, guid: 7731927cf621844b6aad08f3b4f9e278, type: 3}
propertyPath: m_LocalScale.y
value: 1
objectReference: {fileID: 0}
- target: {fileID: 5278868739616043210, guid: 7731927cf621844b6aad08f3b4f9e278, type: 3}
propertyPath: m_LocalScale.z
value: 1
objectReference: {fileID: 0}
- target: {fileID: 5278868739616043210, guid: 7731927cf621844b6aad08f3b4f9e278, type: 3}
propertyPath: m_LocalPosition.x
value: -0.09662003
objectReference: {fileID: 0}
- target: {fileID: 5278868739616043210, guid: 7731927cf621844b6aad08f3b4f9e278, type: 3}
propertyPath: m_LocalPosition.y
value: 0.019779649
objectReference: {fileID: 0}
- target: {fileID: 5278868739616043210, guid: 7731927cf621844b6aad08f3b4f9e278, type: 3}
propertyPath: m_LocalPosition.z
value: 0.023702811
objectReference: {fileID: 0}
- target: {fileID: 5278868739616043210, guid: 7731927cf621844b6aad08f3b4f9e278, type: 3}
propertyPath: m_LocalRotation.w
value: -0.4927276
objectReference: {fileID: 0}
- target: {fileID: 5278868739616043210, guid: 7731927cf621844b6aad08f3b4f9e278, type: 3}
propertyPath: m_LocalRotation.x
value: 0.5017962
objectReference: {fileID: 0}
- target: {fileID: 5278868739616043210, guid: 7731927cf621844b6aad08f3b4f9e278, type: 3}
propertyPath: m_LocalRotation.y
value: -0.49552006
objectReference: {fileID: 0}
- target: {fileID: 5278868739616043210, guid: 7731927cf621844b6aad08f3b4f9e278, type: 3}
propertyPath: m_LocalRotation.z
value: -0.50978434
objectReference: {fileID: 0}
- target: {fileID: 5278868739616043210, guid: 7731927cf621844b6aad08f3b4f9e278, type: 3}
propertyPath: m_LocalEulerAnglesHint.x
value: 0.49
objectReference: {fileID: 0}
- target: {fileID: 5278868739616043210, guid: 7731927cf621844b6aad08f3b4f9e278, type: 3}
propertyPath: m_LocalEulerAnglesHint.y
value: 1.335
objectReference: {fileID: 0}
- target: {fileID: 5278868739616043210, guid: 7731927cf621844b6aad08f3b4f9e278, type: 3}
propertyPath: m_LocalEulerAnglesHint.z
value: -89.367
objectReference: {fileID: 0}
- target: {fileID: 5278868739616043210, guid: 7731927cf621844b6aad08f3b4f9e278, type: 3}
propertyPath: m_ConstrainProportionsScale
value: 1
objectReference: {fileID: 0}
m_RemovedComponents: []
m_RemovedGameObjects: []
m_AddedGameObjects: []
m_AddedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: 7731927cf621844b6aad08f3b4f9e278, type: 3}
--- !u!4 &1375238161 stripped --- !u!4 &1375238161 stripped
Transform: Transform:
m_CorrespondingSourceObject: {fileID: 7998878104662105930, guid: 5c6ff9c85cb0b4e54a56a4714e2245e7, type: 3} m_CorrespondingSourceObject: {fileID: 7998878104662105930, guid: 5c6ff9c85cb0b4e54a56a4714e2245e7, type: 3}
@@ -8759,7 +8643,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 63e1e2b9c1bac4a1bb3906c33e11ce3c, type: 3} m_Script: {fileID: 11500000, guid: 63e1e2b9c1bac4a1bb3906c33e11ce3c, type: 3}
m_Name: m_Name:
m_EditorClassIdentifier: m_EditorClassIdentifier:
batteryModulePrefab: {fileID: 3736973296473420116, guid: 46058ab5ebab64d548b4008f54df1f6d, type: 3} batteryModulePrefab: {fileID: 5681477249120589453, guid: 2d0654bf410fb459196f824c861fff6b, type: 3}
hubModulePrefab: {fileID: 2038062744777034846, guid: 2e29377717f1046f2b6b15656dd58cc2, type: 3} hubModulePrefab: {fileID: 2038062744777034846, guid: 2e29377717f1046f2b6b15656dd58cc2, type: 3}
dcMotorModulePrefab: {fileID: 7364692261245862742, guid: 6ffe98828f23843f4814a5dc44baaf85, type: 3} dcMotorModulePrefab: {fileID: 7364692261245862742, guid: 6ffe98828f23843f4814a5dc44baaf85, type: 3}
servoBendModulePrefab: {fileID: 2587764185522029205, guid: 5c6ff9c85cb0b4e54a56a4714e2245e7, type: 3} servoBendModulePrefab: {fileID: 2587764185522029205, guid: 5c6ff9c85cb0b4e54a56a4714e2245e7, type: 3}
@@ -8768,6 +8652,7 @@ MonoBehaviour:
displayModulePrefab: {fileID: 9087040773434933035, guid: 1d13960332e6840458c2d63f616e2774, type: 3} displayModulePrefab: {fileID: 9087040773434933035, guid: 1d13960332e6840458c2d63f616e2774, type: 3}
distanceSensorModulePrefab: {fileID: 4820635649742989172, guid: 71a1ec0b30283422eafea6e72a83d947, type: 3} distanceSensorModulePrefab: {fileID: 4820635649742989172, guid: 71a1ec0b30283422eafea6e72a83d947, type: 3}
imuSensorModulePrefab: {fileID: 7670757311786442011, guid: 78f1dcd3d1ad14720bec24368d935b13, type: 3} imuSensorModulePrefab: {fileID: 7670757311786442011, guid: 78f1dcd3d1ad14720bec24368d935b13, type: 3}
speakerModulePrefab: {fileID: 7364806464279017071, guid: 8bcdcbcb5a03245248cb7f883e80d948, type: 3}
--- !u!4 &2021810912 --- !u!4 &2021810912
Transform: Transform:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0

69
Assets/SpeakerModule.cs Normal file
View File

@@ -0,0 +1,69 @@
using System;
using System.IO;
using UnityEngine;
public class SpeakerModule : ModuleBase
{
[Header("Selected Audio")]
public string audioFilePath = "";
public string audioFileName = "";
public byte[] audioBytes;
// Called by UI after user picks a file
public void SetAudioFile(string path)
{
if (string.IsNullOrEmpty(path) || !File.Exists(path))
{
Debug.LogWarning("[SpeakerModule] Invalid audio file path.");
ClearAudio();
return;
}
audioFilePath = path;
audioFileName = Path.GetFileName(path);
try
{
audioBytes = File.ReadAllBytes(path);
Debug.Log($"[SpeakerModule] Loaded audio file: {audioFileName} ({audioBytes.Length} bytes)");
}
catch (Exception e)
{
Debug.LogError($"[SpeakerModule] Failed to read audio file: {e.Message}");
ClearAudio();
}
}
// Called by UI when user presses the shared Send button
public void SendAudioToHardware()
{
if (audioBytes == null || audioBytes.Length == 0)
{
Debug.LogWarning("[SpeakerModule] No audio selected to send.");
return;
}
// TODO: replace with your real control library call
Debug.Log($"[SpeakerModule] Sending audio '{audioFileName}' ({audioBytes.Length} bytes) to hardware");
// Example:
// ControlLibrary.send_speaker_audio(Int32.Parse(moduleID), audioBytes, audioBytes.Length);
// or chunk it if your library requires.
}
public void PlayAudioOnHardware()
{
// TODO: Replace with your real ControlLibrary call
// Example:
// ControlLibrary.speaker_play(Int32.Parse(moduleID));
Debug.Log($"[SpeakerModule] Play requested on hardware for '{audioFileName}'.");
}
private void ClearAudio()
{
audioFilePath = "";
audioFileName = "";
audioBytes = null;
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 20afe4b54fe7b42cb97881ff62dd6797

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 57e25b4a578dba94c9353f4633b20549
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,13 @@
using System;
namespace SFB {
public interface IStandaloneFileBrowser {
string[] OpenFilePanel(string title, string directory, ExtensionFilter[] extensions, bool multiselect);
string[] OpenFolderPanel(string title, string directory, bool multiselect);
string SaveFilePanel(string title, string directory, string defaultName, ExtensionFilter[] extensions);
void OpenFilePanelAsync(string title, string directory, ExtensionFilter[] extensions, bool multiselect, Action<string[]> cb);
void OpenFolderPanelAsync(string title, string directory, bool multiselect, Action<string[]> cb);
void SaveFilePanelAsync(string title, string directory, string defaultName, ExtensionFilter[] extensions, Action<string> cb);
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 7609f7b6787a54496aa41a3053fcc76a
timeCreated: 1483902788
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: ddc4e7b83981f244ba9a26b88c18cb67
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 82666e520ab4d4cf08bebbb8059cd6f4
folderAsset: yes
timeCreated: 1538224809
licenseType: Free
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: bd198408642944765b9305bd99404136
folderAsset: yes
timeCreated: 1538230728
licenseType: Free
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,126 @@
fileFormatVersion: 2
guid: b8c465928f1784a3fac8dc3766f7201c
timeCreated: 1538230728
licenseType: Free
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
isPreloaded: 0
isOverridable: 0
platformData:
- first:
'': Any
second:
enabled: 0
settings:
Exclude Android: 1
Exclude Editor: 0
Exclude Linux: 1
Exclude Linux64: 0
Exclude LinuxUniversal: 0
Exclude OSXIntel: 1
Exclude OSXIntel64: 1
Exclude OSXUniversal: 1
Exclude SamsungTV: 1
Exclude Tizen: 1
Exclude WebGL: 1
Exclude Win: 0
Exclude Win64: 0
Exclude iOS: 1
- first:
Android: Android
second:
enabled: 0
settings:
CPU: ARMv7
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 1
settings:
CPU: x86_64
DefaultValueInitialized: true
OS: Linux
- first:
Facebook: Win
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Facebook: Win64
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Samsung TV: SamsungTV
second:
enabled: 0
settings:
STV_MODEL: STANDARD_15
- first:
Standalone: Linux
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: Linux64
second:
enabled: 1
settings:
CPU: x86_64
- first:
Standalone: LinuxUniversal
second:
enabled: 1
settings:
CPU: x86_64
- first:
Standalone: OSXIntel
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: OSXIntel64
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: OSXUniversal
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: Win
second:
enabled: 1
settings:
CPU: AnyCPU
- first:
Standalone: Win64
second:
enabled: 1
settings:
CPU: AnyCPU
- first:
iPhone: iOS
second:
enabled: 0
settings:
CompileFlags:
FrameworkDependencies:
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

View File

@@ -0,0 +1,145 @@
fileFormatVersion: 2
guid: e60958662eed5413d86143a0a69b731e
timeCreated: 1491979494
licenseType: Pro
PluginImporter:
serializedVersion: 2
iconMap: {}
executionOrder: {}
isPreloaded: 0
isOverridable: 0
platformData:
data:
first:
'': Any
second:
enabled: 0
settings:
Exclude Android: 1
Exclude Editor: 0
Exclude Linux: 1
Exclude Linux64: 1
Exclude LinuxUniversal: 1
Exclude OSXIntel: 1
Exclude OSXIntel64: 1
Exclude OSXUniversal: 1
Exclude WebGL: 1
Exclude Win: 0
Exclude Win64: 0
Exclude iOS: 1
data:
first:
'': Editor
second:
enabled: 0
settings:
CPU: AnyCPU
OS: AnyOS
data:
first:
Android: Android
second:
enabled: 0
settings:
CPU: ARMv7
data:
first:
Any:
second:
enabled: 0
settings: {}
data:
first:
Editor: Editor
second:
enabled: 1
settings:
DefaultValueInitialized: true
data:
first:
Facebook: Win
second:
enabled: 0
settings:
CPU: AnyCPU
data:
first:
Facebook: Win64
second:
enabled: 0
settings:
CPU: AnyCPU
data:
first:
Standalone: Linux
second:
enabled: 0
settings:
CPU: None
data:
first:
Standalone: Linux64
second:
enabled: 0
settings:
CPU: None
data:
first:
Standalone: LinuxUniversal
second:
enabled: 0
settings:
CPU: None
data:
first:
Standalone: OSXIntel
second:
enabled: 0
settings:
CPU: None
data:
first:
Standalone: OSXIntel64
second:
enabled: 0
settings:
CPU: None
data:
first:
Standalone: OSXUniversal
second:
enabled: 0
settings:
CPU: None
data:
first:
Standalone: Win
second:
enabled: 1
settings:
CPU: AnyCPU
data:
first:
Standalone: Win64
second:
enabled: 1
settings:
CPU: AnyCPU
data:
first:
Windows Store Apps: WindowsStoreApps
second:
enabled: 0
settings:
CPU: AnyCPU
data:
first:
iPhone: iOS
second:
enabled: 0
settings:
CompileFlags:
FrameworkDependencies:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,40 @@
fileFormatVersion: 2
guid: 110fdfb459db4fc448a2ccd37e200fa4
folderAsset: yes
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
isPreloaded: 0
isOverridable: 0
platformData:
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 1
settings:
DefaultValueInitialized: true
- first:
Standalone: OSXIntel
second:
enabled: 1
settings: {}
- first:
Standalone: OSXIntel64
second:
enabled: 1
settings: {}
- first:
Standalone: OSXUniversal
second:
enabled: 1
settings: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 996ea0b0fb9804844ba9595686ee3e7a
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>BuildMachineOSBuild</key>
<string>18A391</string>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>StandaloneFileBrowser</string>
<key>CFBundleIdentifier</key>
<string>com.gkngkc.sfb</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>StandaloneFileBrowser</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>1.0 </string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleSupportedPlatforms</key>
<array>
<string>MacOSX</string>
</array>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>CSResourcesFileMapped</key>
<true/>
<key>DTCompiler</key>
<string>com.apple.compilers.llvm.clang.1_0</string>
<key>DTPlatformBuild</key>
<string>10A255</string>
<key>DTPlatformVersion</key>
<string>GM</string>
<key>DTSDKBuild</key>
<string>18A384</string>
<key>DTSDKName</key>
<string>macosx10.14</string>
<key>DTXcode</key>
<string>1000</string>
<key>DTXcodeBuild</key>
<string>10A255</string>
</dict>
</plist>

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: a5a66f5db020f344c9327188aec2c060
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,90 @@
var StandaloneFileBrowserWebGLPlugin = {
// Open file.
// gameObjectNamePtr: Unique GameObject name. Required for calling back unity with SendMessage.
// methodNamePtr: Callback method name on given GameObject.
// filter: Filter files. Example filters:
// Match all image files: "image/*"
// Match all video files: "video/*"
// Match all audio files: "audio/*"
// Custom: ".plist, .xml, .yaml"
// multiselect: Allows multiple file selection
UploadFile: function(gameObjectNamePtr, methodNamePtr, filterPtr, multiselect) {
gameObjectName = Pointer_stringify(gameObjectNamePtr);
methodName = Pointer_stringify(methodNamePtr);
filter = Pointer_stringify(filterPtr);
// Delete if element exist
var fileInput = document.getElementById(gameObjectName)
if (fileInput) {
document.body.removeChild(fileInput);
}
fileInput = document.createElement('input');
fileInput.setAttribute('id', gameObjectName);
fileInput.setAttribute('type', 'file');
fileInput.setAttribute('style','display:none;');
fileInput.setAttribute('style','visibility:hidden;');
if (multiselect) {
fileInput.setAttribute('multiple', '');
}
if (filter) {
fileInput.setAttribute('accept', filter);
}
fileInput.onclick = function (event) {
// File dialog opened
this.value = null;
};
fileInput.onchange = function (event) {
// multiselect works
var urls = [];
for (var i = 0; i < event.target.files.length; i++) {
urls.push(URL.createObjectURL(event.target.files[i]));
}
// File selected
SendMessage(gameObjectName, methodName, urls.join());
// Remove after file selected
document.body.removeChild(fileInput);
}
document.body.appendChild(fileInput);
document.onmouseup = function() {
fileInput.click();
document.onmouseup = null;
}
},
// Save file
// DownloadFile method does not open SaveFileDialog like standalone builds, its just allows user to download file
// gameObjectNamePtr: Unique GameObject name. Required for calling back unity with SendMessage.
// methodNamePtr: Callback method name on given GameObject.
// filenamePtr: Filename with extension
// byteArray: byte[]
// byteArraySize: byte[].Length
DownloadFile: function(gameObjectNamePtr, methodNamePtr, filenamePtr, byteArray, byteArraySize) {
gameObjectName = Pointer_stringify(gameObjectNamePtr);
methodName = Pointer_stringify(methodNamePtr);
filename = Pointer_stringify(filenamePtr);
var bytes = new Uint8Array(byteArraySize);
for (var i = 0; i < byteArraySize; i++) {
bytes[i] = HEAPU8[byteArray + i];
}
var downloader = window.document.createElement('a');
downloader.setAttribute('id', gameObjectName);
downloader.href = window.URL.createObjectURL(new Blob([bytes], { type: 'application/octet-stream' }));
downloader.download = filename;
document.body.appendChild(downloader);
document.onmouseup = function() {
downloader.click();
document.body.removeChild(downloader);
document.onmouseup = null;
SendMessage(gameObjectName, methodName);
}
}
};
mergeInto(LibraryManager.library, StandaloneFileBrowserWebGLPlugin);

View File

@@ -0,0 +1,96 @@
fileFormatVersion: 2
guid: 265aaf20a6d564e0fb00a9c4a7a9c300
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
isPreloaded: 0
isOverridable: 0
platformData:
- first:
'': Any
second:
enabled: 0
settings:
Exclude Editor: 1
Exclude Linux: 1
Exclude Linux64: 1
Exclude LinuxUniversal: 1
Exclude OSXUniversal: 1
Exclude Win: 1
Exclude Win64: 1
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
CPU: AnyCPU
DefaultValueInitialized: true
OS: AnyOS
- first:
Facebook: WebGL
second:
enabled: 1
settings: {}
- first:
Facebook: Win
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Facebook: Win64
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Standalone: Linux
second:
enabled: 0
settings:
CPU: x86
- first:
Standalone: Linux64
second:
enabled: 0
settings:
CPU: x86_64
- first:
Standalone: LinuxUniversal
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: OSXUniversal
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Standalone: Win
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Standalone: Win64
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
WebGL: WebGL
second:
enabled: 1
settings: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,145 @@
fileFormatVersion: 2
guid: 7d459a96865cc4aaab657012c6dc4833
timeCreated: 1491979494
licenseType: Pro
PluginImporter:
serializedVersion: 2
iconMap: {}
executionOrder: {}
isPreloaded: 0
isOverridable: 0
platformData:
data:
first:
'': Any
second:
enabled: 0
settings:
Exclude Android: 1
Exclude Editor: 0
Exclude Linux: 1
Exclude Linux64: 1
Exclude LinuxUniversal: 1
Exclude OSXIntel: 1
Exclude OSXIntel64: 1
Exclude OSXUniversal: 1
Exclude WebGL: 1
Exclude Win: 0
Exclude Win64: 0
Exclude iOS: 1
data:
first:
'': Editor
second:
enabled: 0
settings:
CPU: AnyCPU
OS: AnyOS
data:
first:
Android: Android
second:
enabled: 0
settings:
CPU: ARMv7
data:
first:
Any:
second:
enabled: 0
settings: {}
data:
first:
Editor: Editor
second:
enabled: 1
settings:
DefaultValueInitialized: true
data:
first:
Facebook: Win
second:
enabled: 0
settings:
CPU: AnyCPU
data:
first:
Facebook: Win64
second:
enabled: 0
settings:
CPU: AnyCPU
data:
first:
Standalone: Linux
second:
enabled: 0
settings:
CPU: None
data:
first:
Standalone: Linux64
second:
enabled: 0
settings:
CPU: None
data:
first:
Standalone: LinuxUniversal
second:
enabled: 0
settings:
CPU: None
data:
first:
Standalone: OSXIntel
second:
enabled: 0
settings:
CPU: None
data:
first:
Standalone: OSXIntel64
second:
enabled: 0
settings:
CPU: None
data:
first:
Standalone: OSXUniversal
second:
enabled: 0
settings:
CPU: None
data:
first:
Standalone: Win
second:
enabled: 1
settings:
CPU: AnyCPU
data:
first:
Standalone: Win64
second:
enabled: 1
settings:
CPU: AnyCPU
data:
first:
Windows Store Apps: WindowsStoreApps
second:
enabled: 0
settings:
CPU: AnyCPU
data:
first:
iPhone: iOS
second:
enabled: 0
settings:
CompileFlags:
FrameworkDependencies:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 435c74f62ab57b448adeeb37cbc0f96b
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,119 @@
using System.Collections;
using UnityEngine;
using SFB;
public class BasicSample : MonoBehaviour {
private string _path;
void OnGUI() {
var guiScale = new Vector3(Screen.width / 800.0f, Screen.height / 600.0f, 1.0f);
GUI.matrix = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, guiScale);
GUILayout.Space(20);
GUILayout.BeginHorizontal();
GUILayout.Space(20);
GUILayout.BeginVertical();
// Open File Samples
if (GUILayout.Button("Open File")) {
WriteResult(StandaloneFileBrowser.OpenFilePanel("Open File", "", "", false));
}
GUILayout.Space(5);
if (GUILayout.Button("Open File Async")) {
StandaloneFileBrowser.OpenFilePanelAsync("Open File", "", "", false, (string[] paths) => { WriteResult(paths); });
}
GUILayout.Space(5);
if (GUILayout.Button("Open File Multiple")) {
WriteResult(StandaloneFileBrowser.OpenFilePanel("Open File", "", "", true));
}
GUILayout.Space(5);
if (GUILayout.Button("Open File Extension")) {
WriteResult(StandaloneFileBrowser.OpenFilePanel("Open File", "", "txt", true));
}
GUILayout.Space(5);
if (GUILayout.Button("Open File Directory")) {
WriteResult(StandaloneFileBrowser.OpenFilePanel("Open File", Application.dataPath, "", true));
}
GUILayout.Space(5);
if (GUILayout.Button("Open File Filter")) {
var extensions = new [] {
new ExtensionFilter("Image Files", "png", "jpg", "jpeg" ),
new ExtensionFilter("Sound Files", "mp3", "wav" ),
new ExtensionFilter("All Files", "*" ),
};
WriteResult(StandaloneFileBrowser.OpenFilePanel("Open File", "", extensions, true));
}
GUILayout.Space(15);
// Open Folder Samples
if (GUILayout.Button("Open Folder")) {
var paths = StandaloneFileBrowser.OpenFolderPanel("Select Folder", "", true);
WriteResult(paths);
}
GUILayout.Space(5);
if (GUILayout.Button("Open Folder Async")) {
StandaloneFileBrowser.OpenFolderPanelAsync("Select Folder", "", true, (string[] paths) => { WriteResult(paths); });
}
GUILayout.Space(5);
if (GUILayout.Button("Open Folder Directory")) {
var paths = StandaloneFileBrowser.OpenFolderPanel("Select Folder", Application.dataPath, true);
WriteResult(paths);
}
GUILayout.Space(15);
// Save File Samples
if (GUILayout.Button("Save File")) {
_path = StandaloneFileBrowser.SaveFilePanel("Save File", "", "", "");
}
GUILayout.Space(5);
if (GUILayout.Button("Save File Async")) {
StandaloneFileBrowser.SaveFilePanelAsync("Save File", "", "", "", (string path) => { WriteResult(path); });
}
GUILayout.Space(5);
if (GUILayout.Button("Save File Default Name")) {
_path = StandaloneFileBrowser.SaveFilePanel("Save File", "", "MySaveFile", "");
}
GUILayout.Space(5);
if (GUILayout.Button("Save File Default Name Ext")) {
_path = StandaloneFileBrowser.SaveFilePanel("Save File", "", "MySaveFile", "dat");
}
GUILayout.Space(5);
if (GUILayout.Button("Save File Directory")) {
_path = StandaloneFileBrowser.SaveFilePanel("Save File", Application.dataPath, "", "");
}
GUILayout.Space(5);
if (GUILayout.Button("Save File Filter")) {
// Multiple save extension filters with more than one extension support.
var extensionList = new [] {
new ExtensionFilter("Binary", "bin"),
new ExtensionFilter("Text", "txt"),
};
_path = StandaloneFileBrowser.SaveFilePanel("Save File", "", "MySaveFile", extensionList);
}
GUILayout.EndVertical();
GUILayout.Space(20);
GUILayout.Label(_path);
GUILayout.EndHorizontal();
}
public void WriteResult(string[] paths) {
if (paths.Length == 0) {
return;
}
_path = "";
foreach (var p in paths) {
_path += p + "\n";
}
}
public void WriteResult(string path) {
_path = path;
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 5148400295519405d82bb0fa65246ea2
timeCreated: 1483902788
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,248 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!29 &1
OcclusionCullingSettings:
m_ObjectHideFlags: 0
serializedVersion: 2
m_OcclusionBakeSettings:
smallestOccluder: 5
smallestHole: 0.25
backfaceThreshold: 100
m_SceneGUID: 00000000000000000000000000000000
m_OcclusionCullingData: {fileID: 0}
--- !u!104 &2
RenderSettings:
m_ObjectHideFlags: 0
serializedVersion: 9
m_Fog: 0
m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1}
m_FogMode: 3
m_FogDensity: 0.01
m_LinearFogStart: 0
m_LinearFogEnd: 300
m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1}
m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1}
m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1}
m_AmbientIntensity: 1
m_AmbientMode: 3
m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1}
m_SkyboxMaterial: {fileID: 0}
m_HaloStrength: 0.5
m_FlareStrength: 1
m_FlareFadeSpeed: 3
m_HaloTexture: {fileID: 0}
m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0}
m_DefaultReflectionMode: 0
m_DefaultReflectionResolution: 128
m_ReflectionBounces: 1
m_ReflectionIntensity: 1
m_CustomReflection: {fileID: 0}
m_Sun: {fileID: 0}
m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1}
m_UseRadianceAmbientProbe: 0
--- !u!157 &3
LightmapSettings:
m_ObjectHideFlags: 0
serializedVersion: 11
m_GIWorkflowMode: 1
m_GISettings:
serializedVersion: 2
m_BounceScale: 1
m_IndirectOutputScale: 1
m_AlbedoBoost: 1
m_TemporalCoherenceThreshold: 1
m_EnvironmentLightingMode: 0
m_EnableBakedLightmaps: 0
m_EnableRealtimeLightmaps: 0
m_LightmapEditorSettings:
serializedVersion: 10
m_Resolution: 2
m_BakeResolution: 40
m_AtlasSize: 1024
m_AO: 0
m_AOMaxDistance: 1
m_CompAOExponent: 1
m_CompAOExponentDirect: 0
m_Padding: 2
m_LightmapParameters: {fileID: 0}
m_LightmapsBakeMode: 1
m_TextureCompression: 1
m_FinalGather: 0
m_FinalGatherFiltering: 1
m_FinalGatherRayCount: 256
m_ReflectionCompression: 2
m_MixedBakeMode: 1
m_BakeBackend: 0
m_PVRSampling: 1
m_PVRDirectSampleCount: 32
m_PVRSampleCount: 500
m_PVRBounces: 2
m_PVRFilterTypeDirect: 0
m_PVRFilterTypeIndirect: 0
m_PVRFilterTypeAO: 0
m_PVRFilteringMode: 0
m_PVRCulling: 1
m_PVRFilteringGaussRadiusDirect: 1
m_PVRFilteringGaussRadiusIndirect: 5
m_PVRFilteringGaussRadiusAO: 2
m_PVRFilteringAtrousPositionSigmaDirect: 0.5
m_PVRFilteringAtrousPositionSigmaIndirect: 2
m_PVRFilteringAtrousPositionSigmaAO: 1
m_ShowResolutionOverlay: 1
m_LightingDataAsset: {fileID: 0}
m_UseShadowmask: 0
--- !u!196 &4
NavMeshSettings:
serializedVersion: 2
m_ObjectHideFlags: 0
m_BuildSettings:
serializedVersion: 2
agentTypeID: 0
agentRadius: 0.5
agentHeight: 2
agentSlope: 45
agentClimb: 0.4
ledgeDropHeight: 0
maxJumpAcrossDistance: 0
minRegionArea: 2
manualCellSize: 0
cellSize: 0.16666667
manualTileSize: 0
tileSize: 256
accuratePlacement: 0
debug:
m_Flags: 0
m_NavMeshData: {fileID: 0}
--- !u!1 &382763637
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 382763642}
- component: {fileID: 382763641}
- component: {fileID: 382763640}
- component: {fileID: 382763639}
- component: {fileID: 382763638}
m_Layer: 0
m_Name: Main Camera
m_TagString: MainCamera
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!81 &382763638
AudioListener:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 382763637}
m_Enabled: 1
--- !u!124 &382763639
Behaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 382763637}
m_Enabled: 1
--- !u!92 &382763640
Behaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 382763637}
m_Enabled: 1
--- !u!20 &382763641
Camera:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 382763637}
m_Enabled: 1
serializedVersion: 2
m_ClearFlags: 1
m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0}
m_projectionMatrixMode: 1
m_SensorSize: {x: 36, y: 24}
m_LensShift: {x: 0, y: 0}
m_FocalLength: 50
m_NormalizedViewPortRect:
serializedVersion: 2
x: 0
y: 0
width: 1
height: 1
near clip plane: 0.3
far clip plane: 1000
field of view: 60
orthographic: 1
orthographic size: 5
m_Depth: -1
m_CullingMask:
serializedVersion: 2
m_Bits: 4294967295
m_RenderingPath: -1
m_TargetTexture: {fileID: 0}
m_TargetDisplay: 0
m_TargetEye: 3
m_HDR: 0
m_AllowMSAA: 1
m_AllowDynamicResolution: 0
m_ForceIntoRT: 0
m_OcclusionCulling: 1
m_StereoConvergence: 10
m_StereoSeparation: 0.022
--- !u!4 &382763642
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 382763637}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: -10}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &986049433
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 986049435}
- component: {fileID: 986049434}
m_Layer: 0
m_Name: GameObject
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &986049434
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 986049433}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 5148400295519405d82bb0fa65246ea2, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!4 &986049435
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 986049433}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: d97280fe82b874466870f709c3315d41
timeCreated: 1483902786
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,53 @@
using System.Text;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using SFB;
[RequireComponent(typeof(Button))]
public class CanvasSampleOpenFileImage : MonoBehaviour, IPointerDownHandler {
public RawImage output;
#if UNITY_WEBGL && !UNITY_EDITOR
//
// WebGL
//
[DllImport("__Internal")]
private static extern void UploadFile(string gameObjectName, string methodName, string filter, bool multiple);
public void OnPointerDown(PointerEventData eventData) {
UploadFile(gameObject.name, "OnFileUpload", ".png, .jpg", false);
}
// Called from browser
public void OnFileUpload(string url) {
StartCoroutine(OutputRoutine(url));
}
#else
//
// Standalone platforms & editor
//
public void OnPointerDown(PointerEventData eventData) { }
void Start() {
var button = GetComponent<Button>();
button.onClick.AddListener(OnClick);
}
private void OnClick() {
var paths = StandaloneFileBrowser.OpenFilePanel("Title", "", ".png", false);
if (paths.Length > 0) {
StartCoroutine(OutputRoutine(new System.Uri(paths[0]).AbsoluteUri));
}
}
#endif
private IEnumerator OutputRoutine(string url) {
var loader = new WWW(url);
yield return loader;
output.texture = loader.texture;
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 331c95b7bf39e4792acecff50a972040
timeCreated: 1489946149
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,53 @@
using System.Text;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using SFB;
[RequireComponent(typeof(Button))]
public class CanvasSampleOpenFileText : MonoBehaviour, IPointerDownHandler {
public Text output;
#if UNITY_WEBGL && !UNITY_EDITOR
//
// WebGL
//
[DllImport("__Internal")]
private static extern void UploadFile(string gameObjectName, string methodName, string filter, bool multiple);
public void OnPointerDown(PointerEventData eventData) {
UploadFile(gameObject.name, "OnFileUpload", ".txt", false);
}
// Called from browser
public void OnFileUpload(string url) {
StartCoroutine(OutputRoutine(url));
}
#else
//
// Standalone platforms & editor
//
public void OnPointerDown(PointerEventData eventData) { }
void Start() {
var button = GetComponent<Button>();
button.onClick.AddListener(OnClick);
}
private void OnClick() {
var paths = StandaloneFileBrowser.OpenFilePanel("Title", "", "txt", false);
if (paths.Length > 0) {
StartCoroutine(OutputRoutine(new System.Uri(paths[0]).AbsoluteUri));
}
}
#endif
private IEnumerator OutputRoutine(string url) {
var loader = new WWW(url);
yield return loader;
output.text = loader.text;
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 99a65d6437df64949b37cba4eadc67a2
timeCreated: 1489946149
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,62 @@
using System.Text;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using SFB;
[RequireComponent(typeof(Button))]
public class CanvasSampleOpenFileTextMultiple : MonoBehaviour, IPointerDownHandler {
public Text output;
#if UNITY_WEBGL && !UNITY_EDITOR
//
// WebGL
//
[DllImport("__Internal")]
private static extern void UploadFile(string gameObjectName, string methodName, string filter, bool multiple);
public void OnPointerDown(PointerEventData eventData) {
UploadFile(gameObject.name, "OnFileUpload", ".txt", true);
}
// Called from browser
public void OnFileUpload(string urls) {
StartCoroutine(OutputRoutine(urls.Split(',')));
}
#else
//
// Standalone platforms & editor
//
public void OnPointerDown(PointerEventData eventData) { }
void Start() {
var button = GetComponent<Button>();
button.onClick.AddListener(OnClick);
}
private void OnClick() {
// var paths = StandaloneFileBrowser.OpenFilePanel("Title", "", "txt", true);
var paths = StandaloneFileBrowser.OpenFilePanel("Open File", "", "", true);
if (paths.Length > 0) {
var urlArr = new List<string>(paths.Length);
for (int i = 0; i < paths.Length; i++) {
urlArr.Add(new System.Uri(paths[i]).AbsoluteUri);
}
StartCoroutine(OutputRoutine(urlArr.ToArray()));
}
}
#endif
private IEnumerator OutputRoutine(string[] urlArr) {
var outputText = "";
for (int i = 0; i < urlArr.Length; i++) {
var loader = new WWW(urlArr[i]);
yield return loader;
outputText += loader.text;
}
output.text = outputText;
}
}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: f0d44e50b94d44bf6b87f9db5a07981c guid: 71c09849449d61e47a4599e06b964998
MonoImporter: MonoImporter:
externalObjects: {} externalObjects: {}
serializedVersion: 2 serializedVersion: 2

View File

@@ -0,0 +1,65 @@
using System.IO;
using System.Text;
using System.Runtime.InteropServices;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using SFB;
[RequireComponent(typeof(Button))]
public class CanvasSampleSaveFileImage : MonoBehaviour, IPointerDownHandler {
public Text output;
private byte[] _textureBytes;
void Awake() {
// Create red texture
var width = 100;
var height = 100;
Texture2D tex = new Texture2D(width, height, TextureFormat.RGB24, false);
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
tex.SetPixel(i, j, Color.red);
}
}
tex.Apply();
_textureBytes = tex.EncodeToPNG();
UnityEngine.Object.Destroy(tex);
}
#if UNITY_WEBGL && !UNITY_EDITOR
//
// WebGL
//
[DllImport("__Internal")]
private static extern void DownloadFile(string gameObjectName, string methodName, string filename, byte[] byteArray, int byteArraySize);
// Broser plugin should be called in OnPointerDown.
public void OnPointerDown(PointerEventData eventData) {
DownloadFile(gameObject.name, "OnFileDownload", "sample.png", _textureBytes, _textureBytes.Length);
}
// Called from browser
public void OnFileDownload() {
output.text = "File Successfully Downloaded";
}
#else
//
// Standalone platforms & editor
//
public void OnPointerDown(PointerEventData eventData) { }
// Listen OnClick event in standlone builds
void Start() {
var button = GetComponent<Button>();
button.onClick.AddListener(OnClick);
}
public void OnClick() {
var path = StandaloneFileBrowser.SaveFilePanel("Title", "", "sample", "png");
if (!string.IsNullOrEmpty(path)) {
File.WriteAllBytes(path, _textureBytes);
}
}
#endif
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 6e681018aa67241a69b8447678ec3b4e
timeCreated: 1489946149
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,52 @@
using System.IO;
using System.Text;
using System.Runtime.InteropServices;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using SFB;
[RequireComponent(typeof(Button))]
public class CanvasSampleSaveFileText : MonoBehaviour, IPointerDownHandler {
public Text output;
// Sample text data
private string _data = "Example text created by StandaloneFileBrowser";
#if UNITY_WEBGL && !UNITY_EDITOR
//
// WebGL
//
[DllImport("__Internal")]
private static extern void DownloadFile(string gameObjectName, string methodName, string filename, byte[] byteArray, int byteArraySize);
// Broser plugin should be called in OnPointerDown.
public void OnPointerDown(PointerEventData eventData) {
var bytes = Encoding.UTF8.GetBytes(_data);
DownloadFile(gameObject.name, "OnFileDownload", "sample.txt", bytes, bytes.Length);
}
// Called from browser
public void OnFileDownload() {
output.text = "File Successfully Downloaded";
}
#else
//
// Standalone platforms & editor
//
public void OnPointerDown(PointerEventData eventData) { }
// Listen OnClick event in standlone builds
void Start() {
var button = GetComponent<Button>();
button.onClick.AddListener(OnClick);
}
public void OnClick() {
var path = StandaloneFileBrowser.SaveFilePanel("Title", "", "sample", "txt");
if (!string.IsNullOrEmpty(path)) {
File.WriteAllText(path, _data);
}
}
#endif
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 8e97f52f0bd664ee78305dae0094a755
timeCreated: 1489946149
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: c0e4eec5741834194a946535d535405c
timeCreated: 1483902786
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,153 @@
using System;
namespace SFB {
public struct ExtensionFilter {
public string Name;
public string[] Extensions;
public ExtensionFilter(string filterName, params string[] filterExtensions) {
Name = filterName;
Extensions = filterExtensions;
}
}
public class StandaloneFileBrowser {
private static IStandaloneFileBrowser _platformWrapper = null;
static StandaloneFileBrowser() {
#if UNITY_STANDALONE_OSX
_platformWrapper = new StandaloneFileBrowserMac();
#elif UNITY_STANDALONE_WIN
_platformWrapper = new StandaloneFileBrowserWindows();
#elif UNITY_STANDALONE_LINUX
_platformWrapper = new StandaloneFileBrowserLinux();
#elif UNITY_EDITOR
_platformWrapper = new StandaloneFileBrowserEditor();
#endif
}
/// <summary>
/// Native open file dialog
/// </summary>
/// <param name="title">Dialog title</param>
/// <param name="directory">Root directory</param>
/// <param name="extension">Allowed extension</param>
/// <param name="multiselect">Allow multiple file selection</param>
/// <returns>Returns array of chosen paths. Zero length array when cancelled</returns>
public static string[] OpenFilePanel(string title, string directory, string extension, bool multiselect) {
var extensions = string.IsNullOrEmpty(extension) ? null : new [] { new ExtensionFilter("", extension) };
return OpenFilePanel(title, directory, extensions, multiselect);
}
/// <summary>
/// Native open file dialog
/// </summary>
/// <param name="title">Dialog title</param>
/// <param name="directory">Root directory</param>
/// <param name="extensions">List of extension filters. Filter Example: new ExtensionFilter("Image Files", "jpg", "png")</param>
/// <param name="multiselect">Allow multiple file selection</param>
/// <returns>Returns array of chosen paths. Zero length array when cancelled</returns>
public static string[] OpenFilePanel(string title, string directory, ExtensionFilter[] extensions, bool multiselect) {
return _platformWrapper.OpenFilePanel(title, directory, extensions, multiselect);
}
/// <summary>
/// Native open file dialog async
/// </summary>
/// <param name="title">Dialog title</param>
/// <param name="directory">Root directory</param>
/// <param name="extension">Allowed extension</param>
/// <param name="multiselect">Allow multiple file selection</param>
/// <param name="cb">Callback")</param>
public static void OpenFilePanelAsync(string title, string directory, string extension, bool multiselect, Action<string[]> cb) {
var extensions = string.IsNullOrEmpty(extension) ? null : new [] { new ExtensionFilter("", extension) };
OpenFilePanelAsync(title, directory, extensions, multiselect, cb);
}
/// <summary>
/// Native open file dialog async
/// </summary>
/// <param name="title">Dialog title</param>
/// <param name="directory">Root directory</param>
/// <param name="extensions">List of extension filters. Filter Example: new ExtensionFilter("Image Files", "jpg", "png")</param>
/// <param name="multiselect">Allow multiple file selection</param>
/// <param name="cb">Callback")</param>
public static void OpenFilePanelAsync(string title, string directory, ExtensionFilter[] extensions, bool multiselect, Action<string[]> cb) {
_platformWrapper.OpenFilePanelAsync(title, directory, extensions, multiselect, cb);
}
/// <summary>
/// Native open folder dialog
/// NOTE: Multiple folder selection doesn't supported on Windows
/// </summary>
/// <param name="title"></param>
/// <param name="directory">Root directory</param>
/// <param name="multiselect"></param>
/// <returns>Returns array of chosen paths. Zero length array when cancelled</returns>
public static string[] OpenFolderPanel(string title, string directory, bool multiselect) {
return _platformWrapper.OpenFolderPanel(title, directory, multiselect);
}
/// <summary>
/// Native open folder dialog async
/// NOTE: Multiple folder selection doesn't supported on Windows
/// </summary>
/// <param name="title"></param>
/// <param name="directory">Root directory</param>
/// <param name="multiselect"></param>
/// <param name="cb">Callback")</param>
public static void OpenFolderPanelAsync(string title, string directory, bool multiselect, Action<string[]> cb) {
_platformWrapper.OpenFolderPanelAsync(title, directory, multiselect, cb);
}
/// <summary>
/// Native save file dialog
/// </summary>
/// <param name="title">Dialog title</param>
/// <param name="directory">Root directory</param>
/// <param name="defaultName">Default file name</param>
/// <param name="extension">File extension</param>
/// <returns>Returns chosen path. Empty string when cancelled</returns>
public static string SaveFilePanel(string title, string directory, string defaultName , string extension) {
var extensions = string.IsNullOrEmpty(extension) ? null : new [] { new ExtensionFilter("", extension) };
return SaveFilePanel(title, directory, defaultName, extensions);
}
/// <summary>
/// Native save file dialog
/// </summary>
/// <param name="title">Dialog title</param>
/// <param name="directory">Root directory</param>
/// <param name="defaultName">Default file name</param>
/// <param name="extensions">List of extension filters. Filter Example: new ExtensionFilter("Image Files", "jpg", "png")</param>
/// <returns>Returns chosen path. Empty string when cancelled</returns>
public static string SaveFilePanel(string title, string directory, string defaultName, ExtensionFilter[] extensions) {
return _platformWrapper.SaveFilePanel(title, directory, defaultName, extensions);
}
/// <summary>
/// Native save file dialog async
/// </summary>
/// <param name="title">Dialog title</param>
/// <param name="directory">Root directory</param>
/// <param name="defaultName">Default file name</param>
/// <param name="extension">File extension</param>
/// <param name="cb">Callback")</param>
public static void SaveFilePanelAsync(string title, string directory, string defaultName , string extension, Action<string> cb) {
var extensions = string.IsNullOrEmpty(extension) ? null : new [] { new ExtensionFilter("", extension) };
SaveFilePanelAsync(title, directory, defaultName, extensions, cb);
}
/// <summary>
/// Native save file dialog async
/// </summary>
/// <param name="title">Dialog title</param>
/// <param name="directory">Root directory</param>
/// <param name="defaultName">Default file name</param>
/// <param name="extensions">List of extension filters. Filter Example: new ExtensionFilter("Image Files", "jpg", "png")</param>
/// <param name="cb">Callback")</param>
public static void SaveFilePanelAsync(string title, string directory, string defaultName, ExtensionFilter[] extensions, Action<string> cb) {
_platformWrapper.SaveFilePanelAsync(title, directory, defaultName, extensions, cb);
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 3c708be74128e4ced9b79eaaf80e8443
timeCreated: 1483902788
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,56 @@
#if UNITY_EDITOR
using System;
using UnityEditor;
namespace SFB {
public class StandaloneFileBrowserEditor : IStandaloneFileBrowser {
public string[] OpenFilePanel(string title, string directory, ExtensionFilter[] extensions, bool multiselect) {
string path = "";
if (extensions == null) {
path = EditorUtility.OpenFilePanel(title, directory, "");
}
else {
path = EditorUtility.OpenFilePanelWithFilters(title, directory, GetFilterFromFileExtensionList(extensions));
}
return string.IsNullOrEmpty(path) ? new string[0] : new[] { path };
}
public void OpenFilePanelAsync(string title, string directory, ExtensionFilter[] extensions, bool multiselect, Action<string[]> cb) {
cb.Invoke(OpenFilePanel(title, directory, extensions, multiselect));
}
public string[] OpenFolderPanel(string title, string directory, bool multiselect) {
var path = EditorUtility.OpenFolderPanel(title, directory, "");
return string.IsNullOrEmpty(path) ? new string[0] : new[] {path};
}
public void OpenFolderPanelAsync(string title, string directory, bool multiselect, Action<string[]> cb) {
cb.Invoke(OpenFolderPanel(title, directory, multiselect));
}
public string SaveFilePanel(string title, string directory, string defaultName, ExtensionFilter[] extensions) {
var ext = extensions != null ? extensions[0].Extensions[0] : "";
var name = string.IsNullOrEmpty(ext) ? defaultName : defaultName + "." + ext;
return EditorUtility.SaveFilePanel(title, directory, name, ext);
}
public void SaveFilePanelAsync(string title, string directory, string defaultName, ExtensionFilter[] extensions, Action<string> cb) {
cb.Invoke(SaveFilePanel(title, directory, defaultName, extensions));
}
// EditorUtility.OpenFilePanelWithFilters extension filter format
private static string[] GetFilterFromFileExtensionList(ExtensionFilter[] extensions) {
var filters = new string[extensions.Length * 2];
for (int i = 0; i < extensions.Length; i++) {
filters[(i * 2)] = extensions[i].Name;
filters[(i * 2) + 1] = string.Join(",", extensions[i].Extensions);
}
return filters;
}
}
}
#endif

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 2650af8de2cda46b99b1bc7cf5d30ca5
timeCreated: 1483902788
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,115 @@
#if UNITY_STANDALONE_LINUX
using System;
using System.IO;
using System.Runtime.InteropServices;
using UnityEngine;
namespace SFB {
public class StandaloneFileBrowserLinux : IStandaloneFileBrowser {
private static Action<string[]> _openFileCb;
private static Action<string[]> _openFolderCb;
private static Action<string> _saveFileCb;
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void AsyncCallback(string path);
[DllImport("StandaloneFileBrowser")]
private static extern void DialogInit();
[DllImport("StandaloneFileBrowser")]
private static extern IntPtr DialogOpenFilePanel(string title, string directory, string extension, bool multiselect);
[DllImport("StandaloneFileBrowser")]
private static extern void DialogOpenFilePanelAsync(string title, string directory, string extension, bool multiselect, AsyncCallback callback);
[DllImport("StandaloneFileBrowser")]
private static extern IntPtr DialogOpenFolderPanel(string title, string directory, bool multiselect);
[DllImport("StandaloneFileBrowser")]
private static extern void DialogOpenFolderPanelAsync(string title, string directory, bool multiselect, AsyncCallback callback);
[DllImport("StandaloneFileBrowser")]
private static extern IntPtr DialogSaveFilePanel(string title, string directory, string defaultName, string extension);
[DllImport("StandaloneFileBrowser")]
private static extern void DialogSaveFilePanelAsync(string title, string directory, string defaultName, string extension, AsyncCallback callback);
public StandaloneFileBrowserLinux()
{
DialogInit();
}
public string[] OpenFilePanel(string title, string directory, ExtensionFilter[] extensions, bool multiselect) {
var paths = Marshal.PtrToStringAnsi(DialogOpenFilePanel(
title,
directory,
GetFilterFromFileExtensionList(extensions),
multiselect));
return paths.Split((char)28);
}
public void OpenFilePanelAsync(string title, string directory, ExtensionFilter[] extensions, bool multiselect, Action<string[]> cb) {
_openFileCb = cb;
DialogOpenFilePanelAsync(
title,
directory,
GetFilterFromFileExtensionList(extensions),
multiselect,
(string result) => { _openFileCb.Invoke(result.Split((char)28)); });
}
public string[] OpenFolderPanel(string title, string directory, bool multiselect) {
var paths = Marshal.PtrToStringAnsi(DialogOpenFolderPanel(
title,
directory,
multiselect));
return paths.Split((char)28);
}
public void OpenFolderPanelAsync(string title, string directory, bool multiselect, Action<string[]> cb) {
_openFolderCb = cb;
DialogOpenFolderPanelAsync(
title,
directory,
multiselect,
(string result) => { _openFolderCb.Invoke(result.Split((char)28)); });
}
public string SaveFilePanel(string title, string directory, string defaultName, ExtensionFilter[] extensions) {
return Marshal.PtrToStringAnsi(DialogSaveFilePanel(
title,
directory,
defaultName,
GetFilterFromFileExtensionList(extensions)));
}
public void SaveFilePanelAsync(string title, string directory, string defaultName, ExtensionFilter[] extensions, Action<string> cb) {
_saveFileCb = cb;
DialogSaveFilePanelAsync(
title,
directory,
defaultName,
GetFilterFromFileExtensionList(extensions),
(string result) => { _saveFileCb.Invoke(result); });
}
private static string GetFilterFromFileExtensionList(ExtensionFilter[] extensions) {
if (extensions == null) {
return "";
}
var filterString = "";
foreach (var filter in extensions) {
filterString += filter.Name + ";";
foreach (var ext in filter.Extensions) {
filterString += ext + ",";
}
filterString = filterString.Remove(filterString.Length - 1);
filterString += "|";
}
filterString = filterString.Remove(filterString.Length - 1);
return filterString;
}
}
}
#endif

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 5d3a668018554b8a89c3fe12de72b60c
timeCreated: 1538067919

View File

@@ -0,0 +1,119 @@
#if UNITY_STANDALONE_OSX
using System;
using System.Runtime.InteropServices;
namespace SFB {
public class StandaloneFileBrowserMac : IStandaloneFileBrowser {
private static Action<string[]> _openFileCb;
private static Action<string[]> _openFolderCb;
private static Action<string> _saveFileCb;
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void AsyncCallback(string path);
[AOT.MonoPInvokeCallback(typeof(AsyncCallback))]
private static void openFileCb(string result) {
_openFileCb.Invoke(result.Split((char)28));
}
[AOT.MonoPInvokeCallback(typeof(AsyncCallback))]
private static void openFolderCb(string result) {
_openFolderCb.Invoke(result.Split((char)28));
}
[AOT.MonoPInvokeCallback(typeof(AsyncCallback))]
private static void saveFileCb(string result) {
_saveFileCb.Invoke(result);
}
[DllImport("StandaloneFileBrowser")]
private static extern IntPtr DialogOpenFilePanel(string title, string directory, string extension, bool multiselect);
[DllImport("StandaloneFileBrowser")]
private static extern void DialogOpenFilePanelAsync(string title, string directory, string extension, bool multiselect, AsyncCallback callback);
[DllImport("StandaloneFileBrowser")]
private static extern IntPtr DialogOpenFolderPanel(string title, string directory, bool multiselect);
[DllImport("StandaloneFileBrowser")]
private static extern void DialogOpenFolderPanelAsync(string title, string directory, bool multiselect, AsyncCallback callback);
[DllImport("StandaloneFileBrowser")]
private static extern IntPtr DialogSaveFilePanel(string title, string directory, string defaultName, string extension);
[DllImport("StandaloneFileBrowser")]
private static extern void DialogSaveFilePanelAsync(string title, string directory, string defaultName, string extension, AsyncCallback callback);
public string[] OpenFilePanel(string title, string directory, ExtensionFilter[] extensions, bool multiselect) {
var paths = Marshal.PtrToStringAnsi(DialogOpenFilePanel(
title,
directory,
GetFilterFromFileExtensionList(extensions),
multiselect));
return paths.Split((char)28);
}
public void OpenFilePanelAsync(string title, string directory, ExtensionFilter[] extensions, bool multiselect, Action<string[]> cb) {
_openFileCb = cb;
DialogOpenFilePanelAsync(
title,
directory,
GetFilterFromFileExtensionList(extensions),
multiselect,
openFileCb);
}
public string[] OpenFolderPanel(string title, string directory, bool multiselect) {
var paths = Marshal.PtrToStringAnsi(DialogOpenFolderPanel(
title,
directory,
multiselect));
return paths.Split((char)28);
}
public void OpenFolderPanelAsync(string title, string directory, bool multiselect, Action<string[]> cb) {
_openFolderCb = cb;
DialogOpenFolderPanelAsync(
title,
directory,
multiselect,
openFolderCb);
}
public string SaveFilePanel(string title, string directory, string defaultName, ExtensionFilter[] extensions) {
return Marshal.PtrToStringAnsi(DialogSaveFilePanel(
title,
directory,
defaultName,
GetFilterFromFileExtensionList(extensions)));
}
public void SaveFilePanelAsync(string title, string directory, string defaultName, ExtensionFilter[] extensions, Action<string> cb) {
_saveFileCb = cb;
DialogSaveFilePanelAsync(
title,
directory,
defaultName,
GetFilterFromFileExtensionList(extensions),
saveFileCb);
}
private static string GetFilterFromFileExtensionList(ExtensionFilter[] extensions) {
if (extensions == null) {
return "";
}
var filterString = "";
foreach (var filter in extensions) {
filterString += filter.Name + ";";
foreach (var ext in filter.Extensions) {
filterString += ext + ",";
}
filterString = filterString.Remove(filterString.Length - 1);
filterString += "|";
}
filterString = filterString.Remove(filterString.Length - 1);
return filterString;
}
}
}
#endif

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: bcb49ddb0ed5644fda9c3b055cafa27a
timeCreated: 1483902788
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,137 @@
#if UNITY_STANDALONE_WIN
using System;
using System.IO;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using Ookii.Dialogs;
namespace SFB {
// For fullscreen support
// - WindowWrapper class and GetActiveWindow() are required for modal file dialog.
// - "PlayerSettings/Visible In Background" should be enabled, otherwise when file dialog opened app window minimizes automatically.
public class WindowWrapper : IWin32Window {
private IntPtr _hwnd;
public WindowWrapper(IntPtr handle) { _hwnd = handle; }
public IntPtr Handle { get { return _hwnd; } }
}
public class StandaloneFileBrowserWindows : IStandaloneFileBrowser {
[DllImport("user32.dll")]
private static extern IntPtr GetActiveWindow();
public string[] OpenFilePanel(string title, string directory, ExtensionFilter[] extensions, bool multiselect) {
var fd = new VistaOpenFileDialog();
fd.Title = title;
if (extensions != null) {
fd.Filter = GetFilterFromFileExtensionList(extensions);
fd.FilterIndex = 1;
}
else {
fd.Filter = string.Empty;
}
fd.Multiselect = multiselect;
if (!string.IsNullOrEmpty(directory)) {
fd.FileName = GetDirectoryPath(directory);
}
var res = fd.ShowDialog(new WindowWrapper(GetActiveWindow()));
var filenames = res == DialogResult.OK ? fd.FileNames : new string[0];
fd.Dispose();
return filenames;
}
public void OpenFilePanelAsync(string title, string directory, ExtensionFilter[] extensions, bool multiselect, Action<string[]> cb) {
cb.Invoke(OpenFilePanel(title, directory, extensions, multiselect));
}
public string[] OpenFolderPanel(string title, string directory, bool multiselect) {
var fd = new VistaFolderBrowserDialog();
fd.Description = title;
if (!string.IsNullOrEmpty(directory)) {
fd.SelectedPath = GetDirectoryPath(directory);
}
var res = fd.ShowDialog(new WindowWrapper(GetActiveWindow()));
var filenames = res == DialogResult.OK ? new []{ fd.SelectedPath } : new string[0];
fd.Dispose();
return filenames;
}
public void OpenFolderPanelAsync(string title, string directory, bool multiselect, Action<string[]> cb) {
cb.Invoke(OpenFolderPanel(title, directory, multiselect));
}
public string SaveFilePanel(string title, string directory, string defaultName, ExtensionFilter[] extensions) {
var fd = new VistaSaveFileDialog();
fd.Title = title;
var finalFilename = "";
if (!string.IsNullOrEmpty(directory)) {
finalFilename = GetDirectoryPath(directory);
}
if (!string.IsNullOrEmpty(defaultName)) {
finalFilename += defaultName;
}
fd.FileName = finalFilename;
if (extensions != null) {
fd.Filter = GetFilterFromFileExtensionList(extensions);
fd.FilterIndex = 1;
fd.DefaultExt = extensions[0].Extensions[0];
fd.AddExtension = true;
}
else {
fd.DefaultExt = string.Empty;
fd.Filter = string.Empty;
fd.AddExtension = false;
}
var res = fd.ShowDialog(new WindowWrapper(GetActiveWindow()));
var filename = res == DialogResult.OK ? fd.FileName : "";
fd.Dispose();
return filename;
}
public void SaveFilePanelAsync(string title, string directory, string defaultName, ExtensionFilter[] extensions, Action<string> cb) {
cb.Invoke(SaveFilePanel(title, directory, defaultName, extensions));
}
// .NET Framework FileDialog Filter format
// https://msdn.microsoft.com/en-us/library/microsoft.win32.filedialog.filter
private static string GetFilterFromFileExtensionList(ExtensionFilter[] extensions) {
var filterString = "";
foreach (var filter in extensions) {
filterString += filter.Name + "(";
foreach (var ext in filter.Extensions) {
filterString += "*." + ext + ",";
}
filterString = filterString.Remove(filterString.Length - 1);
filterString += ") |";
foreach (var ext in filter.Extensions) {
filterString += "*." + ext + "; ";
}
filterString += "|";
}
filterString = filterString.Remove(filterString.Length - 1);
return filterString;
}
private static string GetDirectoryPath(string directory) {
var directoryPath = Path.GetFullPath(directory);
if (!directoryPath.EndsWith("\\")) {
directoryPath += "\\";
}
if (Path.GetPathRoot(directoryPath) == directoryPath) {
return directory;
}
return Path.GetDirectoryName(directoryPath) + Path.DirectorySeparatorChar;
}
}
}
#endif

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 194e247414a78461d83ae606c1b96917
timeCreated: 1483902788
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because one or more lines are too long