public void AttachBodyPart(BodyPartController bpc)
        {
            #region Nearest Bone
            int   nearestBoneIndex = -1;
            float minDistance      = float.PositiveInfinity;

            for (int boneIndex = 0; boneIndex < root.childCount; boneIndex++)
            {
                float distance = Vector3.Distance(root.GetChild(boneIndex).position, bpc.transform.position);
                if (distance < minDistance)
                {
                    minDistance      = distance;
                    nearestBoneIndex = boneIndex;
                }
            }
            #endregion

            if (bpc.AttachedBodyPart == null)
            {
                AttachedBodyPart attachedBodyPart = new AttachedBodyPart(bpc.name.Replace("(Flipped)", ""), nearestBoneIndex, new SerializableTransform(bpc.transform));
                bpc.AttachedBodyPart = bpc.Flipped.AttachedBodyPart = attachedBodyPart;
                bpc.Drag.WorldBounds = bpc.Flipped.Drag.WorldBounds = new Bounds(new Vector3(0, 1, 0), new Vector3(4, 4, 4));

                data.attachedBodyParts.Add(attachedBodyPart);
            }
            bpc.transform.SetParent(root.GetChild(nearestBoneIndex), true);
        }
        public void Load(string creatureName)
        {
            Clear();

            CreatureData data = JsonUtility.FromJson <CreatureData>(SaveUtility.Load(creatureName + ".json"));

            for (int i = 0; i < data.bones.Count; i++)
            {
                Bone bone = data.bones[i];
                Add(i, bone.Position, bone.Rotation, bone.Size);
            }
            for (int i = 0; i < data.attachedBodyParts.Count; i++)
            {
                AttachedBodyPart attachedBodyPart = data.attachedBodyParts[i];

                BodyPartController bpc = Instantiate(DatabaseManager.GetDatabaseEntry <BodyPart>("Body Parts", attachedBodyPart.BodyPartID).Prefab, root.GetChild(attachedBodyPart.BoneIndex)).GetComponent <BodyPartController>();
                bpc.gameObject.name = attachedBodyPart.BodyPartID;

                SerializableTransform.RecurseUpdate(bpc.transform, attachedBodyPart.Transform);

                SetupBodyPart(bpc);
                AttachBodyPart(bpc);
                AddToStatistics(bpc.name);

                if (Mathf.Abs(bpc.transform.position.x) > settings.MergeThreshold)
                {
                    bpc.Flipped.transform.position = new Vector3(-bpc.transform.position.x, bpc.transform.position.y, bpc.transform.position.z);
                    bpc.Flipped.transform.rotation = Quaternion.Euler(bpc.transform.rotation.eulerAngles.x, -bpc.transform.rotation.eulerAngles.y, -bpc.transform.rotation.eulerAngles.z);

                    if (bpc is LimbController)
                    {
                        LimbController limb        = bpc as LimbController;
                        LimbController flippedLimb = limb.FlippedLimb;

                        for (int j = 0; j < limb.Bones.Length; j++)
                        {
                            float x = -limb.Bones[j].position.x;
                            float y = limb.Bones[j].position.y;
                            float z = limb.Bones[j].position.z;

                            flippedLimb.Bones[j].position = new Vector3(x, y, z);
                        }
                    }
                }
                else
                {
                    bpc.Flipped.gameObject.SetActive(false);
                }
            }
            SetColours(data.primaryColour, data.secondaryColour);
            SetPattern(data.patternID);

            SetSelected(false);
            SetTextured(Textured);
            SetInteractable(Interactable);
        }
        public void DetachBodyPart(BodyPartController bpc)
        {
            for (int i = 0; i < data.attachedBodyParts.Count; i++)
            {
                if (data.attachedBodyParts[i] == bpc.AttachedBodyPart)
                {
                    data.attachedBodyParts.RemoveAt(i);
                    break;
                }
            }

            if (bpc.AttachedBodyPart != null)
            {
                bpc.AttachedBodyPart = bpc.Flipped.AttachedBodyPart = null;
            }
        }
        public void SetupBodyPart(BodyPartController bpc)
        {
            BodyPartController flipped = Instantiate(bpc.gameObject, bpc.transform.parent).GetComponent <BodyPartController>();

            bpc.Flipped     = flipped;
            flipped.Flipped = bpc;

            flipped.gameObject.name = bpc.gameObject.name + "(Flipped)";
            if (bpc is LimbController)
            {
                LimbController limb = bpc as LimbController;

                limbs.Add(limb);
                limbs.Add(limb.FlippedLimb);
            }
            else
            {
                flipped.Model.localScale = new Vector3(-flipped.Model.localScale.x, flipped.Model.localScale.y, flipped.Model.localScale.z);
            }

            #region Interact
            UnityAction onPress = delegate
            {
                CreatureCreator.Instance.CameraOrbit.Freeze();

                bpc.transform.SetParent(Dynamic.Transform);
                flipped.transform.SetParent(Dynamic.Transform);

                bpc.gameObject.SetLayerRecursively(LayerMask.NameToLayer("Ignore Raycast"), new List <string> {
                    "Tools"
                });
                flipped.gameObject.SetLayerRecursively(LayerMask.NameToLayer("Ignore Raycast"), new List <string> {
                    "Tools"
                });
            };
            UnityAction onRelease = delegate
            {
                CreatureCreator.Instance.CameraOrbit.Unfreeze();

                DetachBodyPart(bpc);
                DetachBodyPart(flipped);

                if (Physics.Raycast(RectTransformUtility.ScreenPointToRay(CreatureCreator.Instance.CameraOrbit.Camera, Input.mousePosition), out RaycastHit raycastHit) && raycastHit.collider.CompareTag("Player"))
                {
                    AttachBodyPart(bpc);
                    AttachBodyPart(flipped);
                }
                else
                {
                    audioSource.PlayOneShot(poofAudioClip);
                    Instantiate(poofEffect, bpc.Drag.IsPressing ? bpc.transform.position : flipped.transform.position, Quaternion.identity, Dynamic.Transform);
                    RemoveFromStatistics(bpc.name);

                    if (bpc is LimbController)
                    {
                        LimbController limb = bpc as LimbController;

                        limbs.Remove(limb);
                        limbs.Remove(limb.FlippedLimb);
                    }

                    Destroy(bpc.gameObject);
                    Destroy(flipped.gameObject);
                }

                bpc.gameObject.SetLayerRecursively(LayerMask.NameToLayer("Body"), new List <string> {
                    "Tools"
                });
                flipped.gameObject.SetLayerRecursively(LayerMask.NameToLayer("Body"), new List <string> {
                    "Tools"
                });

                bpc.Drag.Plane = flipped.Drag.Plane = new Plane(Vector3.right, Vector3.zero);
            };
            UnityAction onDrag = delegate
            {
                if (Physics.Raycast(RectTransformUtility.ScreenPointToRay(CreatureCreator.Instance.CameraOrbit.Camera, Input.mousePosition), out RaycastHit raycastHit) && raycastHit.collider.CompareTag("Player"))
                {
                    bpc.Drag.Draggable = false;

                    bpc.transform.position = raycastHit.point;
                    bpc.transform.rotation = Quaternion.LookRotation(raycastHit.normal);

                    if (Mathf.Abs(bpc.transform.position.x) > settings.MergeThreshold)
                    {
                        flipped.gameObject.SetActive(true);
                        flipped.transform.position = new Vector3(-bpc.transform.position.x, bpc.transform.position.y, bpc.transform.position.z);
                        flipped.transform.rotation = Quaternion.Euler(bpc.transform.rotation.eulerAngles.x, -bpc.transform.rotation.eulerAngles.y, -bpc.transform.rotation.eulerAngles.z);
                    }
                    else
                    {
                        flipped.gameObject.SetActive(false);
                        bpc.transform.position = new Vector3(0, bpc.transform.position.y, bpc.transform.position.z);
                        bpc.transform.rotation = Quaternion.LookRotation(new Vector3(0, raycastHit.normal.y, raycastHit.normal.z));

                        if (bpc is LimbController)
                        {
                            foreach (Transform bone in (bpc as LimbController).Bones)
                            {
                                bone.position = new Vector3(0, bone.position.y, bone.position.z);
                            }
                        }
                    }
                }
                else
                {
                    bpc.Drag.Draggable = true;
                    flipped.gameObject.SetActive(false);
                }
            };
            UnityAction onFlippedDrag = delegate
            {
                if (Physics.Raycast(RectTransformUtility.ScreenPointToRay(CreatureCreator.Instance.CameraOrbit.Camera, Input.mousePosition), out RaycastHit raycastHit) && raycastHit.collider.CompareTag("Player"))
                {
                    flipped.Drag.Draggable = false;

                    flipped.transform.position = raycastHit.point;
                    flipped.transform.rotation = Quaternion.LookRotation(raycastHit.normal);

                    if (Mathf.Abs(flipped.transform.position.x) > settings.MergeThreshold)
                    {
                        bpc.gameObject.SetActive(true);
                        bpc.transform.position = new Vector3(-flipped.transform.position.x, flipped.transform.position.y, flipped.transform.position.z);
                        bpc.transform.rotation = Quaternion.Euler(flipped.transform.rotation.eulerAngles.x, -flipped.transform.rotation.eulerAngles.y, -flipped.transform.rotation.eulerAngles.z);
                    }
                    else
                    {
                        bpc.gameObject.SetActive(false);
                        flipped.transform.position = new Vector3(0, flipped.transform.position.y, flipped.transform.position.z);
                        flipped.transform.rotation = Quaternion.LookRotation(new Vector3(0, raycastHit.normal.y, raycastHit.normal.z));

                        if (bpc is LimbController)
                        {
                            foreach (Transform bone in (flipped as LimbController).Bones)
                            {
                                bone.position = new Vector3(0, bone.position.y, bone.position.z);
                            }
                        }
                    }
                }
                else
                {
                    flipped.Drag.Draggable = true;
                    bpc.gameObject.SetActive(false);
                }
            };

            bpc.Drag.OnPress.AddListener(onPress);
            bpc.Drag.OnDrag.AddListener(onDrag);
            bpc.Drag.OnRelease.AddListener(onRelease);
            flipped.Drag.OnPress.AddListener(onPress);
            flipped.Drag.OnDrag.AddListener(onFlippedDrag);
            flipped.Drag.OnRelease.AddListener(onRelease);
            #endregion
        }
Ejemplo n.º 5
0
        private void Start()
        {
            SetCash(startingCash);

            #region Creature
            creature.Add(0, new Vector3(0, 0.75f, 0), Quaternion.identity, 0f);
            creature.AddToBack();

            creature.SetSelected(false);
            creature.SetTextured(false);
            creature.SetInteractable(true);
            #endregion

            #region UI
            statisticsMenu  = Instantiate(statisticsMenuPrefab, Dynamic.Canvas).GetComponent <StatisticsMenu>();
            patternMaterial = new Material(patternMaterial);

            foreach (string bodyPartID in DatabaseManager.GetDatabase("Body Parts").Objects.Keys)
            {
                BodyPart bodyPart = DatabaseManager.GetDatabaseEntry <BodyPart>("Body Parts", bodyPartID);

                GameObject bodyPartGO       = Instantiate(bodyPartPrefab, bodyPartGrids[bodyPart.GetType().Name].GetComponent <RectTransform>());
                Animator   bodyPartAnimator = bodyPartGO.GetComponent <Animator>();

                DragUI dragUI = bodyPartGO.GetComponent <DragUI>();
                dragUI.OnPress.AddListener(delegate
                {
                    bodyPartAnimator.SetBool("Expanded", false);
                    statisticsMenu.Hide();
                });
                dragUI.OnRelease.AddListener(delegate
                {
                    bodyPartGrids[bodyPart.GetType().Name].enabled = false;
                    bodyPartGrids[bodyPart.GetType().Name].enabled = true;
                });
                dragUI.OnDrag.AddListener(delegate
                {
                    bool notEnoughCash = (cash < bodyPart.Price);
                    bool tooComplex    = (creature.Statistics.Complexity + bodyPart.Complexity > creature.Settings.MaximumComplexity);
                    if (notEnoughCash || tooComplex)
                    {
                        dragUI.OnPointerUp(null);
                        audioSource.PlayOneShot(errorAudioClip);

                        if (notEnoughCash && !cashWarningAnimator.IsInTransition(0) && !cashWarningAnimator.GetCurrentAnimatorStateInfo(0).IsName("Warning"))
                        {
                            cashWarningAnimator.SetTrigger("Warn");
                        }
                        if (tooComplex && !complexityWarningAnimator.IsInTransition(0) && !complexityWarningAnimator.GetCurrentAnimatorStateInfo(0).IsName("Warning"))
                        {
                            complexityWarningAnimator.SetTrigger("Warn");
                        }
                    }

                    if (!RectTransformUtility.RectangleContainsScreenPoint(bodyPartsRT, Input.mousePosition))
                    {
                        dragUI.OnPointerUp(null);
                        audioSource.PlayOneShot(createAudioClip);
                        creature.AddToStatistics(bodyPartID);

                        Ray ray     = cameraOrbit.Camera.ScreenPointToRay(Input.mousePosition);
                        Plane plane = new Plane(cameraOrbit.Camera.transform.forward, Vector3.zero);

                        if (plane.Raycast(ray, out float distance))
                        {
                            BodyPartController bpc = Instantiate(bodyPart.Prefab, ray.GetPoint(distance), Quaternion.identity, Dynamic.Transform).GetComponent <BodyPartController>();

                            bpc.gameObject.name = bodyPartID;

                            bpc.Drag.Plane = plane;
                            creature.SetupBodyPart(bpc);
                            bpc.Drag.OnMouseDown();
                        }
                    }
                });