How to change weapons

Hello everyone. I am developing a RPG fighting game using unity5. And I want to change my hero’s weapon when it hits the weapon of my scene. So I have a weapon prefab like this:

It has mesh renderer component.
And my hero looks like this:
Upload and share screenshots and images - print screen online | Snipboard.io.
It has a sword as a child of his right hand.
Please how can I change the sword to the weapon shown in the first picture.
I noticed that some blog show a way which is changing the skinned mesh render, but my weapon does not have skinned mesh render component. Is there another way to do this?

There are many ways of doing this. I would approach this problem in this way:

  • create seperate prefabs for every weapon you need
  • create character controller script
  • in this script, expose a public transform and call it Hand and another public transform called Weapon
  • place hand transform into Hand in your script and sword transform into Weapon slot
  • when you hit a weapon in the scene, destroy sword assigned to Weapon
  • then, assign scene weapon into Weapon and do transform.parent = Hand ( Unity - Scripting API: Transform.parent )
  • and to make sure, that your Weapon is aligned to the Hand do:
    Weapon.position = Vector3.zero;
    Weapon.rotation.EulerAngles = Vector3.zero;
1 Like

Thank you very much for your reply and I tried in your way which can solve my problem.
I have three more questions,

  1. When I destroy the old weapon, I cannot use transform component, so I must expose the GameObject of the old weapon instead of Transform, is that right?
  2. I set my new weapon’s position to Vector3.zero, but when I run my game, I saw that my new weapon’s position is not (0, 0, 0), do you know the reason? Here is my script:
public void ChangeWeapon(GameObject newWeapon)
    {
        Destroy (weapon);
        newWeapon.transform.parent = hand;
        newWeapon.transform.position = Vector3.zero;
    }
  1. This way really helps. But In some condition, I only want to change the mesh renderer of the weapon instead of changing the whole gameobject, cause there are some extern component in the weapon which I don’t want to add to the new weapon repeatedly. How can I do this?
    I really appreciate for your reply.

For question 2, I’ve known the reason. I should set the local position instead of the position. Thank you!

  1. Not really. Take a look at Transform class in Unity API http://docs.unity3d.com/ScriptReference/Transform.html

Inherited members
Variables
gameObject The game object this component is attached to. A component is always attached to a game object.

It means that you can do this: Destroy(Weapon.gameObject);

  1. You got it right - my code was wrong and you should set localposition, not position which is in world space :wink:
  2. You should use GetComponent function on your current weapon and on weapon in the world and assign world weapon renderer into current weapon renderer.

Renderer renderer = Weapon.gameObject.GetComponent();
Renderer worldWeaponRenderer = worldWeapon.gameObject.GetComponent();
renderer = worldWeaponRenderer;

I tried in your way to change the renderer, it seems doesn’t work. The renderer component can be assigned in this way? I doubt it. I am newbie in c#, but I am experienced in c++. Is the renderer variable a value copy of Weapon’s renderer component?
When the weapon has SkinnedMeshRenderer component, I know this can work:

 GameObject weapon1 = GameObject.FindWithTag ("weapon");
MyskinMeshRender = weapon1.GetComponent<SkinnedMeshRenderer>();
GameObject weapon2 =
Instantiate (Resources.Load("weapon2Name"))as GameObject;
SrcSkinMeshRender = weapon2.transform.GetChild(1).GetComponent<SkinnedMeshRenderer>();
MyskinMeshRender.sharedMesh = SrcSkinMeshRender.sharedMesh;
Destroy (weapon2);

But my weapon don’t have SkinnedMeshRenderer.
Am I wrong? Thank you

SkinnedMeshRenderer and regular Renderer are not the same thing. I don’t know how to assign mesh from skinned renderer to regular renderer and vice versa. Maybe you could copy Mesh of Mesh Filter in world weapon, get materials list from Mesh Renderer and copy these values into Skinned mesh equivalents?

You can’t access renderer via transform.gameObject.renderer, but you can use Destroy function with transform.gameObject. To access renderer you should use GetComponent. You can also use GameObject for Weapon instead of Transform and do Weapon.GetComponent instead of Weapon.gameObject.GetComponent or Weapon.renderer. Pick the one that suites your needs.

In most cases, C# is creating references. Most likely " Renderer1 = Renderer2 " will create a reference to Renderer2. I think that you could use “new” keyword. I’m not c# guru but I think that there are some workarounds for this.

I’m not a coder - but I’m pretty knowledgeable about character rigging and skinning.
Best not to get into skinned mesh renderer just to swap out weapons, it’s overly complicating/bloating the process.

Suggest using varfare’s solution and knuckling down to setup all the weapons with the proper (external components) elements - then the weapon switch will work on all weapons regardless of the condition of the weapon.