U3d插件——Swarm Object Manager分析(五)Asteroid 和 AsteroidManager 的实现


/// 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 initialSmallAsteroidCount;
    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; } }

   

、、重要的。。重要的

    public override void Initialize()
    {
        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         {
            // 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);
    }    


   //打碎石头之后的处理

    public void BreakUpAsteroid(Asteroid.ASTEROID_TYPE asteroidType, Vector3 position)
    {
        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;
    }
}


你可能感兴趣的:(游戏)