- Home /
Changing one object into another
I have a scene in Unity where it is required to choose from three different projectiles. Each one already exists on the stage and has different settings for mesh, materials, rigid body and so on. These projectile objects are to represent wood, metal and rock.
I have a fourth object on the scene which is loaded on to a catapult. By default it is a carbon copy of the wood projectile. I want to be able to swap its attributes with those set by the other projectiles on the scene so that it takes their form, rigid body(mostly for a change in mass) and material. The scaling of each object is the same so this one isn't needed. So far I have this but it doesn't seem to work...
var projectile : GameObject; var rigid : Rigidbody;
var woodrenderer : MeshRenderer; var woodcollider : MeshCollider; var woodfilter : MeshFilter; var woodtexture : Texture2D; var woodmaterial : Material;
var stonerenderer : MeshRenderer; var stonecollider : MeshCollider; var stonefilter : MeshFilter; var stonetexture : Texture2D; var stonematerial : Material;
var metalrenderer : MeshRenderer; var metalcollider : MeshCollider; var metalfilter : MeshFilter; var metaltexture : Texture2D; var metalmaterial : Material;
function Update () { if(Input.GetKey ("1")) { projectile = new GameObject ("Projectile"); projectile.tag = "projectile";
woodcollider = projectile.AddComponent("MeshCollider");
woodrenderer = projectile.AddComponent("MeshRenderer");
rigid = projectile.AddComponent("RigidBody"); projectile.rigid.mass = 1;
woodfilter = projectile.AddComponent("MeshFilter"); projectile.renderer.material.mainTexture = woodtexture;
}
if(Input.GetKey ("2")) { stonecollider = projectile.AddComponent("MeshCollider");
stonerenderer = projectile.AddComponent("MeshRenderer");
rigid = projectile.AddComponent("RigidBody"); projectile.rigid.mass = 20;
stonefilter = projectile.AddComponent("MeshFilter"); projectile.renderer.material.mainTexture = stonetexture; }
}
the code for the switch to metal isn't added in yet as i was only testing between rock and wood.
Could anybody help with this? I can provide more info if needed.
Answer by JinxM · Feb 28, 2012 at 09:28 PM
2 things I would do to make this easier: First, instead of having variables for all the components, make a Prefab for each of the wood, stone, and metal projectiles. Then you can Instantiate(woodPrefab, position, rotation) each time instead of making a game object from scratch.
Second, to answer your question about the catapult, using the method above makes this simple. You would just Instantiate a new prefab of the appropriate type in the catapult (in the same position/rotation), Destroying the old one if necessary.
How would I make this prefab? The three objects on the stage are prefab objects belonging to the project folders.
Oh I've already been working with a lot of prefabs. I'll try instantiating in a new script
so would this work?
var projectile : GameObject; var Log : GameObject; var Boulder : GameObject; var $$anonymous$$etal : GameObject;
function Update () { projectile.tag = "projectile"; if(Input.Get$$anonymous$$ey ("1")) { Instantiate(Log, projectile.position, projectile.rotation); }
if(Input.Get$$anonymous$$ey ("2")) { Instantiate(Boulder, projectile.position, projectile.rotation); }
if(Input.Get$$anonymous$$ey ("3")) { Instantiate($$anonymous$$etal, projectile.position, projectile.rotation); }
}
Looks a lot cleaner! You can set the tag on the Projectile prefab so you don't need to do it in code.
I'm not certain precisely what your game is, so the code can vary but I'm imagining it's a Crush the Castle sort of game where you choose ammo for your catapult?
Here's your code above with a few edits I'll explain after:
var ammoOrigin : Transform;
var log : GameObject;
var boulder : GameObject;
var metal : GameObject;
var currentProjectile : GameObject;
function Update () {
if(Input.Get$$anonymous$$ey ("1"))
{
LoadAmmo(log);
}
if(Input.Get$$anonymous$$ey ("2"))
{
LoadAmmo(boulder);
}
if(Input.Get$$anonymous$$ey ("3"))
{
LoadAmmo(metal);
}
}
function LoadAmmo( ammoType : GameObject) {
if (currentProjectile)
{
Destroy(currentProjectile);
}
currentProjectile = Instantiate(ammoType, ammoOrigin.position, Quaternion.identity);
}
Okay, so the things I changed: 1) LoadAmmo function: Anytime you have repeated code, an alarm should go off in your head that that's something that could be a seperate function. :) $$anonymous$$inor style point, not a big deal. Along the same lines, variables should use camelCase (start with lowercase) but that's even less of a big deal.
2) projectile is now ammoOrigin. We were only using that variable to know where to place the new log/boulder/metal object, so we might as well just use the transform. (Link this to an empty gameobject in the Inspector, which you can then move around as you like)
3) Instantiate returns the created gameobject, so I'm using that (saved as currentProjectile) to know what object is sitting in the catapult scoop currently. This lets me destroy an existing one if I want to switch my ammo.
NOTE: I didn't think of it until now, but you'll want to remove the currentProjectile's reference when you fire the projectile, assu$$anonymous$$g it sits in the scene for a while, otherwise you'll Destroy it the next time you switch ammo. Easy enough to do with a currentProjectile = null; line in your Fire() function. :)
Answer by dhoko · Nov 14, 2012 at 04:06 AM
i hope this work becuse i want to prove it D: it is becuse i got a doric column and the column in a destruction animation i want to react column to collision