/// This is an example of a SwarmItemManager that handles creation of SwarmItem asteroids.
/// It is also called to break up asteroids when they are hit by bullets.
//太空石头是随机转动+运动的
public class AsteroidManager : SwarmItemManager
{
private float _fieldRadiusSquared;
大 中 小 三种石头的数量
public int initialMediumAsteroidCount;
public int initialLargeAsteroidCount;
//随机转动的范围
public Vector3 minimumSpin;
public Vector3 maximumSpin;
//速度 (2D: x and y)
public Vector2 minimumVelocity;
public Vector2 maximumVelocity;
public float fieldRadius;
public float FieldRadiusSquared { get { return _fieldRadiusSquared; } }
、、重要的。。重要的
{
base.Initialize();
_fieldRadiusSquared = fieldRadius * fieldRadius;
InitializeAsteroidGroup(Asteroid.ASTEROID_TYPE.Small, initialSmallAsteroidCount);
InitializeAsteroidGroup(Asteroid.ASTEROID_TYPE.Medium, initialMediumAsteroidCount);
InitializeAsteroidGroup(Asteroid.ASTEROID_TYPE.Large, initialLargeAsteroidCount);
}
/// Sets up the asteroids of a given size
private void InitializeAsteroidGroup(Asteroid.ASTEROID_TYPE asteroidType, int count)
{
for (int i=0; i<count; i++)
{
// activate a SwarmItem from the manager
Asteroid asteroid = (Asteroid)ActivateItem((int)asteroidType);
if (asteroid != null)
{
// set asteroid with random spin, velocity, and position
asteroid.Set(this, asteroidType, GetRandomSpin(), GetRandomVelocity(), GetRandomPosition());
}
}
}
/// Returns a random vector between the minimum and maximum spin
private Vector3 GetRandomSpin()
{
return new Vector3(
UnityEngine.Random.Range(minimumSpin.x, maximumSpin.x),
UnityEngine.Random.Range(minimumSpin.y, maximumSpin.y),
UnityEngine.Random.Range(minimumSpin.z, maximumSpin.z)
);
}
/// Returns a random 3D vector between the minimum and maximum velocity in 2D
private Vector3 GetRandomVelocity()
{
// get a random velocity between minimum and maximum velocity
return new Vector3(
UnityEngine.Random.Range(minimumVelocity.x, maximumVelocity.x),
UnityEngine.Random.Range(minimumVelocity.y, maximumVelocity.y),
0
);
}
/// Gets a random position within the field radius
private Vector3 GetRandomPosition()
{
Vector2 position = UnityEngine.Random.insideUnitCircle * fieldRadius;
return new Vector3(position.x, position.y, 0);
}
//打碎石头之后的处理
{
Asteroid asteroid;
switch (asteroidType)
{
case Asteroid.ASTEROID_TYPE.Large:
asteroid = (Asteroid)ActivateItem((int)Asteroid.ASTEROID_TYPE.Medium);
if (asteroid != null)
asteroid.Set(this, Asteroid.ASTEROID_TYPE.Medium, GetRandomSpin(), GetRandomVelocity(), position);
asteroid = (Asteroid)ActivateItem((int)Asteroid.ASTEROID_TYPE.Medium);
if (asteroid != null)
asteroid.Set(this, Asteroid.ASTEROID_TYPE.Medium, GetRandomSpin(), GetRandomVelocity(), position);
break;
case Asteroid.ASTEROID_TYPE.Medium:
asteroid = (Asteroid)ActivateItem((int)Asteroid.ASTEROID_TYPE.Small);
if (asteroid != null)
asteroid.Set(this, Asteroid.ASTEROID_TYPE.Small, GetRandomSpin(), GetRandomVelocity(), position);
asteroid = (Asteroid)ActivateItem((int)Asteroid.ASTEROID_TYPE.Small);
if (asteroid != null)
asteroid.Set(this, Asteroid.ASTEROID_TYPE.Small, GetRandomSpin(), GetRandomVelocity(), position);
break;
case Asteroid.ASTEROID_TYPE.Small:
break;
}
}
}
、、、、、、、、、、、、、、、、、、、、、、下面是Asteroid
public class Asteroid : SwarmItem
{
private AsteroidManager _asteroidManager;
private ASTEROID_TYPE _asteroidType;
private Vector3 _rotation;
private Vector3 _velocity;
private Vector3 _originalScale;
public enum ASTEROID_TYPE
{
Small = 0,
Medium = 1,
Large = 2
}
/// 重要的初始化函数
public override void Initialize(SwarmItemManager swarmItemManager, int prefabIndex, bool debugEvents)
{
base.Initialize(swarmItemManager, prefabIndex, debugEvents);
_originalScale = _thisTransform.localScale;
}
/// Sets the asteroids parameters
public void Set(AsteroidManager asteroidManager, ASTEROID_TYPE asteroidType, Vector3 rotation, Vector3 velocity, Vector3 position)
{
_asteroidManager = asteroidManager;
_asteroidType = asteroidType;
_rotation = rotation;
_velocity = velocity;
// We use the Accessor for this member to update the transform position
Position = position;
}
//更新每一帧
public override void FrameUpdate()
{
// move asteroid
Position += (_velocity * Time.deltaTime);
// reflect the asteroid's velocity within the field so that asteroid's aren't flying off into infinity
if (Position.sqrMagnitude >= _asteroidManager.FieldRadiusSquared)
{
// save the normalized position since we'll be using it twice below.
// this cuts down on the normalization calculations which can be expensive,
// especially when done every frame.
Vector3 normalizedPosition = Position.normalized;
// clip the asteroid's position to the field radius
Position = normalizedPosition * _asteroidManager.fieldRadius;
// reflect the velocity across the inverted normal (makes the asteroid bounce back)
_velocity = Vector3.Reflect(_velocity, -normalizedPosition);
}
_thisTransform.Rotate(_rotation * Time.deltaTime);
base.FrameUpdate();
}
/// Called after being activated or deactivated
protected override void OnStateChange ()
{
switch (_state)
{
case STATE.Inactive:
_asteroidManager.BreakUpAsteroid(_asteroidType, Position);
Explosion explosion = (Explosion)Main.Instance.explosionManager.ActivateItem();
if (explosion != null)
explosion.Position = Position;
break;
}
}
public override void OnSetParentTransform()
{
_thisTransform.localScale = _originalScale;
}
}