The Unity Model Resource usage process

Source: Internet
Author: User

Yesterday, we studied Animatorcontroller automatic generation in unity. Today, the process is a little more refined, and it complements the use of model resources (ASSETBUNDLE) in an MMO, which is only needed if the model resource is very large in an MMO. If it is a relatively small case, directly into the resources directory, loading prefab is OK, do not worry about these problems at all.

Attach the final modified script. It creates a menu option, selects a folder (or file), right-selects createanimation to automatically traverse all the model resources, and then creates the Animatorcontroller and creates the prefab file. After the prefab has been generated (or at the same time as the build), you can create the Assetbundle on any directory in the disk using the function of creating assetbundle.

Using unityengine;using unityeditor;using unityeditorinternal;using system.io;using system.collections;using System.Collections.Generic;    public class Createanimation:editor {//generated PREFAB path private static readonly string Prefab_path = "assets/prefab/";    private static readonly string Path_tag = "assets/";    private static bool _ingnoreexist = TRUE; These animations are looped (except that the looping animations need to be created manually) private static readonly string[] Loop_tag = new string[] {"Idle", "Walk", "Run"}; [MenuItem ("Assets/createanimation")] static void Docreateanimation () {Unityengine.object obj = selection.act        Iveobject;        String path = Assetdatabase.getassetpath (Selection.activeobject); if (directory.exists (path)) {//If the path is Walk (path, (string fbxpath) =>{Fbxpath = Fbxpath.replace ("\ \", "/"). Replace (".                Fbx ",". Fbx ");                String relativepath = Fbxpath.substring (Fbxpath.indexof (Path_tag)); if (!relativepath.endswith (". FBX")) {return;                } docreatecontroller (RelativePath);            Docreateprefab (RelativePath);        }); } else if (file.exists (path)) {//If it is a file, string fbxpath = path. Replace ("\ \", "/"). Replace (".            Fbx ",". Fbx ");            String relativepath = Fbxpath.substring (Fbxpath.indexof (Path_tag));            if (!relativepath.endswith (". Fbx")) {return;            } docreatecontroller (RelativePath);        Docreateprefab (RelativePath); } else {//path does not exist Debug.logerror (string.        Format ("Path does not exist: {0}", path));        } Assetdatabase.refresh (); Debug.Log (String.    Format ("complete conversion: {0}", path));    }//Traverse folder delegate void Pathcallback (string path);        static void Walk (String dir, Pathcallback callback) {DirectoryInfo d = new DirectoryInfo (dir);            if (d.getdirectories () = null) {fileinfo[] allf = D.getfiles ();for (int i = 0; i < ALLF. Length; i++) {if (callback! = NULL) {callback (Allf[i].                FullName);            }} directoryinfo[] Alldr = D.getdirectories (); if (Alldr! = null) {for (int i = 0; i < Alldr. Length; i++) {Walk (Alldr[i].                FullName, callback); }}}} static void Docreatecontroller (String assetpath) {//Get Animationclip Lis        t<animationclip> clips = new list<animationclip> ();        Unityengine.object[] objects = Assetdatabase.loadallassetsatpath (Assetpath);            foreach (var obj in objects) {animationclip clip = obj as Animationclip; if (clip! = null && clip.name.IndexOf ("__preview__") = =-1) {clips.            ADD (clip); }} if (clips.        Count <= 0) {return; }//Controller file can be put together with fbx string acpath = ASSETPATH.REplace (". Fbx", ". Controller");        Create animation controller Animatorcontroller Animatorcontroller = null; The update controller cannot be updated in time, so the controller is created, but cannot be prefab alone, otherwise the association Animatorcontroller = Animatorcontroller.createanimatorco is lost        Ntrolleratpath (Acpath);        Animatorcontrollerlayer layer = animatorcontroller.getlayer (0);        Unityeditorinternal.statemachine sm = layer.statemachine;        Vector3 anystateposition = sm.anystateposition;        float offset_x = 220;        float offset_y = 60;        float item_per_line = 4;        float Originx = anystateposition.x-offset_x * (item_per_line/2.5f);        Float Originy = anystateposition.y + offset_y;        float x = Originx;        Float y = originy;        state defaultstate = null;            foreach (Animationclip newclip in clips) {string clipname = NewClip.name.ToLower (); state state = Sm.            Addstate (Clipname); Set Defaultstate, first select the Idle animation if (defaultstate = = null) {if (Clipname.indexof ("idle")! =-1)                    {sm.defaultstate = state;                Defaultstate = State;                    }} else {if (Clipname = = "Idle") {sm.defaultstate = state;                Defaultstate = State; }} foreach (var tag in loop_tag) {//Some animations I want to be born with it on the animation loop if (clipname.ind                    Exof (TAG)! =-1) {Serializedobject serializedclip = new Serializedobject (newclip); Animationclipsettings clipsettings = new Animationclipsettings (Serializedclip.findproperty ("m_                    Animationclipsettings "));                    Clipsettings.looptime = true;                    Clipsettings.loopblend = true;                    Serializedclip.applymodifiedproperties ();                Break }} state.            Setanimationclip (newclip, layer);         State.position = new Vector3 (x, y, 0);   x + = offset_x;                if (x >= Originx + offset_x * item_per_line) {x = Originx;            Y + = offset_y;    }} assetdatabase.saveassets ();        } static void Docreateprefab (String assetpath) {//Create corresponding folder string destpath = Assetpath;        if (!destpath.startswith (Prefab_path)) {DestPath = Assetpath.replace ("assets/", Prefab_path);        } String dirpath = System.IO.Path.GetDirectoryName (DestPath); if (!        System.IO.Directory.Exists (Dirpath)) {System.IO.Directory.CreateDirectory (Dirpath);        } String acpath = Assetpath.replace (". Fbx", ". Controller");        String prefabpath = Destpath.replace (". Fbx", ". Prefab"); String name = Assetpath.substring (Assetpath.lastindexof ("/") + 1).        Replace (". Fbx", "");        Create prefab Gameobject FBX = Assetdatabase.loadassetatpath (Assetpath, typeof (Gameobject)) as Gameobject; Gameobject go = Instantiate (FBX) as GamEobject;        Go.name = name; If the controller file exists, create the corresponding animator if (System.IO.File.Exists (Acpath)) {Animatorcontroller animatorcontr            Oller = Assetdatabase.loadassetatpath (Acpath, typeof (Animatorcontroller)) as Animatorcontroller; Animator Animator = go.            Getcomponent<animator> (); if (animator = = null) {animator = go.            Addcomponent<animator> ();            } animator.applyrootmotion = false;        Animator.runtimeanimatorcontroller = Animatorcontroller; }//Create Prefab if (System.IO.File.Exists (Prefabpath)) {//Replace the original prefab (each prefab has a corresponding udid cannot be used directly with the new,            Otherwise all related references will be invalidated) gameobject prefab = Assetdatabase.loadassetatpath (Prefabpath, typeof (Gameobject)) as Gameobject;        Prefabutility.replaceprefab (go, prefab); } else {//Create new Prefab Prefabutility.createprefab (Prefabpath, go, replaceprefaboptions.connecttopref        AB); } GAmeobject.destroyimmediate (go, true);    Assetdatabase.saveassets (); } class Animationclipsettings{serializedproperty M_property;private serializedproperty Get (string property) {return m_ Property.findpropertyrelative (property); }public animationclipsettings (Serializedproperty prop) {m_property = prop;} Public float StartTime {get {return get ("M_starttime"). Floatvalue;} set {get ("M_starttime"). Floatvalue = value;}}  Public float stoptime{get {return get ("M_stoptime"). Floatvalue;} set {Get ("M_stoptime"). Floatvalue = value;}} Public float Orientationoffsety {get {return get ("M_orientationoffsety"). Floatvalue;} set {get ("m_orientationoffsety" ). Floatvalue = value; }}public Float Level {get {return get ("M_level"). Floatvalue;} set {get ("M_level"). Floatvalue = value;}} Public float Cycleoffset {get {return get ("M_cycleoffset"). Floatvalue;} set {get ("M_cycleoffset"). Floatvalue = value; }} public bool Looptime {get {return get ("M_looptime"). BoolvaluE        } set {Get ("M_looptime"). Boolvalue = value;}} public bool Loopblend {get {return get ("M_loopblend"). Boolvalue;} set {get ("M_loopblend"). Boolvalue = value;}} public bool Loopblendorientation {get {return get ("M_loopblendorientation"). Boolvalue;} set {get ("M_loopblendorientat Ion "). Boolvalue = value; }}public bool Loopblendpositiony {get {return get {"M_loopblendpositiony"). Boolvalue;} set {get ("M_loopblendpositiony") ). Boolvalue = value; }}public bool Loopblendpositionxz {get {return get {"M_loopblendpositionxz"). Boolvalue;} set {get ("m_loopblendposition XZ "). Boolvalue = value; }}public bool Keeporiginalorientation {get {return get {"M_keeporiginalorientation"). Boolvalue;} set {get ("M_keeporigi Nalorientation "). Boolvalue = value; }}public bool Keeporiginalpositiony {get {return get {"M_keeporiginalpositiony"). Boolvalue;} set {get ("M_keeporiginalp Ositiony "). Boolvalue = value; }}public bool Keeporiginalpositionxz {get {return ' get {' m_keeporiginalpositionXZ "). Boolvalue; } set {Get ("M_keeporiginalpositionxz"). Boolvalue = value;}} public bool Heightfromfeet {get {return get ("M_heightfromfeet"). Boolvalue;} set {get ("M_heightfromfeet"). Boolvalue = V Alue; }}public bool Mirror {get {return get ("M_mirror"). Boolvalue;} set {get ("M_mirror"). Boolvalue = value;}}}

Here are a few points to note:

1, the generation of Animatorcontroller and prefab time is not fast, so a conversion model not too much.

2, the original can update Animatorcontroller content will be better, but did not attempt to succeed, so the controller will be created to update prefab, so that the associated information will not be lost (Miss animator)

3. When the prefab is created, the prefab is updated if it already exists. This ensures that other places where prefab are used do not lose their information. Because a new prefab is created, a new UUID is generated so that the original reference does not exist.

4, when the controller is generated, there is a judgment animationclip, if it is casual or running action, it is automatically set to loop mode. This is not handled in the script, it is necessary to make a model of their own model to modify. If you don't belong to an animation in Loop_tag, then you need to set up a loop to manipulate your changes in unity. Originally I wanted to be able to modify it through Modelimporter, but I didn't find the right method. So refer to the way of rain pine, directly modify the properties of Animationclip.


There are several benefits to this resource (assetbundle) usage process:

1, development projects will not be very large. Load the resources with the program's thinking. Otherwise a large MMO, the amount of resources may be a few grams. It will take a few minutes to run unity.

2, Assetbundle can be completely done by Fine arts, the program only care about the use of resources loading.

3, the creation of assetbundle items can be categorized. such as scene art A project, character art a project and so on. This can further reduce the project and reduce the chance of conflict.

The Unity Model Resource usage process

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.