为了账号安全,请及时绑定邮箱和手机立即绑定

从下一个实例化更改实例化游戏对象的移动

从下一个实例化更改实例化游戏对象的移动

C#
qq_遁去的一_1 2021-10-09 10:09:12
我正在使用 Unity 和 C#。在我的游戏中,敌人被反复实例化并以线性路径向玩家移动。我想让敌人在经过特定时间后以正弦波移动,以使游戏更加艰难。运动会立即发生变化,但我希望这种变化从新(下一个)敌人的实例化而不是当前存在的敌人的实例化生效。我能做什么?EnemySpawner 脚本 -private void Start(){    timeelapsed = 0f;    StartCoroutine(SpawnEnemies(delay));}private void Update(){    timeelapsed += Time.deltaTime;}private IEnumerator SpawnEnemies(float delay){    while (true)    {        SpawnNewEnemy();        yield return new WaitForSeconds(delay);    }}private void SpawnNewEnemy(){    if (!enemyclone)    {        enemyclone = Instantiate(enemy, enemySpawner.transform.position + offset, Quaternion.identity);    }}Enemy Movement 脚本:private void Update(){    t = Time.time;    if (EnemySpawner.timeelapsed > 0f && EnemySpawner.timeelapsed <= 20f)    {        enemy.transform.Translate(Vector3.forward * speed * Time.deltaTime);    }    if (EnemySpawner.timeelapsed > 20f && EnemySpawner.timeelapsed <= 40f)    {        enemy.GetComponent<Rigidbody>().velocity = Vector3.forward * 5 + Vector3.left * 3 * Mathf.Sin(10f * t);    }}
查看完整描述

2 回答

?
富国沪深

TA贡献1790条经验 获得超9个赞

有上千种方法可以实现这一点,但我认为可能易于实现和理解的一种方法是设置 Action,当您从 spawner 实例化一个新敌人时会触发它。我很快就为您的 EnemySpawner 和 EnemyMovement 脚本编写了一些我认为可能对您有所帮助的更改。


首先,EnemySpawner:


public static event Action EnemySpawning;

void SpawnNewEnemy ( )

{

    if ( !enemyclone )

    {

        EnemySpawning?.Invoke ( );

        enemyclone = Instantiate ( enemy, enemySpawner.transform.position + offset, Quaternion.identity );

    }

}

现在,敌人运动:


private bool travelInLinearPath = true;


private void OnEnable ( )

{

    EnemySpawner.EnemySpawning -= OnEnemySpawning;

    EnemySpawner.EnemySpawning += OnEnemySpawning;

    travelInLinearPath = true;

}


public void OnEnemySpawning( )

{

    EnemySpawner.EnemySpawning-= OnEnemySpawning;

    travelInLinearPath = false;

}


private void Update ( )

{

    if ( travelInLinearPath )

        enemy.transform.Translate ( Vector3.forward * speed * Time.deltaTime );

    else

        enemy.GetComponent<Rigidbody> ( ).velocity = Vector3.forward * 5 + Vector3.left * 3 * Mathf.Sin ( 10f * Time.time );

}

每次启用敌人时,您都要求在下一个敌人即将产生时收到通知。发生这种情况时,您告诉这个敌人从线性运动变为正弦运动 ( travelInLinearPath)。您还要求在产生新敌人时不再通知该敌人(除非您重新启用该敌人)。


我也没有讨论你是否应该从敌人对象池中抓取一个新的敌人。但希望你这样做是我在OnEnable(). 您可能希望/需要将该代码放入其中,Start()这取决于您在游戏后期的敌人实例化和创建。


查看完整回答
反对 回复 2021-10-09
?
慕村9548890

TA贡献1884条经验 获得超4个赞

现在知道请求是针对敌人的“波浪”,我们需要向每个敌人添加波浪定义项目。因此,首先修改EnemyMovement脚本:


public class EnemyMovement : MonoBehaviour

{

    public enum MovementType

    {

        None = 0,

        Linear = 1,

        Sinusoidal = 2

        // etc, etcc

    }


    /// <summary>

    /// Movement affects the movement type of the enemy.

    /// </summary>

    public MovementType Movement { get; set; }


    /// <summary>

    /// This affects the Speed of the Enemy. Used in conunction with Movement to

    /// produce the enenmy's wave movement type.

    /// </summary>

    public float Speed { get; set; }


    private Rigidbody rigidBody;



    private void Awake ( )

    {

        rigidBody = GetComponent<Rigidbody> ( );

    }



    private void Update ( )

    {

        switch ( Movement)

        {

            case MovementType.Linear:

                transform.Translate ( Vector3.forward * Speed * Time.deltaTime );

                break;

            case MovementType.Sinusoidal:

                // You probably want the Speed property to affect this as well...

                rigidBody.velocity = Vector3.forward * 5 + Vector3.left * 3 * Mathf.Sin ( 10f * Time.time );

                break;


           // Any extra movement types you want here...

        }


    }

}

然后是EnemySpawner驱动 Enemy 实例化的脚本:


public class EnemySpawner : MonoBehaviour

{

    public float Delay;

    public float StartSpeed;


    public GameObject enemy;

    public GameObject enemySpawner;

    public Vector3 offset;


    private float timeElapsed;

    private float currentSpeed;

    private EnemyMovement.MovementType currentMovement;



    void Start ( )

    {

        timeElapsed = 0f;

        currentSpeed = StartSpeed;

        StartCoroutine ( SpawnEnemies ( Delay ) );

        currentMovement = EnemyMovement.MovementType.Linear;

    }



    void Update ( )

    {

        timeElapsed += Time.deltaTime;


        // We can determine at what time the Wave parameters change here.

        if ( timeElapsed >= 40.0f )

        {

            currentSpeed += 10.0f; // Add speed, for example.

        }

        else if ( timeElapsed >= 20.0f )

        {

            currentMovement = EnemyMovement.MovementType.Sinusoidal;

        }

    }



    IEnumerator SpawnEnemies ( float delay )

    {

        while ( true )

        {

            var enemyClone = Instantiate ( enemy, enemySpawner.transform.position + offset, Quaternion.identity );

            var movement = enemyClone.GetComponent<EnemyMovement> ( );


            // We now set what the enemy uses as the Wave values.

            movement.Speed = currentSpeed;

            movement.Movement = currentMovement;


            yield return new WaitForSeconds ( delay );

        }

    }

}


查看完整回答
反对 回复 2021-10-09
  • 2 回答
  • 0 关注
  • 155 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信