I'm new to Unity3d and in JS scripting and I need help to symplify a scene and code in the app I'm developing Here is the concept of my scene:
There is a Camera, that sees through layer masking, three planes. Also there is a material that acts as a swapping texture, and a script that runs this swapping respectively on each plane. In order to run this script, I use a GUI with a scroll list buttons, so when button1 is pressed, camera sees only plane1 and the script1 runs the texture material1 on this plane. The same happens on the other 2 planes by pressing the corresponding buttons. You can get a view of this concept in the attached image 1:
What I need your help for, is to simplify this scene by keeping only one plane for the camera to be seen, and attaching the respective scripts (1, 2, 3 etc), material as texture (1, 2, 3 etc) on this same plane when the player touches the corresponding GUI buttons, in runtime. Need to mention though that the GUI buttons are on a script named "GUI" attached to an empty GameObject and the script and materials I need to a dynamically attach, are on a GameObject named "Animator" as a child to a Camera. You can get a view of this concept in the attached image 2.
I believe this functionality can be achieved by using e.g. "gameObject.AddComponent ("myScript")" , but as I'm a noob, I cannot make it happen. Furthermore, I do not know how to apply the different material on this plane in runtime. So I need some help and a coding example maybe, as I find it difficult to follow only tips without seeing an example.
Thank you all for your time reading this post, hope someone be kind enough to help me on this matter.
Edit 1
Well, in order to make it more comprehensive for anyone willing help, and for me be helped afterwards by their answers, I'm posting screenshots of Hierarchy and Inspector, plus a code snippet of Unity project.
In image 3, view of Hierarchy, I'm showing that, script "ShowAnimation" is on gameObject "Animation_Buttons_Controller". Through this script, I want to access e.g. gameObject child "Animator2inScene2" in parent gameObject "AnimationCamera".
In image 4, view of Inspector, I'm showing the material element "Texture_Animator2_Material", and the script "ScriptTextureAnimator2" that should be added on this gameObject only in runtime.
Following is the code snippet in script "ShowAnimation.js" that has to access gameObject child "Animator2inScene2" and add material element "Texture_Animator2_Material" and the script "ScriptTextureAnimator2" on this gameObject child:
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;
}
}
Problem is that on play, I get no function on gui button and the following error in console:
" NullReferenceException: Object reference not set to an instance of an object ScriptTextureAnimator2.FixedUpdate ()"
I know, I've missed something vital for compilation, but what may that be? Please take a look and post a recommendation on my codding. Thank you.
Adding scripts.
Newest versions of Unity allows to multiple instances of the script on the same game object.
Adding materials.
Create "Resources" folder in your project and create a new material "TestMaterial" in this folder. You can load this material in runtime using Resources routine:
You may add subfolders "Materials" to your "Resources" and place TestMaterian in to this subfolder:
Note that this loaded material is a shared material. I.e. if you change it in runtime the changes will be saved in project. You still may place this material on to any renderer but you must use sharedMaterial property:
If you want to avoid changing shared material in runtime you must create an instance:
Now you can safely change this material and you can place in on to renderer using material property:
this.renderer.material = testMaterialInstance
;I really appreciate you for making pictures out of this question, thus making it more enjoyable to read :)
To change your script at runtime, you need to destroy the old script and add the new one:
Destroy the old script:
Add the new script:
To change material at runtime:
Prepare global variables for your material and assign it with the materials from the inspector:
Then you can just change your material to the material of your choice like this:
plane.renderer.material = material1; // change plane material to material1
Seeing your example, these scripts will be put inside the GUI Button.
So you'll need to make a public game object variable inside GUI button scripts so that you can assign your plane to it.
Notice that in the code above I always write
plane
as the base class, that is what I meant about the public game object in the GUI button.Just declare the
plane
game object variable like this:And assign it your plane object at the inspector.
Hope this helps!
EDIT 1:
That error is possibly caused by misplacement of your code snippet.
Have you placed your function to
OnGUI()
?I have modified your code to match your needs:
Note that to add the script and material to the gameobject you want, you must specify the variable of that gameobject if you want to do it from other gameobject.
I have also assign the material which you haven't done before.
Please note that
Resources.Load
will search for directoryResources
inAssets
, so make sure you put your material in there.