public static ActorAnimation Read(BlockReader reader, ActorComponent[] components) { ActorAnimation animation = new ActorAnimation(); animation.m_Name = Actor.ReadString(reader); animation.m_FPS = (int)reader.ReadByte(); animation.m_Duration = reader.ReadSingle(); animation.m_IsLooping = reader.ReadByte() != 0; int numKeyedComponents = reader.ReadUInt16(); //animation.m_Components = new ComponentAnimation[numKeyedComponents]; // We distinguish between animated and triggered components as ActorEvents are currently only used to trigger events and don't need // the full animation cycle. This lets them optimize them out of the regular animation cycle. int animatedComponentCount = 0; int triggerComponentCount = 0; ComponentAnimation[] animatedComponents = new ComponentAnimation[numKeyedComponents]; for (int i = 0; i < numKeyedComponents; i++) { ComponentAnimation componentAnimation = ComponentAnimation.Read(reader, components); animatedComponents[i] = componentAnimation; if (componentAnimation != null) { ActorComponent actorComponent = components[componentAnimation.ComponentIndex]; if (actorComponent != null) { if (actorComponent is ActorEvent) { triggerComponentCount++; } else { animatedComponentCount++; } } } } animation.m_Components = new ComponentAnimation[animatedComponentCount]; animation.m_TriggerComponents = new ComponentAnimation[triggerComponentCount]; // Put them in their respective lists. int animatedComponentIndex = 0; int triggerComponentIndex = 0; for (int i = 0; i < numKeyedComponents; i++) { ComponentAnimation componentAnimation = animatedComponents[i]; if (componentAnimation != null) { ActorComponent actorComponent = components[componentAnimation.ComponentIndex]; if (actorComponent != null) { if (actorComponent is ActorEvent) { animation.m_TriggerComponents[triggerComponentIndex++] = componentAnimation; } else { animation.m_Components[animatedComponentIndex++] = componentAnimation; } } } } return(animation); }