0
\$\begingroup\$

I am building a game where players can build their own airplanes and fly them around. When the vehicle is spawned, all the buildables used to construct the airplane should be placed into groups of 20 to be merged as a submesh to the airplane. When one of the buildables is hit by a projectile and is destroyed, the mesh is reloaded, this time without the buildable that was hit creating the illusion that it was destroyed.

I have a few scripts

Airplane Core:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[System.Serializable]
public class AirplaneCore : MonoBehaviour {

    public GameObject airplaneCore;
    public List<AirplaneBuildable> buildables;
    public List<AirplaneChunk> chunks;

    void Start () {
        AirplaneChunk[] airplaneChunks = airplaneCore.GetComponentsInChildren<AirplaneChunk> ();
        foreach (AirplaneChunk chunk in airplaneChunks) {
            chunks.Add (chunk);
        }
    }
}

AirplaneBuildable:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[System.Serializable]
public class AirplaneBuildable {
    public string buildableName;
    public GameObject buildableObject;
    public GameObject buildableNormalPrefab, buildableEditorPrefab, buildablePreviewPrefab;
    public Vector3 pos, rot;
    public bool destroyed = false;
    public float health = 100f, maxHealth = 100f;
}

And Airplane Chunk:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[System.Serializable]
public class AirplaneChunk : MonoBehaviour {
    public List<AirplaneBuildable> buildablesInChunk;
}

Anyone know a way I can take the buildables from AirplaneCore and place them in groups of 20 and assign each group to an AirplaneChunk's buildablesInChunk list?

For those who don't know, the gameobjects that are in the AirplaneBuilder script are: -Buildable Object: The actual object representing the component that was placed on the airplane. -Buildable Normal Prefab: The buildable that is spawned when spawning the plane. -Buildable Editor Prefab: The buildable that appears on the airplane in the vehicle builder editor. -Buildable Preview Prefab: Is simply a preview of the buildable and shows what it will look like when placed on the airplane.

\$\endgroup\$
2
  • \$\begingroup\$ This question has an answer here: Create batches in linq (StackOverflow). \$\endgroup\$ – Olivier Jacot-Descombes Oct 25 '18 at 14:19
  • \$\begingroup\$ The problem with that is it uses a premade bunch of scripts. I am trying to learn how to make my own for the sake of learning how to do it. For some reason I really don't like using premade libraries. \$\endgroup\$ – Kenneth Carrington Oct 25 '18 at 14:22
1
\$\begingroup\$

To make it in a generic way, there must be a logical conversion from List<AirplaneBuildable> to AirplaneChunk. Therefore I create an abstract base class

public abstract class Chunk<T> : MonoBehaviour
{
    public List<T> BuildablesChunk { get; set; }
}

AirplaneChunk is now redefined as

[System.Serializable]
public class AirplaneChunk : Chunk<AirplaneBuildable>
{
}

Instead of having a fixed typed List<AirplaneBuildable> buildablesInChunk field, it has now a List<AirplaneBuildable> BuildablesChunk property (a field would work as well, if you prefer) resulting from a generic type argument.

Now we can implement the chunking as

TChunk[] GetComponentsInChildren<TSource, TChunk>(IList<TSource> source)
    where TChunk : Chunk<TSource>, new()
{
    const int ChunkSize = 20;

    int numberOfChunks = (source.Count + ChunkSize - 1) / ChunkSize;
    var chunks = new TChunk[numberOfChunks];
    for (int i = 0; i < numberOfChunks; i++) {
        List<TSource> batch = source.Skip(i * ChunkSize).Take(ChunkSize).ToList();
        var chunk = new TChunk { BuildablesChunk = batch };
        chunks[i] = chunk;
    }

    return chunks;
}

And can call it with

AirplaneChunk[] airplaneChunks =
    GetComponentsInChildren<AirplaneBuildable, AirplaneChunk>(buildables);
chunks.AddRange(airplaneChunks);

Note that we need two type parameters, as we cannot infer the chunk type (AirplaneChunk) from (AirplaneBuildable). You could have several classes deriving from Chunk<AirplaneBuildable>. C# has no way of knowing which one you meant.

We also need generic type constraints (where TChunk : Chunk<TSource>, new()). Basically Chunk<TSource> says: we have a type having a List<T> BuildablesChunk property we can assign the result to. And new() says: TChunk must have a default constructor.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.