0
\$\begingroup\$

I have two objects from the same prefab. They have bodies and swords. What good options do i have to check if a sword belongs to player2 or player1?

For example when body registers that it has been hit by a sword i need to see if its the sword belonging to the enemy or the same body.

\$\endgroup\$
1
\$\begingroup\$

I trust you are using OnCollisionEnter and/or OnTriggerEnter.

void OnCollisionEnter(Collision col)
{ 
}

Allows you to investigate the collider properly.

First, keep track of each sword's owner in the sword's script (you do have a script that you attach to swords, right?). When a sword collides with something, you:

class Sword
{
    public Player owner; //Set this when the script initializes or in the editor.
                     //It should point to this sword's owner.

    void OnCollisionEnter(Collision collision)
    { 
         //You might want to iterate through all collision points and do this check so
         //you don't miss collisions with the player if multiple collisions are registered.
          Collider col = collision.collider;
          Player player = col.gameObject.getComponent<Player>();
          if (player != null) //We hit a player
          {
                if (player != this.owner) //If we didn't hit this sword's owner.
                {
                     player.getHit(SomeDamage);
                }
          }
    } 
}

To set the sword's owner you can just drag & drop the owner's GameObject in the sword's owner property field. Alternatively, if you're instantiating characters dynamically at runtime, you can search for the sword's owner and set it appropriately. Here's a function that will work in any hierarchy:

private void setOwner()
{
     Transform tr = this.transform.parent;
     bool foundParent = false;
     while ((tr != null) && (!foundParent))
     {
            Player player = tr.gameObject.getComponent<Player>();
            if (player != null)
            {
                 this.owner = player;
                 foundParent = true;                     
            }
            tr = tr.transform.parent;
     }
}

This will go up in the hierarchy to find the closest Player, which becomes the sword's owner. If no suitable owner is found, the owner field keeps its default value, null. If you can guarantee the owner of the sword is the direct parent GameObject, you can instead ditch the hierarchy travelling and just do

this.owner = this.transform.parent.gameObject.getComponent<Player>().

Do all of this inside OnStart().

\$\endgroup\$
5
  • \$\begingroup\$ How would you go about letting each script now who they are attached to? \$\endgroup\$ – Daarwin Oct 20 '13 at 14:23
  • \$\begingroup\$ Sorry i need to clarify. My players are a hierarchy of objects. How can all scripts attached on objects belonging to player 3 know that they are attached to player 3? Sometimes they are 3 levels down in the hierarchy. \$\endgroup\$ – Daarwin Oct 20 '13 at 14:34
  • \$\begingroup\$ See my updated answer. Mainly the setOwner() method. \$\endgroup\$ – user15805 Oct 20 '13 at 14:36
  • \$\begingroup\$ GREAT! However i did it the opposite way. OnStart Player goes all down its transform hierarchy and sets all body parts owner to itself. Thanks for your help! \$\endgroup\$ – Daarwin Oct 20 '13 at 15:19
  • \$\begingroup\$ That works too :) No problem. \$\endgroup\$ – user15805 Oct 20 '13 at 15:20
0
\$\begingroup\$

Either set a specific tag on each sword (I.e PlayerSword and Player2Sword) and then test which one is the one colliding with an if statement.

The other option is to use transform.parent.gameobject.tag This way is different than the previous method as it checks the tag of whatever game object is the parent. So if each player has a tag then this will work.

All you have to do now is just handle the events when they collide however you'd like.

Let me know if you have any questions.

\$\endgroup\$
5
  • \$\begingroup\$ I wouldn't use tags. Too many tags would result in an unmanageable collection of tags. Also, if you used the Player2Sword tag on EVERY enemy's sword (to reduce the number of tags), you'd be getting a counter-intuitive solution (why does every... orc's sword have a Player2Sword tag?). Using tags like "PlayerWeapon" or "EnemyWeapon" can fix this. But: further, what if the sword's parent is the player's arm instead of the player itself? The solution is too localized to serve in general purpose situations. \$\endgroup\$ – user15805 Oct 20 '13 at 14:12
  • \$\begingroup\$ @AlexM. i agree. There has to be a better solution. I just need something that will say "Hi, im attached to orc1". \$\endgroup\$ – Daarwin Oct 20 '13 at 14:22
  • \$\begingroup\$ Using object names is usually not a good idea because these can change easily while you are working in the editor, and break the game. Also note that each gameobject that comes from an Instantiate(...) call, will have a name like BaseGameObject (Clone). \$\endgroup\$ – user15805 Oct 20 '13 at 14:24
  • \$\begingroup\$ How I'd do it: define a base class for all the characters that can be hit by swords. Call it GameCharacter. Player and Orc would inherit from GameCharacter. See my answer above, but instead of using the Player class, use the base GameCharacter to check for collision with any GameCharacter. If the GameCharacter your sword hit is not the sword's owner, you're good to go and can apply damage. \$\endgroup\$ – user15805 Oct 20 '13 at 14:25
  • \$\begingroup\$ I wouldn't use classes, I would use interfaces for this. And I would only have it so when the collision is triggered it checks the parent hierarchy for anything with an interface you defined. Either way both mine and Alex M's method will work. \$\endgroup\$ – Max McKinney Oct 20 '13 at 15:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.