I am encountering the error- "The name 'FileUtil' does not exist in the current context" only when i am building my unity app for android but it runs fine without any errors when i run it in the editor. This line basically deletes a folder
I have tried adding using System.IO; but it still isn't working. Also it works if I remove the line.
public void Delete()
{
P = EventSystem.current.currentSelectedGameObject.transform;
FileUtil.DeleteFileOrDirectory(Application.persistentDataPath + "/ARPortal/" + P.parent.gameObject.name);
P.gameObject.SetActive(false);
P.parent.GetChild(4).transform.gameObject.SetActive(true);
counter = 0;
}
Is there any workaround or alternate to delete a folder.Snippet ofthe error i am encountering
FileUtil is part of the UnityEditor namespace. It does not exist in a build but only within the Unity Editor itself.
=> You can not use anything from it in a built App.
Usually you only use it for editor scripts (things that shall only happen in Unity e.g. for having fancy Inspectors etc).
In order to exclude such code parts from a build there are basically two ways:
Make sure all editor script are placed in folders named Editor. Those are automatically excluded from the build process.
If you only want to exclude certain code blocks of the build (everything using UnityEditor you can use the if pre-processors with UNITY_EDITOR
#if UNITY_EDITOR
using UnityEditor;
#endif
...
#if UNITY_EDITOR
// some code using the UnityEditor namespace
#endif
For deleting a folder on runtime you could use e.g. Directory.Delete
For a file you can use File.Delete
In both cases you should never directly concatenate path strings but rather use Path.Combine
using System.IO;
...
var path = Path.Combine(Application.persistentDataPath, "ARPortal", P.parent.gameObject.name);
//if it is an empty folder use
Directory.Delete(path);
//if it is a folder with content use
Directory.Delete(path, true);
//if it is a file use
File.Delete(path);
Related
I cannot get Unity Assetbundles working in an iOS build.
In Unity I build the assetbundles:
using UnityEditor;
public class CreateAssetBundles
{
[MenuItem("Assets/Build AssetBundles")]
static void BuildAllAssetBundles()
{
BuildPipeline.BuildAssetBundles("Assets/AssetBundles", BuildAssetBundleOptions.None, BuildTarget.iOS);
}
}
And they work fine in Unity. using them with
AssetBundle bundleLoadRequest = AssetBundle.LoadFromFile("file://" + Application.dataPath + "/AssetBundles/iOS/" + myassetbundlename.ToString());
and/or
WWW wwww = WWW.LoadFromCacheOrDownload("file://" + Application.dataPath + "/AssetBundles/iOS/" + myassetbundlename.ToString(), 4);
(Without the "file://" prefix, the bundles won't work in Unity nor Xcode)
I build the project to Xcode and run it in Xcode and receive this error:
Unable to open archive file:
/Users/user/Documents/Workspaces/unityproject/Assets/AssetBundles/iOS/lchairanimations
It might be related somehow to setting the correct path, but as I have copied the assetbundle folder afterwards to Xcode project, the problem persists.
In this example below, I will demonstrate how to add new asset called "dog" to our AssetBundle named "animals" and build it then load it during run-time.
Setting Up Build Folders:
1. Select the asset such as image file. In this case, that's the "dog.jpeg" file. See the menu in the "Inspector" tab. Sometimes, the AssetBundle option it is hidden, drag it up to show it. See the animated gif below for how to do this. The default AssetBundle is "None". Click on the "None" option then go to the "New" option and create new AssetBundle and name it "animals"
2. Create a folder named StreamingAssets in the Assets folder. This is the folder we are going to build the AssetBundle into. Spelling counts and it's case sensitive so make sure to name it correctly.
3. Create sub-folder in the StreamingAssets folder to hold the AssetBundle. For this example, name this folder AssetBundles so that you can use it to recognize what's in it.
Building AssetBundle:
4. Below is the build script.
A. Create a script named ExportAssetBundles and put it in a folder named "Editor" in the Assets folder then copy the code below inside it:
using System.IO;
using UnityEditor;
using UnityEngine;
public class ExportAssetBundles
{
[MenuItem("Assets/Build AssetBundle")]
static void ExportResource()
{
string folderName = "AssetBundles";
string filePath = Path.Combine(Application.streamingAssetsPath, folderName);
//Build for Windows platform
BuildPipeline.BuildAssetBundles(filePath, BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows64);
//Uncomment to build for other platforms
//BuildPipeline.BuildAssetBundles(filePath, BuildAssetBundleOptions.None, BuildTarget.iOS);
//BuildPipeline.BuildAssetBundles(filePath, BuildAssetBundleOptions.None, BuildTarget.Android);
//BuildPipeline.BuildAssetBundles(filePath, BuildAssetBundleOptions.None, BuildTarget.WebGL);
//BuildPipeline.BuildAssetBundles(filePath, BuildAssetBundleOptions.None, BuildTarget.StandaloneOSX);
//Refresh the Project folder
AssetDatabase.Refresh();
}
}
B. Build your AssetBudle by going to Assets --> Build AssetBundle menu.
You should see the built AssetBundles inside the Assets/StreamingAssets/AssetBundles directory. If not, refresh the Project tab.
Loading the AssetBundle during run-time:
5. When loading it, Application.streamingAssetsPath should be used to access the StreamingAssets folder. To access all the folders use, Application.streamingAssetsPath + "/AssetBundle/" + assetbunlenameWithoutExtension;. The AssetBundle and AssetBundleRequest API are used to load the AssetBundle. Since this is an image, Texture2D is passed to them. If using a prefab, pass GameObject instead then instantiate it. See comment in code for where these changes should be made. It is recommended to use Path.Combine to combine path names so the code below should use that instead.
Below is a simple loading function:
IEnumerator LoadAsset(string assetBundleName, string objectNameToLoad)
{
string filePath = System.IO.Path.Combine(Application.streamingAssetsPath, "AssetBundles");
filePath = System.IO.Path.Combine(filePath, assetBundleName);
//Load "animals" AssetBundle
var assetBundleCreateRequest = AssetBundle.LoadFromFileAsync(filePath);
yield return assetBundleCreateRequest;
AssetBundle asseBundle = assetBundleCreateRequest.assetBundle;
//Load the "dog" Asset (Use Texture2D since it's a Texture. Use GameObject if prefab)
AssetBundleRequest asset = asseBundle.LoadAssetAsync<Texture2D>(objectNameToLoad);
yield return asset;
//Retrieve the object (Use Texture2D since it's a Texture. Use GameObject if prefab)
Texture2D loadedAsset = asset.asset as Texture2D;
//Do something with the loaded loadedAsset object (Load to RawImage for example)
image.texture = loadedAsset;
}
Things to before loading note:
A. Name of Assetbundle is animals.
B. Name of the asset/object we want to load from the animals Assetbundle is dog This is a simple jpg of a dog.
C. The loading is simple as this:
string nameOfAssetBundle = "animals";
string nameOfObjectToLoad = "dog";
public RawImage image;
void Start()
{
StartCoroutine(LoadAsset(nameOfAssetBundle, nameOfObjectToLoad));
}
I have a suggestion as well that might be more accommodating to developers like me who want something more .Net based. You might consider building a "Launcher" using Unity. I would build it using Unity so it remains cross platform. Next, consider bundling your updates in a DLL since Unity supports .Net framework or store them as a image in a web folder. You can grab your data using Webclient. Article here:
https://learn.microsoft.com/en-us/dotnet/api/system.net.webclient.downloadfile?view=netframework-4.8#System_Net_WebClient_DownloadFile_System_Uri_System_String_
A launcher might be a better way to grab or update your content. I've been toying with the idea every since I played Lord of the Rings Online and I like their Launcher. So I wanted to make one for my own games. In your code you would use "DownloadFile(Uri, String)" to get your data. I would use an API or something to first check your current version of the game or DLL etc. Then check the data base for laest version. Finally the API or something could build a list of new files needed or updated files needed and just loop through requesting the files and download what you need.
I am researching how to generate environments in Unity using GIS data in KML format. I came across the SharpKML plugin and it seems to be ideal for my needs.
However, I am experiencing a strange error in that Unity throws an error
“CS0246: The type or namespace name ‘SharpKml’ could not be found (are you missing a using directive or an assembly reference?)”
The reference is added to VS and I have using SharpKML.Dom and using SharpKML.Engine entries which compile in VS with no problems.
But Unity still throws the error.
I have installed via NuGet and have also downloaded the SharpKML source code and rebuilt the dll on my machine and referenced directly with no change. VS also seems to drop the reference intermittently.
Have you come across this problem before or have any idea what is causing it?
The version of Unity is 2019.1.4f1 and the the version of VS is 2017 running framework 4.7.03062
I have recreated the project on a different machine on a different network and experience the same problem.
using UnityEngine;
using System.IO;
using System.Linq;
using SharpKml.Dom;
using SharpKml.Engine;
public class RenderKML : MonoBehaviour
{
public string KLMPath;
// Start is called before the first frame update
void Start()
{
string kmlPth = "Assets\\kml";
GetKMLFiles(kmlPth);
}
private void GetKMLFiles(string pth)
{
if (pth != null)
{
DirectoryInfo dir = new DirectoryInfo(pth);
FileInfo[] info = dir.GetFiles("*.kml");
foreach (FileInfo f in info)
{
print(f.FullName);
GetKMLData(f);
}
}
}
private void GetKMLData(FileInfo fI)
{
// This will read a Kml file into memory.
Stream fs = new FileStream(fI.FullName, FileMode.Open);
KmlFile file = KmlFile.Load(fs);
Kml kml = file.Root as Kml;
if (kml != null)
{
foreach (var placemark in kml.Flatten().OfType<Placemark>())
{
print(placemark.Name);
}
}
}
}
Every time you press "Run", unity rewrites project files. You cant simply use nuget or add references from external projects. You should download all SharpKML dll files and put them in Assets folder manually. See this for more information: https://answers.unity.com/questions/458300/how-to-use-a-external-dll.html
You need to use the Plugin folder in Unity3D. Download your Package or DLL and put it there.
This link can be helpful
I have to copy two text files and a folder to my build data folder after finishing the build (exe) for windows platform. Each time I build, I want to copy these files and folder from assets to build data folder. Is this possible in unity? Cause sometime I forget to copy desired file in data folder and my player does not work correctly.
You can subscribe a static method to PostprocessBuild.OnPostprocessBuild
This method will be called every time a build is finished.
So your code might look like this:
using UnityEditor;
using System.IO;
using UnityEditor.Build;
using UnityEngine;
class MyCustomBuildProcessor : IPostprocessBuild
{
public int callbackOrder { get { return 0; } }
public void OnPostprocessBuild(BuildTarget target, string path)
{
File.Copy("sourceFilePath","destinationFilePath");
}
}
It sounds like you want your own custom editor build function. You can do this with a custom editor menu item.
Unity Editor Extensions – Menu Items
Here is what the code might look like:
[MenuItem("MyBuildMenu/MyBuildMenuItem")]
static void BuildAndCopyItems()
{
File.Copy("path1","path2"); // copy your files
BuildPipeline.BuildPlayer(); // build the player
}
you'll need to pass the correct arguments to BuildPlayer:
BuildPipeline.BuildPlayer
The file containing this script will need to be within your project in a folder called 'Editor'.
And you'll get a new menu item in the Unity editor to perform your custom build:
I am using Unity 5.3.5. I have a script that I wrote under the Unity Assets/MyScript folder.
ScriptA.cs
public class ScriptA : MonoBehaviour
{
//code here
public static bool flag_I_want_to_reference;
}
Then, because I am using the Unity standard asset vehicle/car thing, it is in a separate namespace in a different folder path (i.e. not in MyScripts folder but in a different path under Assets)
SomeCarScript.cs
namespace UnityStandardAssets.Vehicles.Car
{
public class SomeCarScript : MonoBehaviour
{
//code here
bool foo = ScriptA.flag_I_want_to_reference;
}
}
Now, I have a bool that I want reference from within the SomeCarScript.cs but I am getting the error The name 'ScriptA' does not exist in the current context
I am trying to figure out what class/reference I need to have with using statements on the top of the SomeCarScript.cs script to make this work. I have tried looking up global namespaces and tried global::ScriptA.flag_I_want_to_reference and global::flag_I_want_to_reference but that doesn't work. I have also tried using "Assets/MyScripts/ScriptA.cs;" but that doesn't work either.
Any help would be greatly appreciated.
This looks like a compilation order issue.
If SomeCarScript is in a subdirectory of a "Standard Assets" folder and ScriptA is somewhere else, then it's because of the compilation order that ScriptA can't be referenced. ScriptA is compiled in a phase after SomeCarScript and therefore does not exist for SomeCarScript.
All code compiled in a specific phase can access code compiled in the same phase or an earlier phase, but not the code that will be compiled in a later phase (because, for the code being compiled, it doesn't exist yet).
General practice is to keep all code referencing the Standard Assets scripts in a folder other than "Standard Assets", so that it is compiled at a later stage and is able to access all other code.
Coming to your solution, you have two options:
Move ScriptA to the same directory as SomeCarScript (not recommended)
Move SomeCarScript to a directory which is not a subdirectory of "Standard Assets", "Pro Standard Assets" or "Plugins" (recommended)
Check out the Unity Manual page concerning script compilation order for more information.
I know there are a dozen questions like this and I looked at the more popular ones, but I have had no luck in figuring out anything.
I want to make a C# *.exe that would play a sound when opened, I decided it would be OK to start with a Console Application project, but I have no idea if that is the best choice.
I have added the "file.mp3" file to the resource designer under "Other" files and set its build action to "Embedded Resource".
From there I saw the suggestion about WMPLib, which I cannot access in my project - it is not present neither in my Reference Manager, neither does "using WMPLib;" work (it raises a "could not be found" error) or the one about the "System.Media.SoundPlayer.Play();" method but I am having trouble implementing it, because my complier either says an object reference is required for it or it has no overload, because it only takes 1 arguments if I make it like "System.Media.SoundPlayer.Play("file.mp3");"
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Program p = new Program();
p.Mum();
}
void Mum()
{
System.Media.SoundPlayer.Play();
}
}
}
To play an mp3 file, You will need to add the windows media player Library.
1. Add a reference to the WMP library - in your solution explorer, under your project, go to References, right click and add a reference to WMP. It will be under the COM libraries, I think.
2. Add "using WMPLib;" to your code at the top,
3. Add this code to play the file:
WindowsMediaPlayer myplayer = new WindowsMediaPlayer();
myplayer.URL = "mysound.mp3";
myplayer.controls.play();
mind you the URL is the path to the file you want to play. If it has backslashes in it, you will have to "escape" them. Like this
myplayer.URL = "C:\\Users\\Public\\Music\\Sample Music\\Kalimba.mp3";