public void PickNRandomAttachmentPrefabs(CreatureDescriptor newDescriptor)
    {
        int DescriptorCount = AttachmentDatabase.Length;

        if (DescriptorCount > 0)
        {
            int AttachmentCount = SpawnAttachmentCount.RandomValue;
            newDescriptor.Attachments     = new GameObject[AttachmentCount];
            newDescriptor.AttachmentTypes = new CreatureAttachmentDescriptor[AttachmentCount];

            for (int AttachmentIndex = 0; AttachmentIndex < AttachmentCount; ++AttachmentIndex)
            {
                CreatureAttachmentDescriptor Descriptor = PickRandomAttachmentDescriptor();
                int VariationIndex = Random.Range(0, Descriptor.Variations.Length);

                newDescriptor.Attachments[AttachmentIndex]     = Descriptor.Variations[VariationIndex];
                newDescriptor.AttachmentTypes[AttachmentIndex] = Descriptor;
            }
        }
        else
        {
            newDescriptor.Attachments     = new GameObject[0];
            newDescriptor.AttachmentTypes = new CreatureAttachmentDescriptor[0];
        }
    }
Exemple #2
0
    public void SpawnAttachments(CreatureDescriptor SpawnDescriptor)
    {
        // Clear off any previous attachments
        if (attachments.Count > 0)
        {
            for (int i = 0; i < attachments.Count; i++)
            {
                Destroy(attachments[i]);
            }
            attachments.Clear();
        }

        // Gather all available attach points
        attachPoints.Clear();
        attachPoints.AddRange(transform.GetComponentsInChildren <ProtoAttachPoint>(false));

        // Shuffle the indices of the attach points
        int[]  shuffledAttachPointIndices = ArrayUtilities.MakeShuffledIntSequence(0, attachPoints.Count - 1);
        bool[] usedAttachPoint            = new bool[attachPoints.Count];

        // Spawn each attachment using the first valid attach point we can find
        for (int attachmentIndex = 0; attachmentIndex < SpawnDescriptor.Attachments.Length; attachmentIndex++)
        {
            // Get the prefab and the constraints for the attachment
            CreatureAttachmentDescriptor attachmentDescriptor = SpawnDescriptor.AttachmentTypes[attachmentIndex];
            GameObject attachmentPrefab = SpawnDescriptor.Attachments[attachmentIndex];

            // Find the first spawn point that satisfies the constraints
            for (int shuffledListIndex = 0; shuffledListIndex < shuffledAttachPointIndices.Length; ++shuffledListIndex)
            {
                int attachPointIndex = shuffledAttachPointIndices[shuffledListIndex];

                // Skip any attach points that are already used
                if (usedAttachPoint[attachPointIndex])
                {
                    continue;
                }

                // Skip any attach points that violate our max pitch constraint
                ProtoAttachPoint attachPoint      = attachPoints[attachPointIndex];
                Vector3          attachPointUp    = attachPoint.transform.forward;
                float            attachPointPitch = Mathf.Abs(90.0f - Vector3.Angle(attachPointUp, Vector3.up));
                if (attachPointPitch > attachmentDescriptor.MaxAllowedPitchAngle)
                {
                    continue;
                }

                // Spawn the attachment
                GameObject attachment = Instantiate(attachmentPrefab, attachPoint.transform) as GameObject;
                attachment.transform.localPosition    = Vector3.zero;
                attachment.transform.localEulerAngles = new Vector3(0f, 0f, Random.Range(RotateMinMax.x, RotateMinMax.y));
                attachment.transform.localScale      *= Random.Range(ScaleMinMax.x, ScaleMinMax.y);
                attachments.Add(attachment);

                // Mark the attach point as used
                usedAttachPoint[attachPointIndex] = true;

                // Stop searching for a valid attach point
                break;
            }
        }
    }