Http://unity3d.9tech.cn/news/2014/0116/39639.html
Usually, during the development of the game, some components are eventually built up, and some data is received through some form of configuration file. These may be some of the parameters of a program-level build system, perhaps a gesture set of gesture recognition systems, or anything else. If you are developing within unity, it is possible to start this task by creating a serializable class that is designed as a simple container to store all the configuration data you need.
But then what? How do you put data into that class in the real world? Do you create a bunch of XML or JSON files and load them when the game starts? Or there is a public instance of the data class in the class that needs the data, and you set everything through inspector, and then create a lot of prefabrication, one for each configuration.
In this article I will describe a simple way to put those serializable data container classes into a custom resource file. This has many advantages over using XML or some other external file format. For example, the file size will typically be smaller, and unity will take control of all serialization and deserialization.
I think this method is best explained by examples. So I'm assuming we're trying to build a JRPG type of dialogue system, like the aura of fire or the ranch thing or the other jrpg. This type has a large text bubble, which slides up from the bottom, and then has a flattened character on the left or right to speak.
OK, now start creating a simple serializable data container for each individual conversation language element, as follows:
12345678910111213 |
[System.Serializable]
public class DialogueElement
{
public enum Characters{ David, Megan};
public enum AvatarPos{ left, right};
public Characters Character;
public AvatarPos CharacterPosition;
public Texture2D CharacterPic;
public string DialogueText;
public GUIStyle DialogueTextStyle;
public float TextPlayBackSpeed;
public AudioClip PlayBackSoundFile;
}
|
There are several enumerations to describe which roles and screen positions are effective, to show the character's texture, what characters actually say in the conversation bubbles, Guistyle for string design, and perhaps a floating point to control the speed at which the text disappears, and a sound fragment to add a background sound to each of the conversation bubbles.
Remember that this is just an example, so you should learn to extrapolate and use this example to learn how to apply technology to any type of data container.
Next, create a class for all conversations that will contain a list of those dialogueelement objects. Instead of making it into a normal serialization class, let it inherit from the Scriptableobject. The Scriptableobject class can turn the dialog class into our own custom resource file.
1234 |
public class Dialogue: ScriptableObject { public List<DialogueElement> DialogItems; } |
You can now customize the dialog resource from that conversation class by saving the Customassetutility class to a location in the project folder first.
Customassetutility class
1234567891011121314151617181920212223242526272829 |
using UnityEngine;
using UnityEditor;
using System.IO;
public static class CustomAssetUtility
{
public static void CreateAsset<T> () where T : ScriptableObject
{
T asset = ScriptableObject.CreateInstance<T> ();
string path = AssetDatabase.GetAssetPath (Selection.activeObject);
if (path ==
""
)
{
path =
"Assets"
;
}
else if (Path.GetExtension (path) !=
""
)
{
path = path.Replace (Path.GetFileName (AssetDatabase.GetAssetPath (Selection.activeObject)),
""
);
}
string assetPathAndName = AssetDatabase.GenerateUniqueAssetPath (path +
"/New " +
typeof
(T).ToString() +
".asset"
);
AssetDatabase.CreateAsset (asset, assetPathAndName);
AssetDatabase.SaveAssets ();
EditorUtility.FocusProjectWindow ();
Selection.activeObject = asset;
}
}
|
After installing this in the project, it takes only a few lines to turn the conversation class, or any class inheriting from Scriptableobject, into a custom resource.
Make a new class/file, name it DialogueAsset.cs, and make sure it is inside the editor folder. Then create a new menu item in the class for the new resource, calling Createasset from the downloaded tool class:
123456789101112 |
using unityengine; using unityeditor; using System; public class dialogueasest { &NBSP;&NBSP;&NBSP;&NBSP; [menuitem ( &NBSP;&NBSP;&NBSP;&NBSP; public static void Createasset () &NBSP;&NBSP;&NBSP;&NBSP; { &NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP; scriptableobjectutility.createasset<dialogue> (); &NBSP;&NBSP;&NBSP;&NBSP; } } |
Now you can see the option to create a new conversation when you choose Assets-Create from menu or when you click the Create button in Project view.
When you click on the newly created resource file, the Inspector view will appear with a list of dialogueelements and all of their public variables. Unlike the instantiated dialogueelements, because these are in their own resource folders, any changes you make to them will be carried out in the end, whether in the editor state or in the running state. So if the game is running in preview mode, you have changed the value, even if the game is stopped running. This technique is essentially how guiskin and other built-in assets of unity work.
To access the data from another class, assume that the class you are writing is actually displayed on the dialog screen, just make a public instance of the conversation.
123456 |
public class DialogWindow : MonoBehaviour { public Dialogue DialogueFile; //The rest of your awesome code to playback //your dialogues or use your customs assets |
Next, just specify it through inspector. Select it from the list by clicking the Small Circle, or drag and drop a new resource file in the open slot.
If you're ambitious, or just want to take extra steps, write a custom inspector class to configure how resources are presented in Inspector. If so, create a new class/file, named DialogueEditor.cs, and so on, and make sure that it is under the Editor folder. and start writing that class, like this:
1234567891011121314151617181920 |
using UnityEngine;
using UnityEditor;
[CustomEditor(
typeof
(Dialogue))]
public class DialogueEditor : Editor
{
private Dialogue D;
//Make an easy shortcut to the Dialogue your editing
void Awake()
{
D=(Dialogue)target;
}
public override void OnInspectorGUI()
{
//The rest of your awesome code to allow custom editing
// of your dialogues or other customs assets you make
.
.
.
|
The Oninspectorgui feature is then populated with code to display options for editing resources. This will be great for cleaning up and simplifying what the Inspector view shows, or for hiding options you don't want to edit. It is also useful for the team. For a team member who is not very skilled in technology, such as a script writer, says, "Look, this is really simple, just click Create a conversation and fill it out." The following describes the purpose of creating a custom inspector for this project.
However, there is a small caveat. If you write a custom inspector class for the edit resource file, or modify the value of a custom resource at another Monobehavior runtime, you need to call Unity's SetDirty method on the object you changed, as follows:
1 |
EditorUtility.SetDirty(yourInstanceOfACustomAsset); |
This is done because unity will know that the content of the object has been modified and needs to be re-serialized and saved to disk.
Now you should know how to make your own custom resources and use them as profiles.
Original link: Unity Pro tip:use Custom made assets as configuration files
Professional Unity tips sharing: Using custom resource Profiles Scriptableobject