예제 #1
0
    public void SetPlacementsActiveBasedOnDistance(string placementIdToAlwaysShow = "")
    {
        if (Managers.personManager == null || Managers.personManager.ourPerson == null ||
            Managers.personManager.ourPerson.Head == null ||
            Managers.areaManager == null)
        {
            return;
        }
        Transform ourTransform = Managers.personManager.ourPerson.Head.transform;

        GameObject[] things = Misc.GetChildrenAsArray(Managers.thingManager.placements.transform);
        things = things.OrderBy(
            x => Vector3.Distance(ourTransform.position, x.transform.position)
            ).ToArray();

        int thingsCount = 0;
        int baseLayerParticleSystemsCount = 0;
        int particleSystemsCount          = 0;
        int lightsCount = 0;
        int lightsThrowingShadowsCount = 0;
        int allPartsImageCount         = 0;

        const float distanceAtWhichToShowAnything = 2.5f;

        foreach (GameObject thingObject in things)
        {
            if (thingObject != CreationHelper.thingThatWasClonedFrom &&
                thingObject != CreationHelper.thingBeingEdited &&
                thingObject.name != Universe.objectNameIfAlreadyDestroyed)
            {
                Thing thing             = thingObject.GetComponent <Thing>();
                bool  alwaysShowThisOne =
                    (!string.IsNullOrEmpty(placementIdToAlwaysShow) && thing.placementId == placementIdToAlwaysShow) ||
                    thing.isHighlighted;
                if (!alwaysShowThisOne)
                {
                    bool forceShow = false;
                    bool forceHide = false;

                    float distance = Vector3.Distance(ourTransform.position, thingObject.transform.position);

                    if (thing.distanceToShow != null && !thing.isHighlighted)
                    {
                        if (distance <= (float)thing.distanceToShow)
                        {
                            forceShow = true;
                        }
                        else
                        {
                            forceHide = true;
                        }
                    }

                    bool didEnable = false;
                    bool makeExceptionToShowAnyway = false;
                    if (!thing.suppressShowAtDistance)
                    {
                        makeExceptionToShowAnyway = thing.thingPartCount <= 15 &&
                                                    (thing.isVeryBig || thing.requiresWiderReach || thing.hasSurroundSound);
                        if (thing.benefitsFromShowingAtDistance || thing.temporarilyBenefitsFromShowingAtDistance ||
                            distance <= distanceAtWhichToShowAnything)
                        {
                            makeExceptionToShowAnyway = true;
                        }
                    }

                    if ((thingsCount < maxThingsAround || makeExceptionToShowAnyway || forceShow) && !forceHide)
                    {
                        thingsCount++;

                        float requiredSizeToShow = 0f;
                        if (!(thing.containsBehaviorScript && distance <= 35f))
                        {
                            if (distance >= 100f)
                            {
                                requiredSizeToShow = 15f;
                            }
                            else if (distance >= 75f)
                            {
                                requiredSizeToShow = 6f;
                            }
                            else if (distance >= 50f)
                            {
                                requiredSizeToShow = 2f;
                            }
                            else if (distance >= 25f)
                            {
                                requiredSizeToShow = 1f;
                            }
                        }

                        bool isFarAwayWithManyParts = distance >= 50f && thing.thingPartCount >= 25;

                        if (makeExceptionToShowAnyway ||
                            (thing.biggestSize >= requiredSizeToShow && !isFarAwayWithManyParts) || forceShow)
                        {
                            thing.gameObject.SetActive(true);
                            didEnable = true;

                            if (thing.containsBaseLayerParticleSystem)
                            {
                                baseLayerParticleSystemsCount++;
                                bool doOptimizeBaseLayerParticleSystem =
                                    baseLayerParticleSystemsCount > Managers.optimizationManager.maxBaseLayerParticleSystemsAround &&
                                    !thing.benefitsFromShowingAtDistance;
                                AdjustThingParticleSystemsOptimization(thing.gameObject, doOptimizeBaseLayerParticleSystem);
                            }

                            if (thing.containsParticleSystem)
                            {
                                particleSystemsCount++;
                                bool doOptimizeParticleSystem =
                                    particleSystemsCount > Managers.optimizationManager.maxParticleSystemsAround &&
                                    !thing.benefitsFromShowingAtDistance;
                                thing.SetParticleSystemsStopPlay(!doOptimizeParticleSystem);
                            }

                            if (thing.containsLight)
                            {
                                lightsCount++;
                                thing.AdjustLightsOptimization(
                                    doOptimize: lightsCount > Managers.optimizationManager.maxLightsAround && !forceShow);

                                if (lightsThrowingShadowsCount < Managers.optimizationManager.maxLightsToThrowShadows)
                                {
                                    int?limit         = Managers.optimizationManager.maxLightsToThrowShadows - lightsThrowingShadowsCount;
                                    int affectedCount = thing.SetLightShadows(true, limit);
                                    lightsThrowingShadowsCount += affectedCount;
                                }
                                else
                                {
                                    thing.SetLightShadows(false);
                                }
                            }

                            if (thing.allPartsImageCount > 0)
                            {
                                allPartsImageCount += thing.allPartsImageCount;
                                bool isWithinLimits =
                                    allPartsImageCount <= Managers.optimizationManager.maxImagePartsAroundCount ||
                                    thing.IsPlacedSubThing() || thing.movableByEveryone;
                                thing.SetImagePartsActive(isWithinLimits);
                            }
                        }
                    }

                    if (!didEnable)
                    {
                        thing.gameObject.SetActive(false);
                    }
                }
            }
        }

        Managers.areaManager.LimitVisibilityIfNeeded();
    }