Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by MrPantaIoons · Apr 15, 2015 at 07:42 PM · destroycolliderstriggering animation box collider

Colliders/Triggers going through each other

I'm making a game, similar to the game Cartoon Wars (don't know if you've heard of it) and Plants vs Zombies. You set down your troops and they attack your enemy's base, while your enemy is attacking yours.

It is working fine, except for one problem. When the enemies or defenders get stacked up to each other, and one of them dies, it registers to the other side that their target has been killed and they continue walking right past the enemies in front of them. Basically, they think that since they killed one guy, the rest in front of them are dead, too.

Here's my code for the Defenders (the Attacker code is basically the same. I have Kinematic Rigidbody2Ds and Box Collider2Ds with Triggers set on them). using UnityEngine; using System.Collections;

public class Defenders : MonoBehaviour {

  public int cost = 50;
  
  private float defenderSpeed;
  private Animator anim;
  private bool standGuard;
  private GameObject defenderTarget;
  
  void Start () {
      defenderSpeed = .5f;
      anim = GetComponent<Animator>();
  }
  
  void Update () {
      transform.Translate (Vector3.right * defenderSpeed * Time.deltaTime);
      if (!defenderTarget) {
          defenderSpeed = .5f;
          anim.SetBool ("isAttacking", false);
      }
  }
  
  
  
  void OnTriggerEnter2D(Collider2D collider) {
      GameObject obj = collider.gameObject;
      defenderTarget = obj;
      
      if (obj.GetComponent<Attacker>()) {
          defenderSpeed = 0f;
          anim.SetBool ("isAttacking", true);
      }
  }
  
  
  void OnMouseDown() {
      if (standGuard == true) {
          anim.SetBool ("standGuard", false);
          standGuard = false;
      } else if (standGuard == false) {
          anim.SetBool ("standGuard", true);
          standGuard = true;
      }
  }
  
  
  
  public void StrikeCurrentTarget (float damage) {
      if (defenderTarget) {
          Health health = defenderTarget.GetComponent<Health>();
          if (health) {
              health.DealDamage (damage);
          }
      }
  }
  
  public void Attack (GameObject obj) {
      defenderTarget = obj;
  }

}

Is there a way that I can make the unit check to make sure there isn't another unit in front of him before carrying on?

Comment
Add comment · Show 4
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image AlwaysSunny · Apr 15, 2015 at 07:16 PM 0
Share

$$anonymous$$inematic rigidbodies and triggers are unhindered by collisions. It sounds as though you do not want collisions to be possible anyway, since apparently your game should never allow a collision to occur in the first place. Otherwise, where is the code responsible for responding to kinematic collisions, or, where are your non-kinematic bodies?

Your logic does not seem to account for occasions where a third agent is detected while two are fighting. Perhaps you assume that that situation is not possible, but I'm guessing the result you're observing is caused by a failure to respond to a situation where one agent detects a third agent while still engaging the second. (I'm not totally confident this is the problem or the only problem, but this logic has no provisions to account for "unexpected" behavior, which is what's likely occurring.)

I'm familiar enough with plants/zombies to recall the basic format of the game. It would seem that some kind of queue system is called for here, whereby each agent knows about all other agents in its lane. Decisions are then based upon the existence and position of enemy agents in that lane. You could even ditch trigger-based detection altogether. To continue using triggers, you must devise a way to account for situations where agents detect one another while still engaging their nearest neighbors. Other odd cases may exist; the gist is, you have to account for every conceivable combination of events. Your current approach seems very inflexible; consider an alternative way for agents to discover and react to one another in a sensible way.

avatar image MrPantaIoons · Apr 15, 2015 at 07:51 PM 0
Share

The game I'm making has five different lanes. When you click on a lane, it spawns a unit (at the moment, I only have a "Soldier" unit for a defender, and a "Fallen" unit for attackers). Once spawned, the defenders moves to the right, and when it meets an attacker (Fallen), they start the attack animation (they both have swords).

At the time of posting, I am somewhat new to coding and Unity. I have been taking classes, and I decided to go off and make this on my own, so please understand I have limited knowledge of C# and Unity.

avatar image AlwaysSunny · Apr 15, 2015 at 08:00 PM 0
Share

There's nothing "wrong" with your approach to this per se, but depending upon the size of the triggers, I'd wager you are detecting more than one enemy at a time and failing to respond to those additional enemies appropriately.

You might try enforcing an attack state. When an agent detects an enemy, it enters the attack state and does not leave that state until the enemy is defeated. During the attack state, additional enemy contacts are ignored. When the current enemy is slain, the attack state ends, and the next enemy contact is registered and responded to.

This is the most basic example of a Finite State $$anonymous$$achine; a program$$anonymous$$g design principle most game devs first encounter when designing AI.

avatar image MrPantaIoons · Apr 16, 2015 at 09:21 PM 0
Share

Okay, could you tell me how I'd go about doing that? Like I said, I'm relatively new to this, and I'm kind of stumped. Everything I've tried has ended in failure.

1 Reply

· Add your reply
  • Sort: 
avatar image
0

Answer by AlwaysSunny · Apr 17, 2015 at 12:46 AM

I'll try a quickie example, but you should be prepared to research such well-documented design techniques on your own.

In a more complicated Finite State Machine, you'd use some variable like an enum to track which state(s) your agents are currently in.

 public enum AgentState { idle, patrol, attack }
 public AgentState currentState;
 //...
 switch ( currentState ) {
   case AgentState.idle : DoIdleBehavior(); break;
   // etc...
 }

In this example, because there are only two states (lookForTargets and attackTarget) you can safely determine the state based on whether a currentTarget variable is null or populated. You'll need a way to detect and select the "best target" among detected agents.

 // where Agent is the name of some script your characters derive from
 private Agent currentTarget;
     
 // it really makes the most sense to discover all nearby objects, 
 // check whether they're agents, 
 // verify that they belong to the same lane,
 // then sort through those agents to select the nearest one.
 // Failure to do so may allow the "wrong" agent to get selected
 // which might lead to all sorts of problems.

 // This isn't hard, but there are many valid ways to do this so I'm leaving it to you.
 // You could use OnTriggerStay() but I would recommend Physics.OverlapSphere()
 // which bypasses triggers altogether, and conveniently
 // hands you a collection of all detected objects.
     
 // don't look for a target if you already have one
 if (currentTarget == null) {
   // do whatever you're gonna do to discover and select the best agent, then...
   Agent otherAgent = (other.gameObject.GetComponent<Agent>() as Agent;
   if (otherAgent != null) currentTarget = otherAgent;
 }

 // now, if you have a target, attack it until the target is no longer valid
 // somewhere in your attack method...
 if (currentTarget.health <= 0) {
   GameObject.Destroy( currentTarget.gameObject );
   currentTarget = null;
 }


You'll then allow your look-for-targets code to run again, starting the cycle over.

Then, you'd probably want a way for friendly agents to detect each other too, so they can "wait" on friendlies in front of them. "Waiting" should really constitute a third state, so you might need to have a more complicated FSM after all...

http://docs.unity3d.com/ScriptReference/Physics.OverlapSphere.html

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image MrPantaIoons · Apr 17, 2015 at 04:19 PM 0
Share

I'll try this later today! Thanks for bearing with me and for the help!

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

3 People are following this question.

avatar image avatar image avatar image

Related Questions

Destroying objects with the same name that are touching eachother. 1 Answer

Why does my counter keep going up after pickup is destroyed? 1 Answer

Target touching enemy collision 1 Answer

Destroy Clone Game Object On Collision Doesn't work 3 Answers

using Contains(gameObject) to find and destroy a gameObject from a list 2 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges