随着时间的推移,在与霜弹碰撞时减速



我是Unity和C#的新手。我几周前开始玩这个2D游戏。

所以基本上我想做的是当玩家被";FrostBullet";,随着时间的推移,它应该会造成伤害并减缓玩家的速度。在我的剧本中,玩家被霜弹击中,它造成的伤害和速度是恒定的,而不是随着时间的推移。我希望当玩家被霜弹击中时,玩家应该减速2秒,然后他的移动速度恢复正常。

所以我的代码是这样的:

public class FrostHit : MonoBehaviour 
{
float maxS = 40f;
float slowSpeed = 20f;
public Rigidbody2D rb;
int damage = -5;
int timeOfReducedSpeed = 2;
bool isHit = false;

void Start()
{
rb.velocity = transform.right * slowSpeed;
}
void OnTriggerEnter2D(Collider2D other)
{
if (other.gameObject.tag == "Player_Njinja")
{
HealthNjinja healthNjinja = other.gameObject.GetComponent<HealthNjinja>();
healthNjinja.ModifyHealth(damage);
PlayerMovementNjinja reduceMoveSpeed = other.gameObject.GetComponent<PlayerMovementNjinja>();
reduceMoveSpeed.runSpeed = slowSpeed;
Destroy(gameObject);
}
PlayerMovementKnight maxSpeed = other.gameObject.GetComponent<PlayerMovementKnight>();
maxSpeed.runSpeed = maxS;
HealthKnight healthKnight = other.gameObject.GetComponent<HealthKnight>();
if (other.gameObject.tag == "Player_Knight")
{
isHit = true;
healthKnight.ModifyHealth(damage);
StartCoroutine(speedTime());
Destroy(gameObject);
}
IEnumerator speedTime()
{
while (isHit == true)
{
slowPlayer();
yield return new WaitForSeconds(timeOfReducedSpeed);
revertSpeed();
}
}
void slowPlayer()
{
maxSpeed.runSpeed = slowSpeed;
}
void revertSpeed()
{
maxSpeed.runSpeed = maxS;
}
}

}

还有我的PlayerMovement代码:

public class PlayerMovementKnight : MonoBehaviour
{
public CharacterController2D controller;
public Animator animator;
public float runSpeed = 40f;
float horizontalMove = 0f;
bool jump = false;
bool crouch = false;
public WeaponKnight Bullet;
public bool grounded;
void Update()
{
horizontalMove = Input.GetAxisRaw("Horizontal") * runSpeed;
animator.SetFloat("Speed", Mathf.Abs(horizontalMove));
if (Input.GetButtonDown("Jump"))
{
jump = true;
animator.SetBool("IsJumping", true);
}
if (Input.GetButtonDown("Crouch"))
{
crouch = true;
}
else if (Input.GetButtonUp("Crouch"))
{
crouch = false;
}
if (grounded && GetComponent<Bullet>().knockBack == false)
{
GetComponent<Rigidbody2D>().velocity = new Vector2(0, 0);
}
}
public void OnLanding()
{
animator.SetBool("IsJumping", false);
}
public void OnCrouching(bool isCrouching)
{
animator.SetBool("IsCrouching", isCrouching);
}
void FixedUpdate()
{
controller.Move(horizontalMove * Time.fixedDeltaTime, crouch, jump);
jump = false;
}

}

问题似乎是,在调用Coroutine之前设置为truebool isHit永远不会重置为false

所以循环:

while (isHit == true)
{
slowPlayer();
yield return new WaitForSeconds(timeOfReducedSpeed);
revertSpeed();
}

实际上是一个无限循环。您可能需要在某个位置将bool重置为false。

编辑:

根据评论,我现在看到你的脚本被附加到了子弹头GameObject上。在启动Coroutine并减慢玩家速度后,您Destroy(gameObject);在那之后,脚本也被销毁,因此Coroutine被停止。。。并且没有任何东西可以使玩家的速度恢复正常。

您应该将Coroutine移到玩家的脚本中,并在需要时启动它。这样,在你销毁子弹后,它仍然存在。

您的boolisHit从未设置为false。导致玩家被减速,然后在被击中一次后永远重置。

除了首先创建isHit之外,还不需要。为什么您在输入IEnumerator时需要检查播放机是否已被击中,而只有在Player_Knight已被击中时才需要检查。

代码示例:

public class FrostHit : MonoBehaviour
{
float maxS = 40f;
float slowSpeed = 20f;
public Rigidbody2D rb;
int damage = -5;
int timeOfReducedSpeed = 2;
void Start()
{
rb.velocity = transform.right * slowSpeed;
}
void OnTriggerEnter2D(Collider2D other)
{
if (other.gameObject.tag == "Player_Njinja")
{
HealthNjinja healthNjinja = other.gameObject.GetComponent<HealthNjinja>();
healthNjinja.ModifyHealth(damage);
PlayerMovementNjinja mSpeedNinja = other.gameObject.GetComponent<PlayerMovementNjinja>();
StartCoroutine(speedTimeNinja());
}
else if (other.gameObject.tag == "Player_Knight")
{
HealthKnight healthKnight = other.gameObject.GetComponent<HealthKnight>();
healthKnight.ModifyHealth(damage);
PlayerMovementKnight mSpeedKnight = other.gameObject.GetComponent<PlayerMovementKnight>();
StartCoroutine(speedTimeKnight());
}

// Destroy Bullet
Destroy(gameObject);
}

IEnumerator speedTimeKnight()
{
mSpeedKnight.runSpeed = slowSpeed;
yield return new WaitForSeconds(timeOfReducedSpeed);
mSpeedKnight.runSpeed = maxS;
}
IEnumerator speedTimeNinja()
{
mSpeedNinja.runSpeed = slowSpeed;
yield return new WaitForSeconds(timeOfReducedSpeed);
mSpeedNinja.runSpeed = maxS;
}
}

我改变的事情和原因:

  1. 删除了bool和while循环,没有解决任何实际目的
  2. 分离的IEnumerator和来自OnTriggerEnter2D()内部的2个函数
  3. 最后添加了Destroy(gameObject);,因为子弹总是会被摧毁
  4. 删除了maxSpeed.runSpeed = maxS;,因为速度已经设置/重置。在我们与子弹相撞后,没有理由重新设定速度
  5. Player_KnightGetComponent放入else-if中,即使Player_Njinja被命中,也没有理由执行GetComponent
  6. 移除reduceMoveSpeed.runSpeed = slowSpeed;后,Player_Njinja只会减速,再也无法恢复速度。请重新使用IEnumerator
  7. 添加了另一个IE分子,使Player_NjinjaPlayer_Knight都能正确减速和解锁(现在甚至可以根据被击中的玩家创建不同的减速时间(
  8. 删除了函数,为一行代码编写一个函数实际上并不值得。尤其是当你可以在IEnumerator中设置它而不需要更多的代码行时

相关内容

  • 没有找到相关文章

最新更新