2 回答
![?](http://img1.sycdn.imooc.com/545863c10001865402200220-100-100.jpg)
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()这取决于您在游戏后期的敌人实例化和创建。
![?](http://img1.sycdn.imooc.com/54584cfb0001308402200220-100-100.jpg)
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 );
}
}
}
- 2 回答
- 0 关注
- 155 浏览
添加回答
举报