Just a quick question. I’ve got an object that I wish to make copies of, which should have the same material as the original, just in a different main color. Here’s what I do:
At the final command I get an error saying “Material doesn’t have a color property called ‘_Color’”. Yet, my template object does have a material with a main color…anybody know what I’m doing wrong?
You can just change the main color of the material on an object directly without instantiating a separate material like that. Each object will get its own material automatically…you have to change sharedMaterial if you want the change to affect every object that has that material.
Edit: I should point out that the materials created that way exist in the scene, but not on disk. They go away when you stop the scene. (Well, normally they go away…I had a project a while ago that somehow had a “scene” material stick around permanently…not sure if that was a bug or what…)
Assuming you’ve declared “var newColor : Color” in your script, just do this, and pick a color in the inspector:
What if you want to do this same thing to Prefabs? How would you do GameObject.(Prefab Name) and create many of those programatically on the scene?
What method would I use?
Edit:
I tried this technique on a prefab, didn’t work, got the error:
Cannot implictily convert type ‘UnityEngine.GameObject’. An explicit conversion exists (are you missing a cast?)
So I tried a different technique and got the same error
This was my code:
using UnityEngine;
using System.Collections;
public class SetupObjects : MonoBehaviour {
GameObject generic;
GameObject clone;
// Use this for initialization
void Start () {
generic=GameObject.Find("SpritePlane");
Vector3 tmpVec=generic.transform.position;
Debug.Log(tmpVec[0]);
tmpVec[0]=0;
generic.transform.position=tmpVec;
Vector3 pos;
for (int i=0;i<10;i++){
pos[0]=i*20;
pos[1]=0;
pos[2]=0;
clone=Instantiate(Resources.Load("SpritePlane"));
clone.transform.position=pos;
}
}
// Update is called once per frame
void Update () {
}
}
I have 4 different objects where they are dynamic on the board. I have 1 row of invaders of type A, 2 rows of invaders of type B, and 2 rows of invaders of type C, and a final row of bunkers. These each have only 1 prefab that is assigned to them to define there properties. The invaders are all 5 rows with synch movement, so that I determine the edge of any row which determines the edge of the entire collection so they stay in sync on hitting the edge properly.
I do this control for the entire collection set through code, I want to add a prefab through code to the game grid, I don’t want to put 1 prefab on each row then clone it that way, I would rather initiate each prefab individual in an array.
The instansiation seems to only work and clone only works if you have a minimum of 1 already existing element on the screen. Which I think should not be the case.
Correct, that’s not the case. Prefabs don’t have to exist in the scene to work. They just have to exist in your project somewhere. I always make a folder called “prefabs” and stick them in there (and then for the sake of organization, I make subfolders if there get to be a lot of them). You can drag them into the scene, or drag them onto slots in scripts in the inspector and instantiate them from code that way. Or both.
This translated from boo (which all my code is in) so my have some syntax errors
but instead of using a resources.load have you tried using a public variable and dropping the prefab on it in the editor?
var sprite : Transform;
....
for (int i=0;i<10;i++){
vec =Vector3(i*20,0,0);
clone=Instantiate(sprite,vec,Quaternion.identity);
}
I instantiate most of my game objects with code either in game or with editor called custom functions.
The error is exactly what it says. You are trying to assing an an object of tpye Object to a variable of type GameObject and since GameObject is a subclass of Objectyou have to explicitly downcast the object. I.e.
If I were doing a Space Invaders clone, I’d probably set it up like this:
var invaders : GameObject[];
var bunker : GameObject;
var rows : int = 5;
var columns : int = 11;
var speed : float = 1.5;
private var invaderClone : GameObject[];
function Start () {
invaderClone = new GameObject[columns * rows];
whichInvader = 0;
for (y = 0; y < rows; y++) {
for (x = 0; x < columns; x++) {
invaderClone[x+(y*columns)] = Instantiate(invaders[whichInvader/2], Vector3(x*5, (y+6)*5, 0), Quaternion.identity);
}
whichInvader = Mathf.Clamp(++whichInvader, 0, invaders.Length+1);
}
for (x = 0; x < 4; x++) {
Instantiate(bunker, Vector3(x*15+10, 5, 0), Quaternion.identity);
}
}
That would do your classic 5X11 group of enemies arranged 1/2/2 by type. And then you could move them around like this:
var move : float = speed * Time.deltaTime;
for (i = 0; i < rows*columns; i++) {
if (invaderClone[i]) {invaderClone[i].transform.Translate(Vector3.right * move);}
}
Or something. Hmm…it occurs to me that I’ve never actually made a Space Invaders clone ever. Maybe I should do something with that.
This all sounds like cool code in javascript, I’ll look over your method. I took the ‘long way’ around this at the moment. So far, I have successfully gotten my 5 rows finished, haven’t worked out the movement yet, sketching it out now. That and I haven’t gotten around to a main menu or options yet. Here is my code thus far that creates 5 rows of enemy ships. I had to do the initial positioning manually since I can’t use Screen.width or Screen.height, which is odd, I should be able to do that, but it doesn’t work for orthographic space, thats totally different dimensions, and seems ortho is based on cube space.
using UnityEngine;
using System.Collections;
public class SetupObjects : MonoBehaviour {
GameObject generic;
GameObject clone;
Vector3 tmpVec;
Vector3 pos;
Vector3 modScale;
// Use this for initialization
void Start () {
// setup our invaders
setupHighRow();
setupMidRow();
setupLowRow();
}
// Update is called once per frame
void Update () {
}
void setupHighRow(){
for (int i=0;i<10;i++){
clone=(GameObject) Instantiate(Resources.Load("pInvaderHigh"));
modScale=clone.transform.lossyScale;
pos[0]=(i*15)-modScale[0]-20;
pos[1]=(modScale[1]-20);
pos[2]=0;
clone.transform.position=pos;
}
}
void setupMidRow(){
for (int iY=0;iY<2;iY++)
{
for (int i=0;i<10;i++){
clone=(GameObject) Instantiate(Resources.Load("pInvaderMid"));
modScale=clone.transform.lossyScale;
pos[0]=(i*15)-modScale[0]-20;
pos[1]=modScale[1]-(30+(iY*10));
pos[2]=0;
clone.transform.position=pos;
}
}
}
void setupLowRow(){
for (int iY=0;iY<2;iY++){
for (int i=0;i<10;i++){
clone=(GameObject) Instantiate(Resources.Load("pInvaderLow"));
modScale=clone.transform.lossyScale;
pos[0]=(i*15)-modScale[0]-20;
pos[1]=modScale[1]-(50+(iY*10));
pos[2]=0;
clone.transform.position=pos;
}
}
}
void setupBunkers(){
for (int i=0;i<10;i++){
clone=(GameObject) Instantiate(Resources.Load("pBunker"));
modScale=clone.transform.lossyScale;
pos[0]=(i*10)-modScale[0]-20;
pos[1]=(modScale[1]-80);
pos[2]=0;
clone.transform.position=pos;
}
}
void setupLives(){
for (int i=0;i<10;i++){
clone=(GameObject) Instantiate(Resources.Load("pGun"));
modScale=clone.transform.lossyScale;
pos[0]=(i*10)-modScale[0]-20;
pos[1]=(modScale[1]-85);
pos[2]=0;
clone.transform.position=pos;
}
}
}
Ortho units are different than scale units for width and height.
I’ve been expanding on the 2d little demo app. I made prefabs off all my core elements, then placed them in a folder called Resources under my assets folder, this way I could load them with Resource.Load just fine. This is a pic so far of the end result of this effort.
Nifty. I like the color scheme. Though I’d recommend using prefabs, so all you have to do is drag them onto slots in the inspector. That makes changing them easy, instead of having to change your code, plus you can easily do arrays and stuff. But whatever works.
Here’s mine…it’s sort of done, except the bunkers don’t do anything, and it needs a title screen and sound effects. Plus it’s just a bog-standard space invaders clone with a 3D background. I have an idea that might make things more…interesting. I’ll probably work on that tomorrow.
LOL showoff (just kidding, nice work)
Nice so far, atleast you got the movement and collision working, I was hoping to have my first level done tonight, but I haven’t figured out how to display the score like you have or give a flat menu yet. This is all just for a learning experience on 2d for unity.
Zumwalt, I hope you aren’t missing the suggestions about simply making your clone GameObject public. Then you can just drag the prefab you want right into your script properties. You won’t have to place it in the workspace, just the script. I’d hate for you to develop a habit with that Resource.Load() stuff when it’s completely unnecessary and probably troublesome in the future.
I am not missing the suggestion, I just don’t understand the suggestion yet. When I drag a prefab into the script, it gives the full file path to the object, which is useless to me. So after I get done with this little project, I’ll post the entire thing then ask for criticism on it and ask what I did wrong and how I might improve on it.
I am taking this one step at a time. As it stands the only “static” things in the game are the cubes that spin. 100% of all game objects are dynamically built through script on a ‘script manager’ cube I created.
That’s just a GUIText object. Also I should use a more appropriate font (that’s the default Gooball font). I ended up kind of “cheating” and assigning a number to each invader’s name that corresponded with the score you get when it’s destroyed (i.e., “10”, “20”, or “30”). Then all I had to do was add that to the score by getting collider.name when the player’s missile hit something. Cheap trick, but that’s the only property I needed, so I didn’t have to bother with other classes or arrays or anything…
Me too…I hadn’t done it before. Not much to it really. As far as prefabs, maybe take another look at the script I posted. I’ll post my project as well when I’m done fiddling with stuff. (I think it needs some cool particle effects…)
I use an empty game object for that sort of thing. That way you don’t have to worry about the cube somehow showing up.
My cube is behind the camera, so its not going to show up.
I’ll throw in some generic sounds for it when I get past my IL error I have right now. Firing, explosion, etc. Keeping it retro.
I am going on a 3 week old unity user. (as in, only had this for like 3 weeks I think) once I get over each hump of the nooks and cranies, its rather simple to use.
Don’t drag the prefab to the script editor itself. Rather, create a public variable, which will be exposed in the Unity IDE’s inspector, and drag to link it there.
For instance, if you have a public variable of type RigidBody, you can drag any GameObject with a RigidBody component to that variable slot in the inspector.
Don’t take this the wrong way, but you really should take a step back and absorb all of the documentation and tutorials. A solid foundation will serve you well.