How do I quit in standalone or in editor mode - c#

I'm using unity 5.4.1f1 Personal on windows 10 64bit
I will explain all the steps i did and all the things i tried so far.
Firs time i created a new c# file with the original code:
Now when i press the Escape key it will go back to the editor but will not QUIT the game ! You can't stop the editor play button and quit the game when using [InitializeOnLoad]. To quit the game you can only do it with Build And Run in Standalone mode then you can make Application.Quit();
using UnityEditor;
using UnityEngine;
using System.Collections;
[InitializeOnLoad]
public class FullscreenPlayMode : MonoBehaviour {
//The size of the toolbar above the game view, excluding the OS border.
private static int tabHeight = 22;
static FullscreenPlayMode()
{
EditorApplication.playmodeStateChanged -= CheckPlayModeState;
EditorApplication.playmodeStateChanged += CheckPlayModeState;
EditorApplication.update += Update;
}
static void CheckPlayModeState()
{
if (EditorApplication.isPlaying)
{
FullScreenGameWindow();
}
else
{
CloseGameWindow();
}
}
static EditorWindow GetMainGameView(){
EditorApplication.ExecuteMenuItem("Window/Game");
System.Type T = System.Type.GetType("UnityEditor.GameView,UnityEditor");
System.Reflection.MethodInfo GetMainGameView = T.GetMethod("GetMainGameView",System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static);
System.Object Res = GetMainGameView.Invoke(null,null);
return (EditorWindow)Res;
}
static void FullScreenGameWindow(){
EditorWindow gameView = GetMainGameView();
Rect newPos = new Rect(0, 0 - tabHeight, Screen.currentResolution.width, Screen.currentResolution.height + tabHeight);
gameView.position = newPos;
gameView.minSize = new Vector2(Screen.currentResolution.width, Screen.currentResolution.height + tabHeight);
gameView.maxSize = gameView.minSize;
gameView.position = newPos;
}
static void CloseGameWindow(){
EditorWindow gameView = GetMainGameView();
gameView.Close();
}
static void Update()
{
if (Input.GetKey (KeyCode.Escape))
{
CloseGameWindow ();
}
}
}
Then since this is not working as i wanted i tried something else.
I deleted the line: [InitializeOnLoad] but didn't change anything else in the rest of the script.
This time after deleting the line [InitializeOnLoad] i dragged the script into the ThirdPersonController.
Now if i will start the game as before form the editor and hit press the escape key it will back to the editor but will not quit the game !
But now if i make in the menu File > Build & Run i will get two errors:
The first error is:
Assets/MyScripts/FullScreenPlayMode.cs(1,7): error CS0246: The type or namespace name `UnityEditor' could not be found. Are you missing a using directive or an assembly reference?
The second error:
Error building Player because scripts had compiler errors
So i went to this solution what suppose to be a solution in this link:
Not working solution
If i move the file script to the EDITOR directory then i can't drag the script to the ThirdPersonController it will throw a message say the script is editor script.
If i tried the second solution in the link:
#if UNITY_EDITOR
// Editor specific code here
#endif
So i did it in the script in the top:
#if UNITY_EDITOR
using UnityEditor;
#endif
And the script file is not in the Editor directory !
This time when i make Build & Run i'm getting a new another error:
Assets/MyScripts/FullScreenPlayMode.cs(34,16): error CS0246: The type or namespace name `EditorWindow' could not be found. Are you missing a using directive or an assembly reference?
Could not find what is this error with the EditorWindow. This error happen when i used the #if and #endif
So in all the ways i tried so far i got another problem.

I might be simplifying your problem but you could simply do this:
void Update()
{
if (Input.GetKey(KeyCode.Escape))
{
#if UNITY_EDITOR
if (EditorApplication.isPlaying)
{
EditorApplication.isPlaying = false;
}
#else
Application.Quit();
#endif
}

Related

Why is GUI.Label not working for me in unity?

I have tried both without OnGUI and with OnGUI and I can not really understand the errors they are giving.
I do not really understand what an error like
Internal build system error. BuildProgram exited with code -2146233088.
error: Build path contains project built with "Create Visual Studio Solution" option, which is incompatible with current build settings. Consider building your project into an empty directory.
System.Exception: Build path contains project built with "Create Visual Studio Solution" option, which is incompatible with current build settings. Consider building your project into an empty directory.
at WinPlayerBuildProgram.WinPlayerPrerequisiteChecks.CheckSafeProjectOverwrite(PlayerBuildConfig playerBuildConfig)
at WinPlayerBuildProgram.WinPlayerBuildProgram..ctor(String[] args)
at PlayerBuildProgramTypeWrapper.Run(String[] args)
at Program.Main(String[] args)
UnityEditor.BuildPlayerWindow:BuildPlayerAndRun ()
means and I do not know the problem with this code
using System.Collections;
using System.Collections.Generic;
using System;
using UnityEngine;
public class SquareScript : MonoBehaviour
{
void Start()
{
transform.position = new Vector3(1, 0);
}
void Update()
{
transform.position = new Vector3((float)Math.Cos(Time.time), (float)Math.Sin(Time.time));
}
void OnGUI()
{
GUI.Label(new Rect(-0.5f, 0.5f, -0.5f, 0.5f), "lol");
}
}
And by the way it has nothing to do with the stuff in void Start() or void Update() since I tested that without the GUI stuff and it works fine.

DllNotFound in Unity

I am trying to use my C++ dll on Unity, so I copied it in Assets/Plugins and at the root of the project but I have DllFoundException when I use the Play button or run the .exe file generated by the build. It doesn't even work when I use the absolute path of the dll file in the DllImport.
However, it works fine when I Build&Run the project.
Unity Code
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using UnityEngine;
using Dummiesman;
public class morph_face : MonoBehaviour
{
bool morphed;
[DllImport(#"facemorph", CallingConvention=CallingConvention.Cdecl)]
static extern void morphModelsPoints(string src_model, string src_csv,
string dst_csv, string output_path);
public GameObject model;
// Start is called before the first frame update
void Start()
{
morphed = false;
}
// Update is called once per frame
void Update()
{
if (!morphed && Input.GetKeyDown("space")) {
Debug.Log("SpaceBar pressed the model will be modified.");
morphModelsPoints("Data/src.obj", "Data/src.csv", "Data/dst.csv",
"Data/res.obj");
//disable old mesh
model.SetActive(false);
OBJLoader obj = new OBJLoader();
model = obj.Load("Data/res.obj");
//displays new mesh
model.SetActive(true);
morphed = true;
}
}
}
The Dll was built with this configuration: Release/Win32.
Here's the dll import settings :
※Please correct me if I am wrong
If I am not mistaken, you can not use 32 dlls in Editor because UNITY is 64bit. If you can just rebuild your dll to 64bit. If you build a standalone then you must set your architecture to x86 instead of x86_64 in Build Settings.

"Predefined type System.Void is not defined or imported" error trying to compile c# scripts for Unity 2D in Visual Studio 2017

I'm trying to learn creating 2D videogames with Unity but i can't compile my script for CharacterMovement because of several errors.
Even creating a new empty script, the compiler says that "Predefined type System.Void is not defined or imported" and i couldn't find online a way to fix this.
This is the empty script :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MyPlayerMovement : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
}
And this is the script i'm trying to compile :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovement : MonoBehaviour {
public CharacterController2D controller;
public Animator animator;
public float runSpeed = 40f;
float horizontalMove = 0f;
bool jump = false;
bool crouch = false;
// Update is called once per frame
void Update () {
horizontalMove = Input.GetAxisRaw("Horizontal") * runSpeed;
animator.SetFloat("Speed", Mathf.Abs(horizontalMove));
if(horizontalMove == 0)
{
animator.SetBool("Jumping", false);
}
if (Input.GetButtonDown("Jump"))
{
jump = true;
animator.SetBool("Jumping", true);
}
if (Input.GetButtonDown("Crouch"))
{
crouch = true;
animator.SetBool("Crouching", true);
} else if (Input.GetButtonUp("Crouch"))
{
crouch = false;
animator.SetBool("Crouching", false);
}
}
void FixedUpdate ()
{
// Move our character
controller.Move(horizontalMove * Time.fixedDeltaTime, crouch, jump);
jump = false;
}
}
(On my script i get about 60 errors all similar)
change the option in File->BuildSettings->playersettings-api compatibility level to .Net 4X
This happened when I tried to install Microsoft.Toolkit.Uwp.Notification using Install-Package Microsoft.Toolkit.Uwp.Notifications -Version 7.1.2.
Once I do this, I notice a new config file is added to my solution explorer. I have to delete this to fix the error.
Another possible solution for those stumbling across this in the future: Go to Edit->Preferences->External Tools->Regenerate project files to bring back the original CS Project & VS solution files.
That was the only option that worked after trying other common answers like changing API compatibility, upgrading VS, or deleting the project obj folder. I think it broke like that due to me trying to clean out the solution manually and Unity ended up corrupting some packages after I attempted to delete them. So unfortunately it seems you will get this error if you try to do that.

Unity, editor-time script, On GameObject Added to Scene Event

Say you have a trivial prefab, "Box", which we'll say is nothing more than a standard meter cube.
1 - The prefab Box is in your Project panel
2 - Drag it to the Scene
3 - Obviously it now appears in the Hierarchy panel also, and probably selected and shown in Inspector
To be clear, game is NOT Play when you do this, you're only in ordinary Editor mode.
Is it possible to make a script (an "Editor script"?) so that,
when you do "1" and "2" above, (again this is in Editor mode, not during a game)
when 3 happens, we can affect the new Box item in the scene
So, simple example: we will set the Z position to "2" always, no matter where you drop it.
In short: Editor code so that every time you drag a prefab P to the scene, it sets the position z to 2.0.
Is this possible in Unity? I know nothing of "editor scripts".
It seems very obvious this should be possible.
You can add a custom window editor which implements OnHierarchyChange to handle all the changes in the hierarchy window. This script must be inside the Editor folder. To make it work automatically make sure you have this window opened first.
using System.Linq;
using UnityEditor;
using UnityEngine;
public class HierarchyMonitorWindow : EditorWindow
{
[MenuItem("Window/Hierarchy Monitor")]
static void CreateWindow()
{
EditorWindow.GetWindow<HierarchyMonitorWindow>();
}
void OnHierarchyChange()
{
var addedObjects = Resources.FindObjectsOfTypeAll<MyScript>()
.Where(x => x.isAdded < 2);
foreach (var item in addedObjects)
{
//if (item.isAdded == 0) early setup
if (item.isAdded == 1) {
// do setup here,
// will happen just after user releases mouse
// will only happen once
Vector3 p = transform.position;
item.transform.position = new Vector3(p.x, 2f, p.z);
}
// finish with this:
item.isAdded++;
}
}
}
I attached the following script to the box:
public class MyScript : MonoBehaviour {
public int isAdded { get; set; }
}
Note that OnHierarchyChange is called twice (once when you start dragging the box onto the scene, and once when you release the mouse button) so isAdded is defined as an int to enable its comparison with 2. So you can also have initialization logic when x.isAdded < 1
You could thy this:
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif
[ExecuteInEditMode]
public class PrintAwake : MonoBehaviour
{
#if UNITY_EDITOR
void Awake() .. Start() also works perfectly
{
if(!EditorApplication.isPlaying)
Debug.Log("Editor causes this Awake");
}
#endif
}
See https://docs.unity3d.com/ScriptReference/ExecuteInEditMode.html
Analysis:
This does in fact work!
One problem! It happens when the object starts to exist, so, when you are dragging it to the scene, but before you let go. So in fact, if you specifically want to adjust the position in some way (snapping to a grid - whatever) it is not possible using this technique!
So, for example, this will work perfectly:
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif
[ExecuteInEditMode]
public class PrintAwake : MonoBehaviour
{
#if UNITY_EDITOR
void Start() {
if(!EditorApplication.isPlaying) {
Debug.Log("Editor causes this START!!");
RandomSpinSetup();
}
}
#endif
private void RandomSpinSetup() {
float r = Random.Range(3,8) * 10f;
transform.eulerAngles = new Vector3(0f, r, 0f);
name = "Cube: " + r + "°";
}
}
Note that this works correctly, that is to say it does "not run" when you actually Play the game. If you hit "Play" it won't then again set random spins :)
Great stuff
Have a similar issue - wanted to do some stuff after object was dragged into scene (or scene was opened with already existed object). But in my case gameobject was disabled. So I couldn't use neither Awake, nor Start.
Solved via akin of dirty trick - just used constructor for my MonoBehaviour class. Unity blocks any attempts to use most of API inside MonoBehaviour constructors, but we could just wait for some time, for example via EditorApplication.delayedCall. So code looks like this:
public class ExampleClass: MonoBehaviour
{
//...
// some runtime logic
//...
#if UNITY_EDITOR
//Constructor
ExampleClass()
{
EditorApplication.delayCall += DoSomeStuffForDisabledObjectAfterCreation;
}
void DoSomeStuffForDisabledObjectAfterCreation()
{
if (!isActiveAndEnabled)
{
//Some usefull stuff
}
}
#endif
}
Monobehaviours have a Reset method, that only gets called in Editor mode, whenever you reset or first instantiate an object.
public class Example : MonoBehaviour
{
void Reset()
{
transform.position =
new Vector3(transform.position.x, 2.22f, transform.position.z);
Debug.Log("Hi ...");
}
}

How to create dialogbox in Unity (not using UnityEditor)?

I want to use dialog boxes (having two options).
I tried UnityEditor, but when I build the project to create an exe file, it didn't work because scripts having UnityEditor references are just working in edit mode. After searching on the Internet for hours, there were two suggestions (both didn't work).
First one: Using #if UNITY_EDITOR before code and ending with #endif. In this case, It was built without an error but there were no dialog boxes in my game at all.
Second one: Putting the script under Assets/Editor directory. In this case, I couldn't add the script to my game object. Maybe, creating a new script under Editor directory and pasting UnityEditor used lines in it would work but I couldn't figured out how to do this.
I used:
#if UNITY_EDITOR
if (UnityEditor.EditorUtility.DisplayDialog("Game Over", "Again?", "Restart", "Exit"))
{
Application.LoadLevel (0);
}
else
{
Application.Quit();
}
#endif
I also tried adding " using UnityEditor; " and encapsulating it with the preprocessor command I mentioned. It is also useless.
Is there anyone knowing how to use UnityEditor in run mode or how to create dialog boxes in a different way?
if I understand right, you need a popup window, when the character dies (or the player failed). The UnityEditor classes are for extending the editor, but in your case you need an in game solution. This can be achived with gui windows.
Here is a short script in c# that achives this.
using UnityEngine;
using System.Collections;
public class GameMenu : MonoBehaviour
{
// 200x300 px window will apear in the center of the screen.
private Rect windowRect = new Rect ((Screen.width - 200)/2, (Screen.height - 300)/2, 200, 300);
// Only show it if needed.
private bool show = false;
void OnGUI ()
{
if(show)
windowRect = GUI.Window (0, windowRect, DialogWindow, "Game Over");
}
// This is the actual window.
void DialogWindow (int windowID)
{
float y = 20;
GUI.Label(new Rect(5,y, windowRect.width, 20), "Again?");
if(GUI.Button(new Rect(5,y, windowRect.width - 10, 20), "Restart"))
{
Application.LoadLevel (0);
show = false;
}
if(GUI.Button(new Rect(5,y, windowRect.width - 10, 20), "Exit"))
{
Application.Quit();
show = false;
}
}
// To open the dialogue from outside of the script.
public void Open()
{
show = true;
}
}
You can add this class to any of your game objects, and call its Open mehtod to open the dialogue.
Have a look at Unity GUI Scripting Guide.
Example:
using UnityEngine;
using System.Collections;
public class GUITest : MonoBehaviour {
private Rect windowRect = new Rect (20, 20, 120, 50);
void OnGUI () {
windowRect = GUI.Window (0, windowRect, WindowFunction, "My Window");
}
void WindowFunction (int windowID) {
// Draw any Controls inside the window here
}
}
Alternatively you could show a textured plane in the center of the camera.

Categories