diff --git a/.vs/MoriBScam/v16/.suo b/.vs/MoriBScam/v16/.suo index 67cd4a2..3058842 100644 Binary files a/.vs/MoriBScam/v16/.suo and b/.vs/MoriBScam/v16/.suo differ diff --git a/.vs/MoriBScam/v16/Server/sqlite3/storage.ide b/.vs/MoriBScam/v16/Server/sqlite3/storage.ide index e7cccaa..02f711e 100644 Binary files a/.vs/MoriBScam/v16/Server/sqlite3/storage.ide and b/.vs/MoriBScam/v16/Server/sqlite3/storage.ide differ diff --git a/.vs/MoriBScam/v16/Server/sqlite3/storage.ide-shm b/.vs/MoriBScam/v16/Server/sqlite3/storage.ide-shm index fe9ac28..f86cc1f 100644 Binary files a/.vs/MoriBScam/v16/Server/sqlite3/storage.ide-shm and b/.vs/MoriBScam/v16/Server/sqlite3/storage.ide-shm differ diff --git a/.vs/MoriBScam/v16/Server/sqlite3/storage.ide-wal b/.vs/MoriBScam/v16/Server/sqlite3/storage.ide-wal index 8140660..f726cce 100644 Binary files a/.vs/MoriBScam/v16/Server/sqlite3/storage.ide-wal and b/.vs/MoriBScam/v16/Server/sqlite3/storage.ide-wal differ diff --git a/.vs/ProjectSettings.json b/.vs/ProjectSettings.json new file mode 100644 index 0000000..f8b4888 --- /dev/null +++ b/.vs/ProjectSettings.json @@ -0,0 +1,3 @@ +{ + "CurrentProjectSetting": null +} \ No newline at end of file diff --git a/.vs/VSWorkspaceState.json b/.vs/VSWorkspaceState.json new file mode 100644 index 0000000..8357d75 --- /dev/null +++ b/.vs/VSWorkspaceState.json @@ -0,0 +1,7 @@ +{ + "ExpandedNodes": [ + "" + ], + "SelectedNode": "\\MonoBehaviors.cs", + "PreviewInSolutionExplorer": false +} \ No newline at end of file diff --git a/.vs/slnx.sqlite b/.vs/slnx.sqlite new file mode 100644 index 0000000..aae18d9 Binary files /dev/null and b/.vs/slnx.sqlite differ diff --git a/.vs/tasks.vs.json b/.vs/tasks.vs.json new file mode 100644 index 0000000..09546ee --- /dev/null +++ b/.vs/tasks.vs.json @@ -0,0 +1,10 @@ +{ + "version": "0.2.1", + "tasks": [ + { + "taskLabel": "task-BeatSaberAutoCamera", + "appliesTo": "BeatSaberAutoCamera.cs", + "type": "launch" + } + ] +} \ No newline at end of file diff --git a/BeatSaberAutoCamera.cs b/BeatSaberAutoCamera.cs new file mode 100644 index 0000000..7b9acb1 --- /dev/null +++ b/BeatSaberAutoCamera.cs @@ -0,0 +1,159 @@ +using System; +using System.Collections.Generic; +using System.IO; +using UnityEngine; +using MorichalionStuff; + +public class MoriBeatSaberCameraSettings : IPluginSettings +{ + +} +public partial class MoriBeatSaberCamera : IPluginCameraBehaviour +{ + MoriBeatSaberCameraSettings _settings = new MoriBeatSaberCameraSettings(); + + public string ID => "MoriBeatSaberKam"; + public string name => "Mori's Beat Saber Cam v0.1.0"; + public string author => "Morichalion"; + public string version => "0.1.0"; + + public IPluginSettings settings => _settings; + + public event EventHandler ApplySettings; + private BeatSaberStatus BS; + PluginCameraHelper _helper; + + + //overlay stuff + private bool overlayactive = true; + private GameObject overlay; + public float overlayScale = .5f; + public float overlayOffsetX = -.5f; + public float overlayOffsetY = -.3f; + OverlayController overlayCon; + + // + RigCam rig; + menuCam men; + + + public void OnActivate(PluginCameraHelper helper) { + _helper = helper;//got my cam stuff. + BS = new BeatSaberStatus(); + if (overlayactive==true) + { + try + { + //getting my overlay + string assetPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); + string dp = System.IO.Path.Combine(assetPath, @"LIV\Plugins\CameraBehaviours\MoriBScam\overlay.yap"); + AssetBundle myasset = AssetBundle.LoadFromFile(dp); + + var prefab = myasset.LoadAsset("Overlay"); + myasset.Unload(false); + Transform c = _helper.manager.camera.worldCamera.transform; + overlay = UnityEngine.Object.Instantiate(prefab); + overlay.transform.parent = c; + overlay.transform.localPosition = new Vector3((overlayOffsetX+0.0f),(overlayOffsetY +.05f),(1.0f)); + float sc = overlayScale * 0.1f; + overlay.transform.localScale = new Vector3(sc, sc, sc); + overlay.transform.rotation = c.rotation; + overlay.transform.Rotate(-90.0f, 0f, 0f); + overlayCon = overlay.AddComponent(); + overlayCon._helper = helper; + overlayCon.position = overlay.transform.localPosition; + overlayCon.scale = overlay.transform.localScale; + overlayCon.BS = BS; + //overlay.SetActive(false); + + } + catch + { + debug("couldn't instantiate overlay"); + overlayactive = false; + } + } + rig = new RigCam(); + rig.worlCam = helper.manager.camera.worldCamera.transform; + men = new menuCam(); + + men.WorldCam = helper.manager.camera.worldCamera.transform; + } + + public void OnDeactivate() + { + if (overlayactive == true) + { + GameObject.Destroy(overlay); + rig.KillThis(); + BS.shutDown(); + + } + } + + public void OnDestroy() + { + + } + + public void OnFixedUpdate() + { + + } + + public void OnLateUpdate() + { + + } + + public void OnSettingsDeserialized() + { + + } + + public void OnUpdate() + { + + //dump the log from the bs socket. + if (BS.debug.Count > 0) + { + debug(BS.debug[0]); + BS.debug.RemoveAt(0); + } + if(BS.menu == false) + { + camLook = rig.PositionUpdate(_helper); + //Transform a = rig.UpdateCameraWithThis.transform; + //_helper.UpdateCameraPose(a.position, a.rotation); + //camLook = rig.CameraLook.transform.position; + //camPos = rig.UpdateCameraWithThis.transform.position; + } + if(BS.menu == true) + { + men.camLookPos = camLook; + camLook = men.menuCamUpdate(_helper); + + } + } + public Vector3 camLook = new Vector3(); + //public Vector3 camPos = new Vector3(0.0f, 0.0f, 0.0f); + //public Vector3 camLook = new Vector3(0.0f, 0.0f, 0.0f); + + + public string debugLogging = "false"; + public void debug(string str) + { + if (debugLogging == "true") + { + + string docPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); + string settingLoc = System.IO.Path.Combine(docPath, @"LIV\Plugins\CameraBehaviours\MoriBScam\"); + string target = System.IO.Path.Combine(settingLoc, "debug.txt"); + + using (var sw = new System.IO.StreamWriter(target, true)) + { + sw.WriteLine(str); + } + } + } +} diff --git a/BeatSaberStatus.cs b/BeatSaberStatus.cs new file mode 100644 index 0000000..d752a07 --- /dev/null +++ b/BeatSaberStatus.cs @@ -0,0 +1,141 @@ +using System; +using System.Collections.Generic; +using WebSocketSharp; +using Newtonsoft.Json.Linq; +using System.Timers; + +public class BeatSaberStatus +{ + public int score = 0;//CurrentScore + public int currentMaxScore = 0;//currentMaxScore possible + public string rank = "SSS";//Rank + public int combo = 0;//Combo + public bool menu = true;//In-menu? + public string type = "";//game type + public string songName = ""; + + public string cover = "empty"; + + //public List received = new List(); + public List debug = new List(); //debug messages. + private WebSocket ws; + + private static Timer reconnectTimer; + + + public void ScoreUpdate(JToken perf) + { + score = (int)perf["score"]; + currentMaxScore = (int)perf["currentMaxScore"]; + rank = perf["rank"].ToString(); + combo = (int)perf["combo"]; + //debug.Add("Score: " + score + " CurrentMaxScore: " + currentMaxScore + " "); + } + + public BeatSaberStatus() + { + + //the constructor, I think. + ws = new WebSocket("ws://localhost:6557/socket"); + ws.OnOpen += (sender, e) => + { + //socket open. + debug.Add("Should have connected to BS"); + }; + ws.OnMessage += (sender, e) => + { + //debug.Add(e.Data); + + JObject received = JObject.Parse(e.Data); + + + + if (received["event"].ToString() == "songStart") + { + debug.Add("SongStart"); + cover = received["status"]["beatmap"]["songCover"].ToString(); + songName = received["status"]["beatmap"]["songName"].ToString(); + menu = false; + debug.Add("Songname is " +songName); + } + + if ( + received["event"].ToString() == "noteMissed" + || + received["event"].ToString() == "scoreChanged" + ) + { + menu = false; + ScoreUpdate(received["status"]["performance"]); + } + if (received["event"].ToString() == "menu") + { + menu = true; + } + + //received.Add(e.Data); + //message. Just add this to the bottom of the responses list. + }; + ws.OnClose += (sender, e) => + { + debug.Add("Closed"); + //closed + reconnectTimer.Start(); + }; + ws.OnError += (sender, e) => + { + //Some error. + debug.Add(e.Message); + if (e.Message.Contains("OnMessage event")) + { + debug.Add("Beatsaber websocket error: OnMessage event"); + debug.Add("Sender is: " +sender.ToString()); + debug.Add("Verbose error is: " + e.Message.ToString()); + } + else + { + + + if (e.Message.Contains("occurred in closing the connection")) + { + debug.Add("Webwsocket error in closing"); + } + else + { + if (ws.IsAlive) + { + debug.Add("Error wasn't about something closing. So I'm attempting to close it so it can restart"); + ws.CloseAsync(); + } + } + } + }; + + reconnectTimer = new Timer(2000); + reconnectTimer.AutoReset = true; + reconnectTimer.Elapsed += wsConnect; + reconnectTimer.Enabled = true; + + } + + private void wsConnect(Object source, ElapsedEventArgs t) + { + debug.Add("Timer Fired. " + t.SignalTime); + if (ws.IsAlive) + { + debug.Add("IsAlive = true. Should be connected."); + } + else + { + debug.Add("IsAlive = false. Try to connect."); + ws.ConnectAsync(); + reconnectTimer.Stop(); + } + } + public void shutDown() + { + reconnectTimer.Dispose(); + ws.CloseAsync(); + + } +} diff --git a/MonoBehaviors.cs b/MonoBehaviors.cs index ecf749b..ba9d234 100644 --- a/MonoBehaviors.cs +++ b/MonoBehaviors.cs @@ -1,78 +1,216 @@ using System; using System.IO; +using System.Collections.Generic; using UnityEngine; //This is going to be a .dll that controls a gameobject that will be instantiated and just "runs forever" namespace MorichalionStuff { public class OverlayController : MonoBehaviour { public PluginCameraHelper _helper; - - Vector3 position;//local, in relation to the ui camera. - Vector3 scale;//local, in relation to the ui camera. + + public Vector3 position;//local, in relation to the ui camera. + public Vector3 scale;//local, in relation to the ui camera. public string SongTitle; - public string coverTexData = ""; public int score = 0; public int maxScore = 0; public float percent = 0.0f; - + + GameObject overIcon; + TextMesh overScore; + TextMesh overRank; + TextMesh overPercent; + TextMesh overTitle; + void Start() { + foreach (Transform t in this.gameObject.GetComponentInChildren(true)) + { + t.gameObject.layer = 10; + string name = t.gameObject.name; + //debug("Changed layer on " + t.gameObject.name); + //define overlay elements that need to be referened later on. + if (name == "Icon") + { + overIcon = t.gameObject; + } + if (name == "Score") + { + overScore = t.gameObject.GetComponent(); + } + if (name == "Rank") + { + overRank = t.gameObject.GetComponent(); + } + if (name == "Percent") + { + overPercent = t.gameObject.GetComponent(); + } + if (name == "Title") + { + overTitle = t.gameObject.GetComponent(); + } + } } public void OnActivate() { - updatepostion = true; - debug("OnActivate in OverlayController fired"); } + public BeatSaberStatus BS; + - public string debugLogging = "false"; - public void debug(string str) + public void Update() { - if (debugLogging == "true") + if (BS.menu == false) { - string docPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); - string settingLoc = Path.Combine(docPath, @"LIV\Plugins\CameraBehaviours\MoriBScam\"); - string target = Path.Combine(settingLoc, "debug.txt"); - - using (var sw = new StreamWriter(target, true)) + this.gameObject.transform.localPosition = position; + //icon update + if (BS.cover != "empty") { - sw.WriteLine(str); + try + { + BS.debug.Add("Should have updated the overlay"); + byte[] bits = Convert.FromBase64String(BS.cover); + Texture2D t = new Texture2D(256, 256); + ImageConversion.LoadImage(t, bits); + MeshRenderer bob = overIcon.GetComponent(); + bob.material.SetTexture("_MainTex", t); + } + catch + { + BS.debug.Add("Failed to update the overlay"); + } + BS.cover = "empty"; } + overScore.text = BS.score.ToString(); + overRank.text = BS.rank; + float percentRaw = (float)BS.score / BS.currentMaxScore; + + string percent = (percentRaw * 100.0f).ToString().Substring(0, 4) + "%"; + overPercent.text = percent; + overTitle.text = BS.songName; + } + if(BS.menu == true) + { + Vector3 moveaway = new Vector3(400f, 440f, 300f); + this.gameObject.transform.position = moveaway; } } - void scoreUpdate(int current, int possible) - { + } - } - private bool updatepostion = false; - public void OnUpdate() + public class RigCam + { + private GameObject RigCamObject; //Center point for the camera rig. + private GameObject FloorReference; //transform on representing the head's directions on the floor. + public GameObject CameraLook; //CameraLook + private List CameraLooks; //List of positions that that coule be assigned to 'CameraPosition' + private Vector3 CameraTargetPosition = new Vector3(0.0f, 0.0f, 0.0f); + private Vector3 CameraTargetPositionVelocity = new Vector3(0.0f, 0.0f, 0.0f); + + private Vector3 RigCamObjectPositionGoal; + private Vector3 RigCamObjectVelocity = new Vector3(0.0f,0.0f,0.0f); + + + private float timeMin = 10.0f; + private float timeMax = 15.0f; + private float waiting = 0.1f; + + public GameObject UpdateCameraWithThis; + public Transform worlCam; + //private Vector3 CameraPosition; //LocalPosition of the camera in relation to the rigCamObject. + public Vector3 PositionUpdate(PluginCameraHelper camhelper) { - if(updatepostion == true) + waiting -= Time.deltaTime; + if (waiting < 0.0f) { - updatepostion = false; - try - { - this.transform.parent = _helper.manager.camera.worldCamera.transform; - this.transform.localPosition = position; - this.transform.rotation = _helper.manager.camera.worldCamera.transform.rotation; - this.transform.Rotate(-90.0f, 0f, 0f); - debug("Should have updated the parent, position, and rotation of the overlay. "); - } - catch (System.Exception bad) - { - debug("Broke bedcause: " + bad.Message.ToString()); - } + waiting += UnityEngine.Random.Range(timeMin, timeMax); + CameraTargetPosition = CameraLooks[UnityEngine.Random.Range(0, CameraLooks.Count)]; } + CameraLook.transform.position = Vector3.SmoothDamp(CameraLook.transform.position, CameraTargetPosition, ref CameraTargetPositionVelocity, 1.5f); + + + + //get floor position of the head. + Vector3 headFloorPoint = new Vector3(camhelper.playerHead.position.x, 0.0f, camhelper.playerHead.position.z); + Vector3 aheaddistance = new Vector3(0.0f, 0.0f, 1.0f); + Vector3 ahead = camhelper.playerHead.TransformPoint(aheaddistance); + ahead = new Vector3(ahead.x, 0.0f, ahead.z);//Directional vector from headfloorpoint. + + FloorReference.transform.position = headFloorPoint; + FloorReference.transform.rotation = Quaternion.LookRotation(ahead - headFloorPoint); + + //update the look point. + + RigCamObject.transform.position = Vector3.SmoothDamp(RigCamObject.transform.position, FloorReference.transform.TransformPoint(RigCamObjectPositionGoal), ref RigCamObjectVelocity, 1.5f); + RigCamObject.transform.rotation = Quaternion.LookRotation(CameraLook.transform.position - RigCamObject.transform.position); + + //orlCam.position = UpdateCameraWithThis.transform.position; + //worlCam.rotation = UpdateCameraWithThis.transform.rotation; + camhelper.UpdateCameraPose(UpdateCameraWithThis.transform.position, UpdateCameraWithThis.transform.rotation); + + + return CameraLook.transform.position; + + } - public void ini(PluginCameraHelper helper, Vector3 pos, Vector3 scal) + public RigCam() { - _helper = helper; - position = pos; - scale = scal; + + //constructor. Makes all the things. + RigCamObject = new GameObject(); + FloorReference = new GameObject(); + CameraLook = new GameObject(); + UpdateCameraWithThis = new GameObject(); + UpdateCameraWithThis.transform.parent = RigCamObject.transform; + UpdateCameraWithThis.transform.localPosition = new Vector3(0.0f, 2.0f, -4.0f); + + RigCamObjectPositionGoal = new Vector3(0.0f, 0.0f, 1.0f); + CameraLooks = new List(); + CameraLooks.Add(new Vector3(2.0f, 0.0f, 4.0f)); + CameraLooks.Add(new Vector3(-2.0f, 0.0f, 4.0f)); + CameraLooks.Add(new Vector3(2.0f, 0.0f, -4.0f)); + CameraLooks.Add(new Vector3(-2.0f, 0.0f, -4.0f)); + } + public void KillThis() + { + GameObject.Destroy(RigCamObject); + GameObject.Destroy(FloorReference); + GameObject.Destroy(CameraLook); + GameObject.Destroy(UpdateCameraWithThis); + + + + } + } + + public class menuCam + { + + //Menu camera Input is the world-camera. Output is smooth-damped coords for the + public Transform WorldCam; + public Vector3 camPos = new Vector3(2.0f,1.8f,-3.0f); + public Vector3 camPosVel = new Vector3(); + public Vector3 camLook = new Vector3(0.0f,1.2f,0.0f); + public Vector3 camLookPos = new Vector3(); + public Vector3 camLookVel = new Vector3(); + public menuCam() + { + + } + public Vector3 menuCamUpdate(PluginCameraHelper helper) + { + + Vector3 pos = Vector3.SmoothDamp(WorldCam.position, camPos, ref camPosVel, .5f); + camLookPos = Vector3.SmoothDamp(camLookPos, camLook, ref camLookVel, .5f); + Quaternion rot = Quaternion.LookRotation(camLookPos - WorldCam.position); + helper.UpdateCameraPose(pos, rot); + + return camLookPos; + } + } } \ No newline at end of file diff --git a/MoriBScam.cs b/MoriBScam.cs index ab2a639..68c431f 100644 --- a/MoriBScam.cs +++ b/MoriBScam.cs @@ -418,33 +418,7 @@ public void OnActivate(PluginCameraHelper helper) { overlay = UnityEngine.Object.Instantiate(prefab); //set layers for each object, assign each to variables in turn. - foreach (Transform t in overlay.GetComponentInChildren(true)) - { - t.gameObject.layer = overlayLayerCur; - string name = t.gameObject.name; - //debug("Changed layer on " + t.gameObject.name); - //define overlay elements that need to be referened later on. - if (name == "Icon") - { - overIcon = t.gameObject; - } - if (name == "Score") - { - overScore = t.gameObject.GetComponent(); - } - if (name == "Rank") - { - overRank = t.gameObject.GetComponent(); - } - if (name == "Percent") - { - overPercent = t.gameObject.GetComponent(); - } - if (name == "Title") - { - overTitle = t.gameObject.GetComponent(); - } - } + debug("Got to end of overlay gen. Camera selection next"); } catch (Exception e) { debug("found it: " + e.Message); } @@ -498,14 +472,16 @@ public void OnActivate(PluginCameraHelper helper) { //debug("Menu mode. Data: " + e.Data); phase = 0; gctype = "menu"; - if(overlayactive == true) { + if(overlayactive == true) + { + - overlayLayerCur = 9; score = "0 "; scorePercent = "100%"; + overlay.SetActive(false); oLay.OnActivate(); - } + } //debug("Should be entering Menu Phase."); @@ -542,10 +518,10 @@ public void OnActivate(PluginCameraHelper helper) { gctype = "follow"; } - }//ScoreChanged event. - if (e.Data.Contains("scoreChanged")) - { - if (overlayactive == true) + }//ScoreChanged event. + if (overlayactive == true) + { + if (e.Data.Contains("scoreChanged")) { //gets score information for the overlay JObject hit = JObject.Parse(e.Data); @@ -561,9 +537,8 @@ public void OnActivate(PluginCameraHelper helper) { //rank rank = hit["status"]["performance"]["rank"].ToString(); } - } - if (overlayactive == true) - { + + if (e.Data.Contains("t\":\"noteCut")) { JObject slice = JObject.Parse(e.Data); @@ -812,7 +787,7 @@ public void OnUpdate() { //overlay stuff. Should only be messed with if it's active. if (overlayactive == true) { - oLay.OnUpdate(); + overPercent.text = scorePercent; overScore.text = "Score: " + score; overRank.text = rank; @@ -911,12 +886,21 @@ public void OnUpdate() { } } ManualSwitcher(); + OnUpdateEnd: ; } + public GameObject olayParent = new GameObject(); // OnLateUpdate is called after OnUpdate also everyframe and has a higher chance that transform updates are more recent. public void OnLateUpdate() { + if (overlayactive == true) + { + olayParent.transform.position = camPosition; + olayParent.transform.rotation = camRotation; + + oLay.OnUpdate(olayParent.transform); + } } // OnDeactivate is called when the user changes the profile to other camera behaviour or when the application is about to close. @@ -1189,7 +1173,8 @@ public void RigCam() Vector3 looky = RigCamFocus.transform.position - RigCamCamera.transform.position; Quaternion rot = Quaternion.LookRotation(looky); - + camPosition = RigCamCamera.transform.position; + camRotation = rot; _helper.UpdateCameraPose(RigCamCamera.transform.position, rot); _helper.UpdateFov(_settings.fov); diff --git a/MoriBScam.csproj b/MoriBScam.csproj index 1909cf8..b1dae06 100644 --- a/MoriBScam.csproj +++ b/MoriBScam.csproj @@ -75,10 +75,10 @@ + + - - diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs index 9d6117b..7882de9 100644 --- a/Properties/AssemblyInfo.cs +++ b/Properties/AssemblyInfo.cs @@ -25,5 +25,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("0.0.21")] -[assembly: AssemblyFileVersion("0.0.21")] +[assembly: AssemblyVersion("0.1.0")] +[assembly: AssemblyFileVersion("0.1.0")] diff --git a/Reebooter.cs b/Reebooter.cs deleted file mode 100644 index d438b3c..0000000 --- a/Reebooter.cs +++ /dev/null @@ -1,129 +0,0 @@ -/* -Copyright 2019 LIV inc. - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software -and associated documentation files (the "Software"), to deal in the Software without restriction, -including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE -OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - - - -using System; -using System.Collections.Generic; -using System.IO; - -using UnityEngine; - - -// User defined settings which will be serialized and deserialized with Newtonsoft Json.Net. -// Only public variables will be serialized. -public class ReebooterSettings : IPluginSettings { - public float fov = 5f; - public float distance = 2f; - public float speed = 1f; - public float bahbah = 1.0f; - public string damnsit = "I dunnot a damnthing if this iz werkin' or not. ><"; -} - -// The class must implement IPluginCameraBehaviour to be recognized by LIV as a plugin. -public class Reebooter : IPluginCameraBehaviour { - - // Store your settings localy so you can access them. - ReebooterSettings _settings = new ReebooterSettings(); - - // Provide your own settings to store user defined settings . - public IPluginSettings settings => _settings; - - - // Invoke ApplySettings event when you need to save your settings. - // Do not invoke event every frame if possible. - public event EventHandler ApplySettings; - - - // ID is used for the camera behaviour identification when the behaviour is selected by the user. - // It has to be unique so there are no plugin collisions. - public string ID => "Reebooter"; - // Readable plugin name "Keep it short". - public string name => "Plugin REEEEBOOOT"; - // Author name. - public string author => "Morichalion"; - // Plugin version. - public string version => "0.0.1"; - // Localy store the camera helper provided by LIV. - PluginCameraHelper _helper; - - - // Constructor is called when plugin loads - public Reebooter() { } - - - - // OnActivate function is called when your camera behaviour was selected by the user. - // The pluginCameraHelper is provided to you to help you with Player/Camera related operations. - - public void OnActivate(PluginCameraHelper helper) { - //local camera helper reference - _helper = helper; - } - - - - // OnSettingsDeserialized is called only when the user has changed camera profile or when the. - // last camera profile has been loaded. This overwrites your settings with last data if they exist. - public void OnSettingsDeserialized() { - - } - - // OnFixedUpdate could be called several times per frame. - // The delta time is constant and it is ment to be used on robust physics simulations. - public void OnFixedUpdate() { - - } - - // OnUpdate is called once every frame and it is used for moving with the camera so it can be smooth as the framerate. - // When you are reading other transform positions during OnUpdate it could be possible that the position comes from a previus frame - // and has not been updated yet. If that is a concern, it is recommended to use OnLateUpdate instead. - public void OnUpdate() { - } - - // OnLateUpdate is called after OnUpdate also everyframe and has a higher chance that transform updates are more recent. - public void OnLateUpdate() { - } - - // OnDeactivate is called when the user changes the profile to other camera behaviour or when the application is about to close. - // The camera behaviour should clean everything it created when the behaviour is deactivated. - public void OnDeactivate() { - // Saving settings here - - ApplySettings?.Invoke(this, EventArgs.Empty); - } - - // OnDestroy is called when the users selects a camera behaviour which is not a plugin or when the application is about to close. - // This is the last chance to clean after your self. - public void OnDestroy() { - - } - public void debug(string str) - { - - string docPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); - string settingLoc = Path.Combine(docPath, @"LIV\Plugins\CameraBehaviours\MoriBScam\"); - string target = Path.Combine(settingLoc, "debug.txt"); - - using (var sw = new StreamWriter(target, true)) - { - sw.WriteLine(str); - } - - } - -} \ No newline at end of file diff --git a/bin/MoriBScam.dll b/bin/MoriBScam.dll new file mode 100644 index 0000000..d1d5174 Binary files /dev/null and b/bin/MoriBScam.dll differ diff --git a/obj/x64/Plugin/MoriBScam.csprojAssemblyReference.cache b/obj/x64/Plugin/MoriBScam.csprojAssemblyReference.cache index 6eb2d33..29989c2 100644 Binary files a/obj/x64/Plugin/MoriBScam.csprojAssemblyReference.cache and b/obj/x64/Plugin/MoriBScam.csprojAssemblyReference.cache differ diff --git a/obj/x64/Plugin/MoriBScam.dll b/obj/x64/Plugin/MoriBScam.dll index 97b14d8..d1d5174 100644 Binary files a/obj/x64/Plugin/MoriBScam.dll and b/obj/x64/Plugin/MoriBScam.dll differ diff --git a/settings.cs b/settings.cs new file mode 100644 index 0000000..390a487 --- /dev/null +++ b/settings.cs @@ -0,0 +1,248 @@ +using System; +using System.Collections.Generic; +using UnityEngine; +using System.IO; +public partial class MoriBeatSaberCamera : IPluginCameraBehaviour +{ + public Vector3 StringToVector3(string str) + { + + //This is going to change the string value from the file into a Vector3 + + string[] a = str.Split('(', ')'); + string[] b = a[1].Split(','); + string[] args = { b[0], b[1], b[2] }; + float[] vals = { 0.0f, 0.0f, 0.0f }; + Vector3 vec; + + try + { + vals[0] = float.Parse(args[0]); + vals[1] = float.Parse(args[1]); + vals[2] = float.Parse(args[2]); + + return vec = new Vector3(vals[0], vals[1], vals[2]); + + } + catch + { + return vec = new Vector3(vals[0], vals[1], vals[2]); + } + /* + foreach (string i in b) + { + debug("Reading someting from ini.txt: " + i); + return null; + } + */ + } + + string ResourceLoc; + public void CheckSettings() + { + + + string docPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); + string settingLoc = Path.Combine(docPath, @"LIV\Plugins\CameraBehaviours\MoriBScam\"); + //create the directory in the off-chance that it doesn't exist. + Directory.CreateDirectory(settingLoc); + ResourceLoc = settingLoc; + + settingLoc = Path.Combine(settingLoc, "ini.txt"); + //Check to see if the file exists + if (File.Exists(@settingLoc)) + { + //reads settings from the file. + try + { + using (StreamReader sr = new StreamReader(@settingLoc)) + { + //apply settings + string line; + List riglookpoints = new List();//temp list to convert to an array for the RigLook array. + + while ((line = sr.ReadLine()) != null) + { + if (line.Contains("RigLook =")) + { + string[] blah = line.Split('='); + riglookpoints.Add(StringToVector3(blah[1])); + } + if (line.Contains("RigCamResponseTime =")) + { + string[] blah = line.Split('='); + RigCamObjectResponsiveness = float.Parse(blah[1]); + } + if (line.Contains("RigCamChangeMin =")) + { + string[] blah = line.Split('='); + RigCamChangeMin = float.Parse(blah[1]); + } + if (line.Contains("RigCamChangeMax =")) + { + string[] blah = line.Split('='); + RigCamChangeMax = float.Parse(blah[1]); + } + + if (line.Contains("MenuCamPosition")) + { + string[] blah = line.Split('='); + MenuCamPosition = StringToVector3(blah[1]); + } + if (line.Contains("MenuCamLook")) + { + string[] blah = line.Split('='); + MenuCamLook = StringToVector3(blah[1]); + } + if (line.Contains("DynCamPosition")) + { + string[] blah = line.Split('='); + DynCamPosition = StringToVector3(blah[1]); + } + if (line.Contains("DynCamLook")) + { + string[] blah = line.Split('='); + DynCamLook = StringToVector3(blah[1]); + } + if (line.Contains("Twitch Oath =")) + { + string[] blah = line.Split('='); + twOath = blah[1].Trim(); + } + if (line.Contains("Twitch Name =")) + { + string[] blah = line.Split('='); + twName = blah[1].Trim(); + } + if (line.Contains("Debug =")) + { + string[] blah = line.Split('='); + debugLogging = blah[1].Trim(); + } + if (line.Contains("FieldOfView =")) + { + //debug("Field of view default is " + _settings.fov.ToString()); + string[] blah = line.Split('='); + _settings.fov = float.Parse(blah[1].Trim()); + //debug("Field of view has been updated to " + _settings.fov.ToString()); + } + if (line.Contains("Overlay =")) + { + if (!line.Contains("no")) + { + overlayactive = true; + + } + else { overlayactive = false; } + } + if (line.Contains("OverlayScale =")) + { + string[] blah = line.Split('='); + try + { + overlayScale = float.Parse(blah[1]); + } + catch + { + debug("Scale didn't parse"); + } + } + if (line.Contains("OverlayOffsetX =")) + { + string[] blah = line.Split('='); + try + { + overlayOffsetX = float.Parse(blah[1]); + } + catch + { + debug("Scale didn't parse"); + } + } + if (line.Contains("OverlayOffsetY =")) + { + string[] blah = line.Split('='); + try + { + overlayOffsetY = float.Parse(blah[1]); + } + catch + { + debug("Scale didn't parse"); + } + } + } + RigCamObjectLookPositions = riglookpoints.ToArray(); + } + } + catch (Exception e) + { + debug(e.Message); + } + } + else + { + //creates the file. + using (var ws = new StreamWriter(@settingLoc)) + { + ws.WriteLine("*Morichalion's Lazy Streamer Beat Saber Camera for LIV Avatars settings."); + ws.WriteLine("*"); + ws.WriteLine("*Field of view. Default is 60."); + ws.WriteLine("FieldOfView = 60"); + ws.WriteLine("*"); + ws.WriteLine("*"); + ws.WriteLine("*Units are in Meters."); + ws.WriteLine("*"); + ws.WriteLine("*Left-Right,Up-Down,Forward-Back"); + ws.WriteLine("*"); + ws.WriteLine("*Menu camera settings. Origin is your playspace center."); + ws.WriteLine("MenuCamPosition = " + MenuCamPosition.ToString()); + ws.WriteLine("MenuCamLook = " + MenuCamLook.ToString()); + ws.WriteLine("*"); + ws.WriteLine("*"); + ws.WriteLine("*Dynamic camera settings. Location and rotation are in relation to your headset."); + ws.WriteLine("DynCamPosition = " + DynCamPosition.ToString()); + ws.WriteLine("DynCamLook = " + DynCamLook.ToString()); + ws.WriteLine("*"); + ws.WriteLine("*"); + ws.WriteLine("**RigCam: Keeps camera at different positions in relation to an object's position and rotation."); + ws.WriteLine("*This setting is for the root of the camera rig. The position is in relation to a player's head on the floor. Default is one meter forward."); + ws.WriteLine("RigCamObjectPosition = " + RigCamObjectPosition.ToString()); + ws.WriteLine("*These are the camera position and the camera target point in relation to the RigCamObjectPosition"); + ws.WriteLine("RigCamPosition = " + RigCamCameraPosition.ToString()); + ws.WriteLine("RigCamCamerFocusPosition = " + RigCamFocusPosition.ToString()); + ws.WriteLine("*The rotation of RigCamObjectPosition is created by looking at one of these points. Just add more lines in the same format if you want more points. "); + //dump all values from an array. + foreach (Vector3 vec in RigCamObjectLookPositions) + { + ws.WriteLine("RigLook = " + vec.ToString()); + } + ws.WriteLine("*Frequency of change in seconds, wait time is random between min and max."); + ws.WriteLine("RigCamChangeMin = " + RigCamChangeMin.ToString()); + ws.WriteLine("RigCamChangeMax = " + RigCamChangeMax.ToString()); + ws.WriteLine("*Speed of camera change time. Make this someting less than RigCamChangeMin*"); + ws.WriteLine("RigCamResponseTime = " + RigCamObjectResponsiveness.ToString()); + + ws.WriteLine("*"); + ws.WriteLine("*"); + ws.WriteLine("**Twitch Login Info, for viewer-controlled cameras**"); + ws.WriteLine("Twitch Oath = " + twOath); + ws.WriteLine("Twitch Name = " + twName); + ws.WriteLine("*"); + ws.WriteLine("*"); + ws.WriteLine("*Overlay. Want it on? yap or no *"); + ws.WriteLine("Overlay = no"); + ws.WriteLine("*"); + ws.WriteLine("*Scale and position stuff for the overlay"); + ws.WriteLine("OverlayScale = 1.0"); + ws.WriteLine("OverlayOffsetX = 0.0"); + ws.WriteLine("OverlayOffsetY = 0.0"); + ws.WriteLine("Debugging on for this plugin? true or false"); + ws.WriteLine("Debug = False"); + + + //Parse.TryParseFloat("0.0"); + } + } + } +}