首页 > 解决方案 > 无法使游戏对象从另一个脚本中移动

问题描述

我正在开发像东方系列这样的 2D STG 游戏,因为我对 Unity 还很陌生。我在控制敌人的子弹时遇到了麻烦,尤其是那些我想要移动的子弹。这是我的两个脚本,我认为它们有一些问题。首先是 EnemyAttackBehavior。我尝试设计敌人可以直射子弹并狙击玩家。我发现我可以在这个脚本中产生子弹,但我不能改变子弹的位置。

public class EnemyAttackBehaviors : MonoBehaviour{
public float bulletSpeed;
public float attackCD;
public float eachWaveCD;
public int oneWaveAmount;

public enum AttackFunctionName
{
    StraightAttack, SnipeAttack,
}

public AttackFunctionName attackFunction;

private int checkNumber;
private float nextShotTime;

private void Start()
{
    checkNumber = (int)attackFunction;
    nextShotTime = Time.time;
}
private void Update()
{
    CheckWhatTypeAttack();
}

private void CheckWhatTypeAttack()
{

    if (checkNumber == 0)
        StraightAttack();            
    else if (checkNumber == 1)
        SnipeAttack();
}

private void StraightAttack()
{
    for (int i = 0; i < oneWaveAmount; i++)
    {
        if (Time.time > nextShotTime)
        {
            GameObject t = ObjectPool.TakeFromPool("EnemyBullet");
            t.transform.SetPositionAndRotation(this.transform.position, this.transform.rotation);
            //t.GetComponent<Rigidbody2D>().velocity = new Vector2(0, -bulletSpeed);
            //t.transform.Translate(Vector3.up * -bulletSpeed * Time.deltaTime);
            t.transform.position -= new Vector3(0, bulletSpeed, 0);
            nextShotTime = Time.time + attackCD;
        }
    }
}

private void SnipeAttack()
{

}

在代码中 StraightAttack。我尝试了三种方法来改变子弹的位置。唯一可以改变子弹位置的是rigibody2D.velocity。但我不喜欢这种方式,因为使用这种方式我无法轻松测量我想要的速度值。不幸的是,其他方式无法改变子弹的位置。我不知道为什么当我直接修改值时子弹的位置不会改变(如 t.transform.position -= new Vector3 (0, bulletSpeed, 0))。然后我认为错误可能在另一个脚本中 - Stage1Path。

public class Stage1Path : MonoBehaviour{
public float firstWave = 4f;

private float timer;
private bool w1Check = true;
private void Start()
{
    timer = 0f;
}

private void Update()
{
    timer += Time.realtimeSinceStartup;
    CheckWhatWave();
}

private void CheckWhatWave()
{
    if (Time.time > firstWave && w1Check == true)
        FirstWave();
}

private void FirstWave()
{
    GameObject e1 = ObjectPool.TakeFromPool("Enemy");
    e1.transform.position = new Vector3(-2f, 3f, 0f);
    EnemyBehaviors e1Script = e1.GetComponent<EnemyBehaviors>();
    e1Script.moveSpeed = 0.01f;
    e1Script.moveFunction = EnemyBehaviors.MoveFunctionName.VerticalMove;
    e1Script.lifeTime = 3f;
    
    EnemyAttackBehaviors e1AttackScript = e1.GetComponent<EnemyAttackBehaviors>();
    e1AttackScript.attackCD = 0.1f;
    e1AttackScript.attackFunction = EnemyAttackBehaviors.AttackFunctionName.StraightAttack;
    e1AttackScript.bulletSpeed = 4f;
    e1AttackScript.eachWaveCD = 3f;
    e1AttackScript.oneWaveAmount = 5;

    w1Check = false;
}

在 Stage1Path 中,我尝试在 FirstWave() 中生成第一个名为 e1 的敌人。它发生在游戏开始 4 秒后。在 FirstWave() 中,我通过脚本 EnemyBehavior 设置 e1 的移动。它工作得很好!但是当我在e1的拍摄类型中使用相同的方式时。子弹产生了,但它们没有移动。我不知道错误发生在 EnemyAttackBehavior 或 Stage1Path 中。我尝试修复这个错误很多小时并搜索了很多互联网。我也尝试在 EnemyAttackBehavior 中使用协程,我认为它可以解决问题。但我还是失败了。非常感谢任何帮助。对不起我的英语不好。

标签: c#unity3d

解决方案


您需要在每一帧都应用翻译。这条线不错,但是

t.transform.Translate(Vector3.up * -bulletSpeed * Time.deltaTime);

因此,在您的情况下,您只应用一次。所以你基本上在一帧中移动它一次,然后等待其他时间再次移动它。

    if (Time.time > nextShotTime)
    {
      // movement logic
      nextShotTime = Time.time + attackCD;
    }

它适用于修改速度,因为基于速度的运动是由物理引擎计算的。在 transform.Translate 的情况下,您需要自己应用每一帧的移动。


推荐阅读