你好,我试图让我的敌人停在玩家面前使用if(Vector2.Distance(transform.position, player.position) > minDistance)
但这并没有像我预期的那样工作。敌人应该开始在一定范围内跟随玩家,而不是停在他面前。这对if(Vector2.Distance(transform.position, player.position) <= range)
很有效
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Enemy : MonoBehaviour
{
public int Health;
public Transform player;
public float range;
public float speed;
public Animator anim;
public Transform goblinRange;
public float attackRangeGoblin;
public LayerMask whatIsPlayer;
public int damage;
private float timeBtwAttack;
public float startTimeBtwAttack;
// Update is called once per frame
void Update()
{
if (Vector2.Distance(transform.position, player.position) <= range)
{
anim.SetBool("GWalking", true);
transform.position = Vector2.MoveTowards(transform.position, player.position, speed *
Time.deltaTime);
Collider2D[] playerToDamage = Physics2D.OverlapCircleAll(goblinRange.position,
attackRangeGoblin, whatIsPlayer);
for (int i = 0; i < playerToDamage.Length; i++)
{
playerToDamage[i].GetComponent<PlayerMovement>().TakeDamage(damage);
}
}
else
{
Idle();
}
}
private void FixedUpdate()
{
if (Health <= 0)
{
Destroy(gameObject);
}
}
private void Idle()
{
anim.SetBool("GWalking", false);
}
public void TakeDamage(int Damage)
{
Health -= Damage;
Debug.Log("Damage Taken");
}
private void OnDrawGizmosSelected()
{
Gizmos.color = Color.red;
Gizmos.DrawWireSphere(goblinRange.position, attackRangeGoblin);
}
private void Attack()
{
anim.SetTrigger("goblinAttack");
}
}
所以我需要敌人停在我的播放器前面并开始攻击动画,但我不知道如何在不删除"<= 范围"的情况下实现对我的代码的if(Vector2.Distance(transform.position, player.position) > minDistance)
。任何帮助将不胜感激。
您可以将minDistance
检查嵌套在range
检查中,如下所示:
if (Vector2.Distance(transform.position, player.position) <= range)
{
if (Vector2.Distance(transform.position, player.position) <= minDistance)
{
//Attack
}
else
{
//Chase
}
}
这样,只要玩家在追逐范围内,但距离还不够近,敌人就会追逐玩家。一旦进入攻击范围,它就会停止追逐并开始攻击。
range
和minDistance
检查不是互斥的("一个或另一个"(。它们可以存在并共存:
//Avoid redundancy, write less, and make things more readable
var distance = Vector2.Distance(transform.position, player.position);
//If within range..
if (distance <= range) {
//If not within minDistance..
if(!(distance <= minDistance)) {
//Move
}
//If within minDistance (incl. after moving, above)..
if (distance <= minDistance) {
//Attack
}
}
//If not within range..
else {
//Idle
}
代码还有其他几个问题:
应遵循命名约定:
- 如果你的变量和参数是驼峰大小写,那么
Health
应该是health
的,GWalking
应该是gWalking
的,Damage
应该是damage
的。
- 如果你的变量和参数是驼峰大小写,那么
名称应具有描述性:
跳过几个字符进行键入不值得您或其他人(例如我们(不得不解密您的代码。
- 避免歧义。
anim
可以指动画器或动画器。使用animator
. - 避免使用首字母缩略词。在
GWalking
,G
代表什么?---G·奥布林。我知道。问题是:我从其余代码的推理中知道;不是从名称本身。请改用goblinWalking
。 - 避免使用类似首字母缩略词的缩短,例如
Btw
而不是Between
。它们很糟糕,原因与"G"相同。
- 避免歧义。
保持一致:
- 对类似的东西使用相同的命名结构。决定一个方案,并遵循它。不要把
GWalking
放在一个地方,goblinAttack
放在另一个地方。如果"subjectAction
"是结构,则使用goblinWalking
、goblinAttack
等。 - 在名称中使用相同的结构顺序。如果你的主题要放在开头,就像在
goblinRange
中一样,那么不要把它放在其他地方的末尾,就像在attackRangeGoblin
一样。使用goblinAttackRange
. - 如果职业是"敌人","哥布林"的东西就不应该存在。所有的哥布林都可能是敌人,但不是所有的敌人都是哥布林。你的职业可能是所有敌人的通用职业,也可能是哥布林特有的;不能两者兼而有之。将其命名为
Goblin
;或者从它的元素中删除"妖精"的东西。
- 对类似的东西使用相同的命名结构。决定一个方案,并遵循它。不要把
命名变量是为了它们是什么,而不是它们的作用:
whatIsPlayer
playerLayerMask
.
在命名时要足智多谋(又名:"描述性并不意味着冗长!
timeBtwAttacks
attackInterval
.
尝试对相关内容进行分组。
修复后,它应如下所示:
//External(?) dependencies
public Transform player;
public LayerMask playerLayerMask; //From: whatIsPlayer
//Internal dependencies
public Animator animator; //From: anim
//Settings
public int health; //From: Health
public float range;
public float speed;
public int damage;
public float attackInterval; //From: timeBtwAttack
//Gobling stuff (probably redundant/unnecessary)
public Transform goblin; //From: goblinRange
public float goblinAttackRange; //From: attackRangeGoblin
//Used in the answer, as infered from the question
public float minDistance; //Probably what 'goblinAttackRange' is.
其他修复:
FixedUpdate
是物理方面的。 如果要遵循当前的结构,if (health <= 0) { Destroy(gameObject); }
应该在Update
(加上一个return
(。如果没有,那么它应该对健康的变化做出反应,从而在TakeDamage
.- 在代码中保持一致。不要在一个地方使用
anim.SetBool("GWalking", true)
,然后在另一个地方使用Idle()
。两者都应该是方法(Idle()
和Walk()
(,或者两者都应该是SetBool
调用。 Transform goblin
是单独的转换吗?如果不是,只需像在Vector2.Distance
中那样使用transform
。
尝试使用
if((transform.position, player.position).magnitude <range)
而不是
if(Vector2.Distance(transform.position, player.position) <= range)