Unity 2D。当我的玩家击中敌人时增加击退效果

时间:2018-10-08 09:40:16

标签: c# unity3d

我正在编程2D Platformer,但遇到问题/问题/怪异的情况-随便命名。首先,在基本场景中,我有4个Blob(如图所示):

从我的场景中查看:

View from my Scene

问题是:当我击中最大的那一击时,它不会受到击退,而上面的较小的那一击则具有击退效果,并且没有伤害。他们每个人都在敌人标签和敌人层上。

有趣的事物-当其中只有一个位于敌人的图层和标记上时,它会获得正确的效果(伤害+击退)。是脚本问题,还是我在Unity中弄乱了东西。

PS。另一个有趣的事情-当我将每个Blob设置在敌人图层和标签上时。然后,我直接(准确地)击中了我上方的那个(带有黄色箭头)。它的行为正确...所以我什至感到困惑。

我的代码(抱歉,由于测试,它被压缩为一个大文件)战斗和移动


[PlayerControls.cs]:

using System.Collections;


using System.Collections.Generic;
 using UnityEngine;
 using UnityEngine.Events;
 using UnityEngine.UI;
 using UnityEngine.Animations;
 using UnityEngine.SceneManagement;

 public class PlayerControls : MonoBehaviour
 {
     private float moveHoriz;
     public float speed;
     public bool grounded;


 private float crouch;
 public bool crouching;

 private Rigidbody2D rb;

 bool sliding;
 public float slideTimer;
 public float maxSlideTime;

 public float jumpForce;

 public bool facingRight = true;

 public bool isDoubleJump = true;

 public LayerMask whatIsGround;
 public float groundRadius;
 public Transform GroundCheck;

 public Transform CeilingCheck;
 private bool ceiled;

 public Transform NearGroundCheck;
 private bool isGroundNear;

 private int extraJumps;
 public int extraJumpValues;

 private bool jumping;

 private bool attack1;
 private bool attack2;
 private bool attack3;

 private bool airAttack1;

 public bool goodOrder1;
 public bool goodOrder2;
 public bool goodOrder3;

 public bool badOrder2;
 public bool badOrder3;

 public bool combo;
 public float comboDuration;
 public float comboEndup = 1;

 private bool shootBow;
 public bool reloadBow = true;
 public int reloadTime = 1;

 public Transform attackPos;
 public float attackRange;
 public LayerMask whatIsEnemy;
 public int damage;

 private EnemyScript enemy;

 public Animator animator;

 // Use this for initialization
 void Start()
 {
     extraJumps = extraJumpValues;
     rb = GetComponent<Rigidbody2D>();
     enemy = GameObject.FindGameObjectWithTag("Enemy").GetComponent<EnemyScript>();
 }


 // Update is called once per frame
 void Update()
 {
     animator.SetFloat("Speed", Mathf.Abs(moveHoriz));
     animator.SetBool("Grounded", grounded);
     animator.SetFloat("vertSpeed", rb.velocity.y);
     animator.SetInteger("isDoubleJump", extraJumps);

     animator.SetBool("Crouch", crouching);

     animator.SetBool("isSliding", sliding);
     animator.SetFloat("stopSliding", slideTimer);

     animator.SetBool("isGroundNear", isGroundNear);

     animator.SetBool("comboAttack", combo);
     animator.SetFloat("comboDuration", comboDuration);

     animator.SetBool("reloadBow", reloadBow);
     animator.SetFloat("reloadTime", reloadTime);

     animator.SetBool("goodOrder1", goodOrder1);
     animator.SetBool("goodOrder2", goodOrder2);
     animator.SetBool("goodOrder3", goodOrder3);

     animator.SetBool("badOrder2", badOrder2);
     animator.SetBool("badOrder3", badOrder3);

     moveHoriz = Input.GetAxisRaw("Horizontal");

     crouch = Input.GetAxisRaw("Crouch");

     RangeAttack();

     OrderCheck();

     Crouch();

     if (grounded != true)
     {
         jumping = true;
         sliding = false;
         slideTimer = 0;
     }

     if (grounded == true)
     {
         jumping = false;
         extraJumps = extraJumpValues;
     }

     if (Input.GetKeyDown(KeyCode.UpArrow) && extraJumps > 0)
     {
         jumping = true;
         rb.velocity = Vector2.up * jumpForce;
         extraJumps--;
     }
     else if (Input.GetKeyDown(KeyCode.UpArrow) && extraJumps == 0 && grounded == true)
     {
         rb.velocity = Vector2.up * jumpForce;
     }

     if (Input.GetKeyDown(KeyCode.H))
     {
         Die();
     }

 }

 void FixedUpdate()
 {
     grounded = Physics2D.OverlapCircle(GroundCheck.position, groundRadius, whatIsGround);

     ceiled = Physics2D.OverlapCircle(CeilingCheck.position, groundRadius, whatIsGround);

     isGroundNear = Physics2D.OverlapCircle(NearGroundCheck.position, groundRadius, whatIsGround); ;

     rb.velocity = new Vector2(moveHoriz * speed, rb.velocity.y);



     Move();

     Flip();

     Sliding();

     Combo();

     HandleInput();

     HandleAttacks();

     DealDmg();

     ResetValues();
 }

 void Move()
 {
     rb.velocity = new Vector2(moveHoriz * speed, rb.velocity.y);
 }

 // Flip (or better said Rotate) Character.
 void Flip()
 {
     if ((moveHoriz < 0 && facingRight == true) || (moveHoriz > 0 && facingRight == false))
     {
         facingRight = !facingRight;
         Vector3 theScale = transform.localScale;
         theScale.x *= -1;
         transform.localScale = theScale;
     }
 }

 void Crouch()
 {
     if ((crouch != 0 || ceiled == true) && grounded == true)
     {

         crouching = true;
     }
     else
     {
         crouching = false;
     }

     if (crouching)
     {
         speed = 10;
     }
     else
     {
         speed = 15;
     }
 }

 void Sliding()
 {
     //If statement to check if player is sliding to maxSlide capacity
     if (Input.GetButtonDown("Crouch") && speed > 0)
     {
         slideTimer = 0f;

         sliding = true;


         if (slideTimer >= maxSlideTime && sliding == true || moveHoriz == 0)
         {
             sliding = false;
             animator.SetBool("isSliding", false);
             crouching = true;
             animator.SetBool("Crouch", false);
         }
     }

     if (slideTimer < maxSlideTime && moveHoriz == 0 && crouch > 0)
     {
         sliding = false;

         animator.SetBool("isSliding", false);
         animator.SetBool("Crouch", true);

         crouching = true;
     }

     if (sliding)
     {
         speed = 25;
         slideTimer += Time.deltaTime;

         if (slideTimer >= maxSlideTime || jumping == true)
         {
             sliding = false;
             animator.SetBool("isSliding", false);
             speed = 15;
         }

         if (facingRight == true)
         {
             rb.velocity = Vector2.right * speed;
         }
         else if (facingRight != true)
         {
             rb.velocity = Vector2.left * speed;
         }
     }
 }

 void HandleAttacks()
 {
     if (attack1 == true)
     {
         goodOrder1 = true;
         goodOrder2 = false;
         goodOrder3 = false;
     }

     if (attack2 == true)
     {
         goodOrder1 = false;
         goodOrder2 = true;
         goodOrder3 = false;
     }

     if (attack3 == true)
     {
         goodOrder1 = false;
         goodOrder2 = false;
         goodOrder3 = true;
     }

     if (airAttack1)
     {
         animator.SetTrigger("airAttack1");
         attackRange = 1;
     }

 }

 private void HandleInput()
 {
     if (Input.GetButtonDown("Attack1"))
     {
         attack1 = true;
     }
     else if (Input.GetButtonUp("Attack1"))
     {
         attack1 = false;
     }

     if (Input.GetButtonDown("Attack2"))
     {
         attack2 = true;
     }
     else if (Input.GetButtonUp("Attack2"))
     {
         attack2 = false;
     }

     if (Input.GetButtonDown("Attack3"))
     {
         attack3 = true;
     }
     else if (Input.GetButtonUp("Attack3"))
     {
         attack3 = false;
     }



     if (grounded == false && (Input.GetButtonDown("Attack1") || Input.GetButtonDown("Attack2") || Input.GetButtonDown("Attack3")))
     {
         airAttack1 = true;
         attack1 = false;
     }

     if (airAttack1 == true && grounded == true)
     {
         airAttack1 = false;
     }
 }

 void OrderCheck()
 {
     // First sequence attack
     if (grounded == true && attack1 == true && comboDuration > 0)
     {
         goodOrder1 = true;
     }
     else if (goodOrder1 != true && grounded == true && attack2 == true && comboDuration <= 0)
     {
         badOrder2 = true;
     }

     // Second sequence attack
     if (grounded == true && attack2 == true && comboDuration > 0)
     {
         goodOrder2 = true;
     }
     else if (goodOrder1 != true && grounded == true && attack3 == true && comboDuration <= 0)
     {
         badOrder3 = true;
     }

     // Third sequence attack
     if (grounded == true && attack3 == true && comboDuration > 0)
     {
         goodOrder3 = true;
     }
     else if (goodOrder2 != true && grounded == true && goodOrder1 != true && comboDuration > 0)
     {
         badOrder3 = true;
     }

     // Clear if badOrder's achived
     if (badOrder2 == true || badOrder3 == true)
     {
         goodOrder1 = false;
         goodOrder2 = false;
         goodOrder3 = false;
     }
 }

 void Combo()
 {
     if (attack1 == true)
     {
         comboDuration = comboEndup;
     }

     /*if ((goodOrder1 == true || goodOrder2 == true || goodOrder3 == true) || (badOrder2 == true || badOrder3 == true))
     {
         comboDuration = comboEndup;
     }*/


     // comboEndup = 1; - reminder

     if (comboDuration > 0)
     {
         comboDuration -= Time.deltaTime;

         combo = true;
     }

     if (comboDuration <= 0 || (badOrder2 == true || badOrder3 == true))
     {
         comboDuration = 0;

         combo = false;

         goodOrder1 = false;
         goodOrder2 = false;
         goodOrder3 = false;

         badOrder2 = false;
         badOrder3 = false;
     }
 }

 void ResetValues()
 {
     if (badOrder2 == true || badOrder3 == true)
     {
         badOrder2 = false;
         badOrder3 = false;
     }

     airAttack1 = false;

     if (gameObject.GetComponent<PlayerControls>().grounded == true && airAttack1 == true)
     {
         airAttack1 = false;
     }
 }

 private void RangeAttack()
 {
     if (grounded == true && Input.GetButtonDown("Ranged"))
     {
         animator.SetTrigger("shootBow");
         reloadBow = false;

         attack1 = false;
         attack2 = false;
         attack3 = false;
     }
 }

 void OnDrawGizmosSelected()
 {
     Gizmos.color = Color.red;
     Gizmos.DrawWireSphere(attackPos.position, attackRange);
 }

 public void DealDmg()
 {
     if (attackPos.gameObject.activeSelf == true)
     {
         Collider2D[] enemiesToDamage = Physics2D.OverlapCircleAll(attackPos.position, attackRange, whatIsEnemy);
         for (int i = 0; i < enemiesToDamage.Length; i++)
         {


             enemiesToDamage[i].GetComponent<EnemyScript>().TakeDmg(damage);


             if (facingRight == true)
             {
                 gameObject.GetComponent<EnemyScript>().EnemyRB.AddForce(transform.up * 500 + transform.right * 500);
             }
             else if (facingRight == false)
             {
                 gameObject.GetComponent<EnemyScript>().EnemyRB.AddForce(transform.up * 500 + (transform.right * 500) * -1);
             }

             attackPos.gameObject.SetActive(false);
         }
     }
 }

 void Die()
 {
     SceneManager.LoadScene(0);
 }
 }

敌人运动[EnemyScript.cs]:

    using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 using UnityEngine.UI;

 public class EnemyScript : MonoBehaviour {

     public float speed;
 public float distance;

 public int health;

 public bool movingRight = true;

 public Transform groundDetection;

 public Rigidbody2D EnemyRB;

 public bool trap;
 public LayerMask TrapLayer;
 public Transform ColideDetector;
 public float detectorRadius;

 public BoxCollider2D CheckHeadBounce;

 // Use this for initialization
 void Start ()
 {
     EnemyRB = gameObject.GetComponent<Rigidbody2D>();
 }

 // Update is called once per frame
 void Update ()
 {
     trap = Physics2D.OverlapCircle(ColideDetector.position, detectorRadius, TrapLayer);

     if (health <= 0)
     {
         Destroy(gameObject);
     }

     transform.Translate(Vector2.right * speed * Time.deltaTime );

     RaycastHit2D groundInfo = Physics2D.Raycast(groundDetection.position, Vector2.down, distance);


     if (groundInfo.collider == false || trap == true)
     {
         if(movingRight == true)
         {
             transform.eulerAngles = new Vector3(0, -180, 0);
             movingRight = false;
         }
         else
         {
             transform.eulerAngles = new Vector3(0, 0, 0);
             movingRight = true;
         }
     }
 }

 public void HeadBounce()
 {

 }

 public void TakeDmg(int damage)
 {
     health -= damage;

     Debug.Log("damage TAKEN!");
 }

}

It's a gif to show what is going on

PlayerInspector - PlayerScript

Enemy Inspector - EnemyScript

1 个答案:

答案 0 :(得分:1)

您没有在EnemyScript内使用DealDmg的正确引用。在循环中,您首先呼叫TakDmg上发现的敌人OverlapCircleAll,然后呼叫AddForce上的gameObject.GetComponent<EnemyScript>().EnemyRB

在这种情况下,gameObject指的是运行脚本附加到的GameObject(此处为PlayerControl.cs)。您需要在碰撞数组enemisToDamage内的游戏对象的刚体上施加力,就像对TakeDmg所做的一样。

这是一个可能的解决方案。

public void DealDmg()
{
    if (attackPos.gameObject.activeSelf == true)
    {
        Collider2D[] enemiesToDamage = Physics2D.OverlapCircleAll(attackPos.position, attackRange, whatIsEnemy);
        for (int i = 0; i < enemiesToDamage.Length; i++)
        {
            EnemyScript enemyScript = enemiesToDamage[i].GetComponent<EnemyScript>();
            enemyScript.TakeDmg(damage);
            if (facingRight == true)
            {
                enemyScript.GetComponent<RigidBody>().AddForce(transform.up * 500 + transform.right * 500);
            }
            else if (facingRight == false)
            {
                enemyScript.GetComponent<RigidBody>().AddForce(transform.up * 500 + (transform.right * 500) * -1);
            }
            attackPos.gameObject.SetActive(false);
        }
    }
}