/// <summary> /// Draw spline on editor /// </summary> private void OnSceneGUI() { _splineMeshRenderer = (SplineMeshRenderer)target; if (_splineMeshRenderer.Spline != null && _splineMeshRenderer.Spline.Theme != null) { Handles.BeginGUI(); if (_splineMeshRenderer.MeshGenerationMethod == MeshGenerationMethod.Manual) { // Scene Window buttons if (GUI.Button(new Rect(SMR_UISettings.btnColumnLine_2, SMR_UISettings.btnColumnLine_4, SMR_UISettings.btnWidth, SMR_UISettings.btnHeight), _splineMeshRenderer.Spline.Theme.MeshIcon)) { _splineMeshRenderer.ExtrudeMesh(); } // Add icons to inspector buttons _btnCreateMesh.image = _splineMeshRenderer.Spline.Theme.SmallMeshIcon; } else if (_splineMeshRenderer.MeshGenerationMethod == MeshGenerationMethod.Realtime) { // Scene Window buttons if (GUI.Button(new Rect(SMR_UISettings.btnColumnLine_2, SMR_UISettings.btnColumnLine_4, SMR_UISettings.btnWidth, SMR_UISettings.btnHeight), _splineMeshRenderer.Spline.Theme.LogIcon)) { _splineMeshRenderer.PrintMeshDetails(); } // Add icons to inspector buttons _btnPrintMeshDetails.image = _splineMeshRenderer.Spline.Theme.SmallLogIcon; } Handles.EndGUI(); } }
/// <summary> /// Bake mesh into folder /// </summary> private void Bake() { txtMessage = string.Empty; if (meshName == string.Empty) { ShowMessage("Please, enter a name for the mesh before proceding", WSMGameStudio.Splines.MessageType.Error); return; } if (outputDirectory == string.Empty) { ShowMessage("Please, select an Output Directory before proceding", WSMGameStudio.Splines.MessageType.Error); return; } GameObject selectedGameObject = Selection.activeGameObject; if (selectedGameObject == null) { ShowMessage("No object selected", WSMGameStudio.Splines.MessageType.Error); return; } SplineMeshRenderer splineMeshRenderer = selectedGameObject.GetComponent <SplineMeshRenderer>(); if (splineMeshRenderer == null) { ShowMessage("Selected object is not a Spline Mesh Renderer", WSMGameStudio.Splines.MessageType.Error); return; } if (splineMeshRenderer.GeneratedMesh == null) { ShowMessage("Generated mesh not found. Please generate a mesh before proceding.", WSMGameStudio.Splines.MessageType.Error); return; } MeshRenderer baseMeshRenderer = splineMeshRenderer.GetComponent <MeshRenderer>(); if (baseMeshRenderer == null) { ShowMessage("Selected object does not contains a Mesh Renderer.", WSMGameStudio.Splines.MessageType.Error); return; } //Create unique mesh instead of referencing original mesh Mesh mesh = (Mesh)Instantiate(splineMeshRenderer.GeneratedMesh); DirectoryInfo info = new DirectoryInfo(Application.dataPath); string folderPath = Path.Combine(info.Name, outputDirectory); string meshFilePath = Path.Combine(folderPath, meshName + "_mesh.asset"); string prefabFilePath = Path.Combine(folderPath, meshName + "_prefab.prefab"); //Check folder existence if (!Directory.Exists(folderPath)) { ShowMessage(string.Format("Folder does not exist: {0}", folderPath), WSMGameStudio.Splines.MessageType.Error); return; } //Overwrite dialog if (Exists(meshFilePath) || Exists(prefabFilePath)) { if (!ShowOverwriteDialog(meshName)) { return; } } //Save mesh as .asset file mesh = SaveMeshFile(mesh, meshFilePath); GameObject sceneObject = new GameObject(meshName); MeshFilter meshFilter = sceneObject.AddComponent <MeshFilter>(); MeshRenderer meshRend = sceneObject.AddComponent <MeshRenderer>(); MeshCollider meshCollider = sceneObject.AddComponent <MeshCollider>(); sceneObject.transform.position = splineMeshRenderer.transform.position; sceneObject.transform.rotation = splineMeshRenderer.transform.rotation; sceneObject.tag = splineMeshRenderer.gameObject.tag; sceneObject.layer = splineMeshRenderer.gameObject.layer; meshCollider.enabled = splineMeshRenderer.EnableCollision; meshCollider.sharedMesh = mesh; meshCollider.sharedMaterial = selectedGameObject.GetComponent <MeshCollider>().sharedMaterial; meshFilter.sharedMesh = mesh; meshRend.sharedMaterials = baseMeshRenderer.sharedMaterials; if (splineMeshRenderer.CustomMeshColliders != null) { foreach (var customCollider in splineMeshRenderer.CustomMeshColliders) { if (customCollider.GeneratedMesh == null) { Debug.LogWarning(string.Format("Generated mesh not found for {0}. Please generate a mesh before proceding.", customCollider.gameObject.name)); continue; } Mesh customMeshCollider = (Mesh)Instantiate(customCollider.GeneratedMesh); string customMeshFilePath = Path.Combine(folderPath, meshName + "_" + customCollider.gameObject.name + "_mesh.asset"); customMeshCollider = SaveMeshFile(customMeshCollider, customMeshFilePath); GameObject sceneObjectChild = new GameObject(customCollider.gameObject.name); MeshCollider customMeshColliderCollider = sceneObjectChild.AddComponent <MeshCollider>(); sceneObjectChild.transform.position = customCollider.transform.position; sceneObjectChild.transform.rotation = customCollider.transform.rotation; sceneObjectChild.tag = customCollider.gameObject.tag; sceneObjectChild.layer = customCollider.gameObject.layer; customMeshColliderCollider.enabled = true; customMeshColliderCollider.sharedMesh = customMeshCollider; customMeshColliderCollider.sharedMaterial = customCollider.GetComponent <MeshCollider>().sharedMaterial; sceneObjectChild.transform.parent = sceneObject.transform; } } //Save prefab as .prefab file GameObject prefab = SavePrefabFile(sceneObject, prefabFilePath, true); ShowMessage(string.Format("Mesh {0} Created Succesfuly!", meshName), WSMGameStudio.Splines.MessageType.Success); }
/// <summary> /// Custom inspector /// </summary> public override void OnInspectorGUI() { //base.OnInspectorGUI(); _splineMeshRenderer = (SplineMeshRenderer)target; //Set up the box style if null if (_menuBoxStyle == null) { _menuBoxStyle = new GUIStyle(GUI.skin.box); _menuBoxStyle.normal.textColor = GUI.skin.label.normal.textColor; _menuBoxStyle.fontStyle = FontStyle.Bold; _menuBoxStyle.alignment = TextAnchor.UpperLeft; } serializedObject.Update(); EditorGUILayout.PropertyField(serializedObject.FindProperty("_spline"), false); serializedObject.ApplyModifiedProperties(); EditorGUI.BeginChangeCheck(); _selectedMenuIndex = GUILayout.Toolbar(_selectedMenuIndex, _toolbarMenuOptions); if (EditorGUI.EndChangeCheck()) { GUI.FocusControl(null); } GUILayout.BeginVertical(_menuBoxStyle); if (_selectedMenuIndex == (int)MeshRendererInspectorMenu.MeshGenerationSettings) { #region Mesh Generation Settings GUILayout.Label("Generation Settings", EditorStyles.boldLabel); EditorGUI.BeginChangeCheck(); MeshGenerationMethod meshGenerationMethod = (MeshGenerationMethod)EditorGUILayout.EnumPopup("Mesh Generation Method", _splineMeshRenderer.MeshGenerationMethod); if (EditorGUI.EndChangeCheck()) { Undo.RecordObject(_splineMeshRenderer, "Mesh Generation Method Changed"); MarkSceneAlteration(); _splineMeshRenderer.MeshGenerationMethod = meshGenerationMethod; } EditorGUI.BeginChangeCheck(); Mesh baseMesh = (Mesh)EditorGUILayout.ObjectField("Base Mesh", _splineMeshRenderer.BaseMesh, typeof(Mesh), false); if (EditorGUI.EndChangeCheck()) { Undo.RecordObject(_splineMeshRenderer, "Base Mesh Changed"); MarkSceneAlteration(); _splineMeshRenderer.BaseMesh = baseMesh; } EditorGUI.BeginChangeCheck(); Vector3 meshOffset = EditorGUILayout.Vector3Field("Mesh Offset", _splineMeshRenderer.MeshOffset); if (EditorGUI.EndChangeCheck()) { Undo.RecordObject(_splineMeshRenderer, "Mesh Offset Changed"); MarkSceneAlteration(); _splineMeshRenderer.MeshOffset = meshOffset; } GUILayout.Label("Mesh Operations", EditorStyles.boldLabel); GUILayout.BeginHorizontal(); if (_splineMeshRenderer.MeshGenerationMethod != MeshGenerationMethod.Manual) { if (GUILayout.Button(_btnPrintMeshDetails)) { _splineMeshRenderer.PrintMeshDetails(); } } else { if (GUILayout.Button(_btnCreateMesh)) { _splineMeshRenderer.ExtrudeMesh(); } } if (GUILayout.Button(_btnBakeMesh)) { BakeMeshWindow.ShowWindow(); } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); if (GUILayout.Button(_btnConnectNewRenderer)) { Selection.activeGameObject = _splineMeshRenderer.ConnectNewRenderer(); MarkSceneAlteration(); } GUILayout.EndHorizontal(); #endregion } else if (_selectedMenuIndex == (int)MeshRendererInspectorMenu.CollisionSettings) { #region Collision Settings GUILayout.Label("Collision Settings", EditorStyles.boldLabel); EditorGUI.BeginChangeCheck(); bool enableCollision = EditorGUILayout.Toggle("Enable Collision", _splineMeshRenderer.EnableCollision); if (EditorGUI.EndChangeCheck()) { Undo.RecordObject(_splineMeshRenderer, "Enable Collision Changed"); MarkSceneAlteration(); _splineMeshRenderer.EnableCollision = enableCollision; } serializedObject.Update(); EditorGUILayout.PropertyField(serializedObject.FindProperty("_customMeshColliders"), true); serializedObject.ApplyModifiedProperties(); #endregion } GUILayout.EndVertical(); }
// Update is called once per frame void Update() { closestPt = grid.GetNearestPointOnGrid(Input.mousePosition); Vector3 worldPos = grid.GetNearestPointOnGrid(cam.ScreenToWorldPoint(closestPt)); worldPos.z = 0; Vector3 screenPos = cam.WorldToScreenPoint(worldPos); transform.position = new Vector3(screenPos.x, screenPos.y, -50); lineRenderer = previewLine.GetComponent <LineRenderer>(); if (Input.GetMouseButtonDown(0)) { if (editingState == 0 && allowClick) { Image i = GetComponent <Image>(); Sprite newCursor = Resources.Load <Sprite>("Cursors/PointUnderSelect"); i.overrideSprite = newCursor; lineRenderer.enabled = true; startingPt = worldPos; GetComponent <CursorRotator>().enabled = true; gameObject.GetComponent <ClickSound>().PlaySound(); editingState++; } else if (editingState == 1) { lineRenderer.enabled = false; if (!(IsOverlapping(startingPt.x, worldPos.x)) && !(startingPt.x == worldPos.x && startingPt.y == worldPos.y)) { gameObject.GetComponent <ClickSound>().PlaySound("TrackPlaced"); startingPt.z = 0; spawnTrack = Instantiate(splinePrefab, startingPt, Quaternion.identity); spawnTrack.name = "Spline" + numTrackPlaced.ToString(); spawnTrack.transform.parent = GameObject.Find("Splines").transform; numTrackPlaced++; Spline spline = spawnTrack.GetComponent <Spline>(); Vector3 origin = new Vector3(0, 0, 0); spline.SetControlPointPositionAbsolute(0, origin); spline.SetControlPointPositionAbsolute(1, (worldPos - startingPt) * 0.25f); spline.SetControlPointPositionAbsolute(2, (worldPos - startingPt) * 0.75f); spline.SetControlPointPositionAbsolute(3, worldPos - startingPt); // Pt for the ending anchor. if (worldPos.x < startingPt.x) { spline.SetControlPointPositionAbsolute(3, origin); spline.SetControlPointPositionAbsolute(2, (worldPos - startingPt) * 0.25f); spline.SetControlPointPositionAbsolute(1, (worldPos - startingPt) * 0.75f); spline.SetControlPointPositionAbsolute(0, worldPos - startingPt); // Pt for the ending anchor. } SplineMeshRenderer splineRenderer = spawnTrack.GetComponent <SplineMeshRenderer>(); splineRenderer.ExtrudeMesh(); splineRenderer.enableCollision = true; MeshCollider collider = spawnTrack.GetComponent <MeshCollider>(); collider.enabled = true; collider.sharedMesh = spawnTrack.GetComponent <MeshFilter>().mesh; /**** For chapter 4: Now check if a portal can be deployed. */ if (GameObject.Find("CheckWinController").GetComponent <CheckWin>().level.Contains("D")) { float EndX = spline.GetControlPointPosition(0).x + spline.transform.position.x; EndX = (Mathf.Round(EndX * 10f)) / 10; float EndY = spline.GetControlPointPosition(0).y + spline.transform.position.y; EndY = (Mathf.Round(EndY * 10f)) / 10; float StartX = spline.GetControlPointPosition(3).x + spline.transform.position.x; StartX = (Mathf.Round(StartX * 10f)) / 10; float StartY = spline.GetControlPointPosition(3).y + spline.transform.position.y; StartY = (Mathf.Round(StartY * 10f)) / 10; Dictionary <Spline, bool> sameXSplines = checkSameXSplines(EndX, StartX, EndY, StartY); foreach (Spline currentSpline in sameXSplines.Keys) { GameObject prompt; if (sameXSplines[currentSpline] == false) // this discontinuity happens on the left side of this spline. { Vector3 otherEnd = new Vector3(EndX, EndY - 2.5f, 0); Vector3 otherEndScreen = cam.WorldToScreenPoint(otherEnd); // deploy the prompt to ask how to place a hole. prompt = Instantiate(holePromptPrefab, otherEndScreen, Quaternion.identity); prompt.name = "HolePrompt" + "x = " + ((int)Mathf.Round(EndX)).ToString(); prompt.transform.GetChild(0).gameObject.GetComponent <TextMeshProUGUI>().text += ((int)Mathf.Round(EndX)).ToString() + "?"; } else // this discontinuity happens on the right side of this spline. { // deploy the prompt to ask how to place a hole. (same as above) Vector3 otherStart = new Vector3(StartX, StartY - 2.5f, 0); Vector3 otherStartScreen = cam.WorldToScreenPoint(otherStart); // deploy the prompt to ask how to place a hole. prompt = Instantiate(holePromptPrefab, otherStartScreen, Quaternion.identity); prompt.name = "HolePrompt" + "x = " + ((int)Mathf.Round(StartX)).ToString(); prompt.transform.GetChild(0).gameObject.GetComponent <TextMeshProUGUI>().text += ((int)Mathf.Round(StartX)).ToString() + "?"; } prompt.transform.SetParent(GameObject.Find("HolePrompts").transform); } } Image i = GetComponent <Image>(); Sprite newCursor = Resources.Load <Sprite>("Cursors/selectCursor"); i.overrideSprite = newCursor; GetComponent <CursorRotator>().enabled = false; } else if (IsOverlapping(startingPt.x, worldPos.x)) // display error message { GameObject.Find("MessageController").GetComponent <MessageController>().PlayMessage("Invalid placement! This track is overlapping with your other tracks."); } editingState = 0; } } if (editingState == 1) { Vector3[] positions = { startingPt, worldPos }; lineRenderer.SetPositions(positions); } }