如何在Unity3d中运行时在GameObject上加载脚本,材质?

时间:2014-07-22 23:26:57

标签: android unity3d unityscript

我是Unity3d和JS脚本的新手,我需要帮助来合并我正在开发的应用程序中的场景和代码这是我的场景的概念:

有一个通过图层蒙版看到的相机,三个平面。还有一种材料用作交换纹理,以及在每个平面上分别运行此交换的脚本。为了运行这个脚本,我使用带有滚动列表按钮的GUI,所以当按下button1时,摄像头只能看到plane1,而script1会在这个平面上运行纹理材质1。按下相应的按钮,在其他2个平面上也会发生相同的情况。您可以在附图1中看到这个概念:

enter image description here

我需要你的帮助,是通过只保留一个相机的平面来简化这个场景,并附加相应的脚本(1,2,3等),材料作为纹理(1,2,3)等等,当玩家在运行时触摸相应的GUI按钮时,在同一平面上。需要提一下的是,GUI按钮位于附加到空GameObject的名为“GUI”的脚本上,而我需要动态附加的脚本和材料位于名为“Animator”的GameObject上,作为Camera的子项。您可以在附图2中看到这个概念。

enter image description here

我相信这个功能可以通过使用例如“gameObject.AddComponent(”myScript“)”,但由于我是一个菜鸟,我无法实现。此外,我不知道如何在运行时在这个平面上应用不同的材料。所以我需要一些帮助和一个编码示例,因为我发现很难只看到提示而没有看到一个例子。

感谢大家抽出时间阅读这篇文章,希望有人能够帮助我解决这个问题。

修改1

好吧,为了让任何人愿意提供帮助更加全面,并且在我之后通过他们的答案得到帮助,我会发布Hierarchy和Inspector的截图,以及Unity项目的代码片段。

在图3中,Hierarchy的视图,我显示,脚本“ShowAnimation”在gameObject“Animation_Buttons_Controller”上。通过这个脚本,我想访问例如父对象游戏对象“AnimationCamera”中的gameObject子“Animator2inScene2”。

enter image description here

在图像4中,Inspector视图,我显示了材质元素“Texture_Animator2_Material”,以及应该仅在运行时添加到此gameObject上的脚本“ScriptTextureAnimator2”。

enter image description here

以下是脚本“ShowAnimation.js”中的代码片段,该代码片段必须访问gameObject子元素“Animator2inScene2”并在此gameObject子元素上添加材质元素“Texture_Animator2_Material”和脚本“ScriptTextureAnimator2”:

if (GUI.Button (Rect (2,2,100,20), "PlayAnimation2")) 
            {
            var addScriptOnPlane2 : GameObject[] = GameObject.FindGameObjectsWithTag("Animator");     
            //for(var addTextureScript2 : GameObject in addScriptOnPlane2)

if(addScriptOnPlane2)
            { 

            // Adds the script named ScriptTextureAnimator2 to the game object child "Animator2inScene2"
            gameObject.AddComponent("ScriptTextureAnimator2");

            // Adds the script named Texture_Animator2_Material to the game object child "Animator2inScene2"
            var addMaterial : Material;

            addMaterial = Resources.Load("Materials/Materials/Texture_Animator2_Material",typeof(Material)) as Material;

}
}

问题是在游戏中,我没有在gui按钮上执行任何功能,并且在控制台中出现以下错误:

” NullReferenceException:未将对象引用设置为对象的实例 ScriptTextureAnimator2.FixedUpdate()“

我知道,我错过了一些对编译至关重要的东西,但可能是什么呢?请查看并发布关于我的编码的建议。谢谢。

2 个答案:

答案 0 :(得分:1)

我真的很感谢你用这个问题制作图片,从而使阅读更加愉快:)

要在运行时更改脚本,您需要销毁旧脚本并添加新脚本:

销毁旧脚本:

Destroy(plane.GetComponent(TestScript)); // get component of type TestScript

添加新脚本:

plane.AddComponent(TestScript); // add component of type TestScript

要在运行时更改材料:

为材料准备全局变量,并使用检查器中的材料进行分配:

var material1 : Material;
var material2 : Material;
var material3 : Material;

然后您可以将材料更改为您选择的材料,如下所示:

plane.renderer.material = material1; // change plane material to material1

看到你的例子,这些脚本将放在GUI Button中 因此,您需要在GUI按钮脚本中创建一个公共游戏对象变量,以便您可以将平面分配给它。 请注意,在上面的代码中,我总是将plane写为基类,这就是我对GUI按钮中公共游戏对象的意义。

只需声明plane游戏对象变量,如下所示:

var plane : GameObject;

并在检查员处为其指定平面物体。

希望这有帮助!

编辑1:
该错误可能是由于您的代码段错位造成的 您是否已将功能置于OnGUI()? 我修改了您的代码以满足您的需求:

function OnGUI () {
    if (GUI.Button (Rect (2,2,100,20), "PlayAnimation2")){
        var addScriptOnPlane2 : GameObject[] = GameObject.FindGameObjectsWithTag("Animator");     

        for(var addTextureScript2 : GameObject in addScriptOnPlane2)
        { 
            // Adds the script named ScriptTextureAnimator2 to the game object child "Animator2inScene2"
            addTextureScript2.AddComponent("ScriptTextureAnimator2");

            // Adds the script named Texture_Animator2_Material to the game object child "Animator2inScene2"
            var addMaterial : Material;

            addMaterial = GameObject.Instantiate(Resources.Load("Materials/Materials/Texture_Animator2_Material",typeof(Material))) as Material;

            addTextureScript2.renderer.material = addMaterial;
        }
    }
}

请注意,要将脚本和材质添加到所需的游戏对象,如果要从其他游戏对象中执行此操作,则必须指定该游戏对象的变量。

gameObject.AddComponent("ScriptTextureAnimator2"); 
// gameObject = this.gameObject = Animation_Buttons_Controller gameobject
// change it to addTextureScript2.AddComponent("ScriptTextureAnimator2"); 

我还指定了您之前没有做过的材料 请注意,Resources.Load会在Resources中搜索目录Assets,因此请务必将您的资料放入其中。

答案 1 :(得分:0)

添加脚本。

TestScript newScript = gameObject.AddComponent<TestScript>();

最新版本的Unity允许在同一个游戏对象上使用多个脚本实例。

添加材料。

在项目中创建“Resources”文件夹,并在此文件夹中创建一个新材料“TestMaterial”。您可以使用Resources例程在运行时加载此材料:

Material testMaterial = Resources.Load( 
   "TestMaterial", 
   typeof(Material) 
) as Material;

您可以在“资源”中添加子文件夹“材质”,并将TestMaterian放入此子文件夹中:

Material testMaterial = Resources.Load( 
   "Materials/TestMaterial", 
   typeof(Material) 
) as Material;

请注意,此加载的材料是共享材料。即如果在运行时更改它,更改将保存在项目中。您仍然可以将此材质放在任何渲染器上,但必须使用sharedMaterial属性:

this.renderer.sharedMaterial = testMaterial;

如果您想避免在运行时更改共享材料,则必须创建一个实例:

Material testMaterialInstance = GameObject.Instantiate( Resources.Load(
   "Materials/TestMaterial", 
   typeof(Material) 
) as Material ) as Material;

现在您可以安全地更改此材质,并且可以使用材质属性放置到渲染器:

this.renderer.material = testMaterialInstance;