I would like to expose a public property in my script from which I can drag and drop an .hlsl file onto the script component in the inspector window, like in this image, which shows an exposed property to drop a TextAsset:
The code powering this is:
public class NativeSDKWrapper : MonoBehaviour
{
public TextAsset ShaderFile;
// ...
}
According to the Unity Manual page on TextAsset, .hlsl is not listed as a supported file type. How can I get around this?
I need to read in the contents of an HLSL file to a string, so that I can compile it with D3DCompile.
You can use the Editor class ScriptedImporter to handle this in your editor:
using UnityEngine;
using UnityEditor.AssetImporters;
using System.IO;
[ScriptedImporter(1, "hlsl")]
public class CubeImporter : ScriptedImporter
{
public override void OnImportAsset(AssetImportContext ctx)
{
var ta = new TextAsset(File.ReadAllText(ctx.assetPath));
ctx.AddObjectToAsset("main obj", ta);
ctx.SetMainObject(ta);
}
}
Code based on documentation code linked above.
Be sure to put it in your project's Editor folder, as it references Editor stuff that won't be accessible once built.
Related
I created two scripts called "CustomTerrain" and "CustomTerrainEditor". Here is the code for the latter:
using UnityEngine;
using UnityEditor;
using EditorGUITable;
[CustomEditor(typeOf(CustomTerrain))] // Links editor code in here with CustomTerrain.cs
[CanEditMultipleObjects]
public class CustomTerrainEditor : Editor
{
void OnEnable() {}
public override void OnInspectorGUI() {} // The GUI we will see in the inspector
}
Here are the 2 errors I get:
I don't understand what I am doing wrong. Thanks for the help!
First, change typeOf to typeof.
And next if CustomTerrain in another namespace, add this space to your script.
I am using Unity 2019.3.13f1 and Visual Studio Community 2019 version 16.5.4. I have the script InterfaceContainer.cs as follows:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class InterfaceContainer : MonoBehaviour {
// Start is called before the first frame update
void Start() {
}
// Update is called once per frame
void Update() {
}
}
public interface IItem {
public string Name { get; }
public string Path { get; }
public GameObject Icon { get; }
public void Open();
}
Visual Studio gives no compilation errors.
In Unity the inspector of the script says "No MonoBehaviour scripts in the file, or their names do not match the file name." And when I drag the script into a GameObject, it says "Can't add script component "InterfaceContainer" because this script class cannot be found. Make sure that there are no compile errors and that the file name and the class name match."
The names definitely match, because when I deleted the interface part the error didn't exist anymore.
I also tried deleting the class part. It didn't help.
Any subsequent scripts added had the exact same error, whether or not they contain any interfaces, or reference this script.
The weird thing is when I deleted the interface part of this script, refreshed Unity, added this part again, and refreshed Unity again, the error disappears. However all subsequently added scripts still have the same error.
I have no idea what causes this error, and have googled for a long time with no avail. Any help will be greatly appreciated.
EDIT: The error isn't gone when I removed the interface part and added it again; I can still drag the script as a component, when when I try entering playmode it asks me to fix all compiler errors.
Try this:
Right click in the Project Panel of Unity
Import New Asset... and select InterfaceContainer.cs
Try add this script as component again.
One thing I would try is to check if it happens in earlier versions of unity. With the unity hub its easy to have different versions of unity to check this kind of things. Its useful if you are working with one of the latests.
I can confirm that in 2018.4.12, I attach my monobehaviours with interfaces with no problem.
On the other hand you dont implement the Interface you define in your monobehaviour, although that should not be causing any problem, have you tried if implementing the interface in your monobehaviour if you got the error?
Hope that helps
In Unity, Resources.LoadAll(path) method would access T type in the specific path(e.g.Resources/Meshes/Buildings). Then we can add all these files to our array.
However, I can't specific any file like .fbx, .obj, .png, etc. The T type allows us to access only the Unity classes suck as GameObject, Texture2D, Mesh and so on...
Here is my script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;
public class AutoPre_Manager : MonoBehaviour
{
public Object[] tractorobj;
public GameObject[] directoryAllFiles;
public string[] Model_Folder;
public List<GameObject> meshGameobj;
private void Start()
{
loadModels();
}
public void loadModels()
{
meshGameobj = new List<GameObject>();
directoryAllFiles = Resources.LoadAll<GameObject>("Model/Equipment");
}
}
The script compiled, smoothly. And when I ran the game, Resources.LoadAll would get every files in my folder(.fbx, .prefabs, .cs)
If I only need .fbx files, what should I do?
Thank you in advance
Unfortunately, there is no way you can distinguish .fbx and .prefabs just by typing the path because extensions are ignored. Here is what you can do:
Try placing your .fbx files into a new folder like: "Model/Equipment/FBXs".
Set the .fbx list through inspector.
Add a tag to .fbx files then after loadall filter the array, but I wouldn't recommend this method because wastes memory.
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 have a class using UnityScript like this:
public class Responder{
private var completeHandler:Function;
public function addHandlers(completeHandler:Function):void {
completeHandler();
}
}
Now, i want to use this class in c# code,
public class MyGame : MonoBehaviour{
void Start(){
Responder res = new Responder();
res.addHandlers(?????); //how to pass the param??
}
}
Thanks!
Put the Javascript class in a folder called Plugins under assets. You will be able to call the methods written in JS from C# scripts.
The type Function in JS appears to me as Boo.Lang.ICallable in C#. As I couldn't import Boo.Lang by default, I took the Boo.Lang.dll from the Unity3D installed folder and copied it to the same Plugins folder in the project, then adding using Boo.Lang; at the top of my C# script.
You can now create and pass a new ICallable type as an argument from C# to JS.