示例#1
0
 private void UpdateProfile()
 {
     // clients will get the transition sent to them via network extension
     if (WeatherMakerScript.Instance == null || !WeatherMakerScript.Instance.NetworkConnection.IsServer || (SingleProfile == null && ProfileGroup == null))
     {
         return;
     }
     else if (SingleProfile == null)
     {
         currentProfileSingle = null;
         if (secondsRemainingTransition <= 0.0f)
         {
             if ((secondsRemainingHold -= Time.deltaTime) <= 0.0f)
             {
                 // setup new transition
                 WeatherMakerProfileScript oldProfile = currentProfile;
                 currentProfile = ProfileGroup.PickWeightedProfile();
                 RangeOfFloats duration = TransitionDuration;
                 currentProfile = WeatherMakerProfileGroupScript.OverrideProfile(currentProfile, CloudProfile, SkyProfile, AuroraProfile,
                                                                                 PrecipitationProfile, FogProfile, WindProfile, LightningProfile, SoundProfile, duration, HoldDuration);
                 secondsRemainingTransition = currentProfile.RandomTransitionDuration();
                 secondsRemainingHold       = currentProfile.RandomHoldDuration();
                 NotifyThoseInZoneOfProfileChange(oldProfile, currentProfile, secondsRemainingTransition);
                 CleanupProfile(oldProfile);
             }
         }
         else
         {
             // else let the transition continue
             secondsRemainingTransition -= Time.deltaTime;
         }
     }
     else if (SingleProfile != currentProfileSingle)
     {
         currentProfileSingle = SingleProfile;
         WeatherMakerProfileScript oldProfile = currentProfile;
         RangeOfFloats             duration   = TransitionDuration;
         currentProfile = WeatherMakerProfileGroupScript.OverrideProfile(SingleProfile, CloudProfile, SkyProfile, AuroraProfile,
                                                                         PrecipitationProfile, FogProfile, WindProfile, LightningProfile, SoundProfile, duration, HoldDuration);
         secondsRemainingTransition = currentProfile.RandomTransitionDuration();
         NotifyThoseInZoneOfProfileChange(oldProfile, SingleProfile, secondsRemainingTransition);
         CleanupProfile(oldProfile);
     }
 }
        /// <summary>
        /// Pick a random profile based on weights of the profiles
        /// </summary>
        /// <returns>Random weighted profile or null if no profiles setup</returns>
        public WeatherMakerProfileScript PickWeightedProfile()
        {
            if (Profiles == null || Profiles.Length == 0)
            {
                return(null);
            }

            int maxWeight = 0;

            // ensure profiles are sorted by weight ascending
            sortedProfiles.Clear();
            sortedProfiles.AddRange(Profiles);
            sortedProfiles.Sort(this);

            // get the max weight (sum of all weights)
            foreach (WeatherMakerProfileAndWeight w in sortedProfiles)
            {
                if (!w.Profile.Disabled)
                {
                    maxWeight += w.Weight;
                }
            }

            // pick a weight that we need to exceed to pick a profile
            int randomWeight = UnityEngine.Random.Range(0, maxWeight);

            // interate all profiles, as we sum up the weight and it crosses are random weight, we have our profile
            foreach (WeatherMakerProfileAndWeight profile in sortedProfiles)
            {
                if (!profile.Profile.Disabled)
                {
                    if (randomWeight < profile.Weight)
                    {
                        WeatherMakerProfileScript individualProfile = profile.GetProfile();
                        return(OverrideProfile(individualProfile, CloudProfile, SkyProfile, AuroraProfile, PrecipitationProfile, FogProfile, WindProfile, LightningProfile, SoundProfile, TransitionDuration, HoldDuration));
                    }
                    randomWeight -= profile.Weight;
                }
            }

            // shouldn't get here
            Debug.LogError("Error in PickWeightedProfile algorithm, should not return null here");
            return(null);
        }
示例#3
0
 private void TargetRpcWeatherProfileChanged(NetworkConnection conn, string oldProfileName, string oldProfileJson, string newProfileName, string newProfileJson, float transitionDuration)
 {
     if (netId != 0 && isClient && WeatherMakerScript.Instance != null)
     {
         // notify any listeners of the change - hold duration is -1.0 meaning the server will send another profile when it is ready (hold duration unknown to client)
         WeatherMakerProfileScript oldProfileFromJson = null;
         WeatherMakerProfileScript newProfileFromJson = null;
         if (oldProfileName != null && oldProfileJson != null)
         {
             oldProfileFromJson = GameObject.Instantiate(Resources.Load <WeatherMakerProfileScript>(oldProfileName));
             JsonUtility.FromJsonOverwrite(oldProfileJson, oldProfileFromJson);
         }
         if (newProfileName != null && newProfileJson != null)
         {
             newProfileFromJson = GameObject.Instantiate(Resources.Load <WeatherMakerProfileScript>(newProfileName));
             JsonUtility.FromJsonOverwrite(newProfileJson, newProfileFromJson);
         }
         WeatherMakerScript.Instance.RaiseWeatherProfileChanged(oldProfileFromJson, newProfileFromJson, transitionDuration, -1.0f, true, null);
     }
 }
示例#4
0
        private void Update()
        {
            UpdateMainThreadActions();

#if UNITY_EDITOR
            if (transform.position != Vector3.zero || transform.localScale != Vector3.one || transform.rotation != Quaternion.identity)
            {
                Debug.LogError("For correct rendering, weather maker prefab should have position and rotation of 0, and scale of 1.");
            }
#endif

            // only for editor mode, detect when inspector has dragged in a new profile
            if (_WeatherProfile != lastProfile)
            {
                if (WeatherProfileChanged != null)
                {
                    WeatherProfileChanged.Invoke(lastProfile, _WeatherProfile);
                }
                lastProfile = _WeatherProfile;
                UpdateWeatherProfile();
            }

#if UNITY_EDITOR
            if (Application.isPlaying)
            {
#endif

            CheckForPrecipitationChange();
            UpdateCollision();
            UpdateClouds();

#if UNITY_EDITOR
        }
#endif

            UpdateShaders();
            UpdateCameras();
            LightManagerScript.Sun   = Sun;
            LightManagerScript.Moons = Moons;
        }
        /// <summary>
        /// Call whenever the weather profile needs to change, handles client/server, etc.
        /// If no networking or network server, this will perform the transition.
        /// WeatherProfileChanged will then be called.
        /// </summary>
        /// <param name="oldProfile">Old weather profile</param>
        /// <param name="newProfile">New weather profile</param>
        /// <param name="transitionDuration">Transition duration</param>
        /// <param name="holdDuration">Hold duration</param>
        /// <param name="forceTransition">True to force a transition, false otherwise. True means it was forced from a server or some other way.</param>
        /// <param name="connectionIds">Connection ids to send to (null for none or single player)</param>
        public void RaiseWeatherProfileChanged(WeatherMakerProfileScript oldProfile, WeatherMakerProfileScript newProfile, float transitionDuration,
                                               float holdDuration, bool forceTransition, string[] connectionIds)
        {
            // default behavior is to perform transition
            if (forceTransition || !NetworkConnection.IsConnected)
            {
                // if no network involved OR we are a client and we got a server update, perform the fast transition if needed
                if (!HasHadWeatherTransition)
                {
                    HasHadWeatherTransition = true;
                    transitionDuration      = 0.001f;
                }
                Debug.LogFormat("Changing weather profile {0} to {1}, transition time: {2}, hold time: {3}",
                                (oldProfile == null ? "None" : oldProfile.name), (newProfile == null ? "None" : newProfile.name), transitionDuration, (holdDuration <= 0.0f ? "Unknown" : holdDuration.ToString(CultureInfo.InvariantCulture)));
                newProfile.TransitionFrom(this, oldProfile, transitionDuration);
            }

            // notify listeners, if using network this should notify the network script to blast out a transition to all clients
            if (WeatherProfileChangedEvent != null)
            {
                WeatherProfileChangedEvent.Invoke(oldProfile, newProfile, transitionDuration, connectionIds);
            }
        }
示例#6
0
 /// <summary>
 /// Profile change event for aurora manager
 /// </summary>
 /// <param name="oldProfile">Old profile</param>
 /// <param name="newProfile">New profile</param>
 /// <param name="transitionDelay">Transition delay</param>
 /// <param name="transitionDuration">Transition duration</param>
 public void WeatherProfileChanged(WeatherMakerProfileScript oldProfile, WeatherMakerProfileScript newProfile, float transitionDelay, float transitionDuration)
 {
     CloudScript.AuroraAnimationDuration = transitionDelay + transitionDuration;
     CloudScript.AuroraProfile           = newProfile.AuroraProfile;
 }
示例#7
0
        public void TransitionFrom(IWeatherMakerProvider managers, WeatherMakerProfileScript script, float transitionDuration)
        {
            if (managers == null)
            {
                return;
            }

            float precipitationIntensity = (PrecipitationProfile == null ? 0.0f : PrecipitationProfile.IntensityRange.Random());
            float cloudChangeDuration;
            float precipitationChangeDelay;
            float precipitationChangeDuration;

            transitionDuration = (transitionDuration <= 0.0f ? float.MaxValue : transitionDuration);

            if (precipitationIntensity == 0.0f)
            {
                // changing to no precipitation, no delay in reduction of precipitation
                precipitationChangeDelay = 0.0f;

                // get precipitation removed quickly
                precipitationChangeDuration = transitionDuration * 0.5f;

                // clouds take full duration to transition out
                cloudChangeDuration = transitionDuration;
            }
            else
            {
                // delay change in precipitation so clouds, etc. have time to animate in
                precipitationChangeDelay = transitionDuration * 0.4f;

                // precipitation animates in with remainder of time after delay
                precipitationChangeDuration = transitionDuration - precipitationChangeDelay;

                // clouds animate in faster, we want them mostly in before precipitation gets going
                cloudChangeDuration = transitionDuration * 0.7f;
            }

            // notify precipitation manager
            if (managers.PrecipitationManager != null)
            {
                managers.PrecipitationManager.WeatherProfileChanged(script, this, precipitationChangeDelay, precipitationChangeDuration);
            }

            // notify clouds
            if (managers.CloudManager != null)
            {
                managers.CloudManager.WeatherProfileChanged(script, this, 0.0f, cloudChangeDuration);
            }

            // notify sky
            if (managers.SkyManager != null)
            {
                managers.SkyManager.WeatherProfileChanged(script, this, 0.0f, transitionDuration);
            }

            // notify aurora
            if (managers.AuroraManager != null)
            {
                managers.AuroraManager.WeatherProfileChanged(script, this, 0.0f, transitionDuration);
            }

            // notify fog
            if (managers.FogManager != null)
            {
                managers.FogManager.WeatherProfileChanged(script, this, 0.0f, transitionDuration);
            }

            // notify wind
            if (managers.WindManager != null)
            {
                managers.WindManager.WeatherProfileChanged(script, this, 0.0f, transitionDuration);
            }

            // notify thunder and lightning
            if (managers.ThunderAndLightningManager != null)
            {
                managers.ThunderAndLightningManager.WeatherProfileChanged(script, this, precipitationChangeDelay, transitionDuration);
            }

            // notify player sound manager
            if (managers.PlayerSoundManager != null)
            {
                managers.PlayerSoundManager.WeatherProfileChanged(script, this, precipitationChangeDelay, transitionDuration);
            }
        }
 /// <summary>
 /// Cloud manager weather profile change handler
 /// </summary>
 /// <param name="oldProfile">Old profile</param>
 /// <param name="newProfile">New profile</param>
 /// <param name="transitionDelay">Transition delay</param>
 /// <param name="transitionDuration">Transition duration</param>
 public void WeatherProfileChanged(WeatherMakerProfileScript oldProfile, WeatherMakerProfileScript newProfile, float transitionDelay, float transitionDuration)
 {
     CloudScript.ShowCloudsAnimated(newProfile.CloudProfile, transitionDelay, transitionDuration);
 }
示例#9
0
 /// <summary>
 /// Weather profile changed handler for wind
 /// </summary>
 /// <param name="oldProfile">Old profile</param>
 /// <param name="newProfile">New profile</param>
 /// <param name="transitionDelay">Transition delay</param>
 /// <param name="transitionDuration">Transition duration</param>
 public void WeatherProfileChanged(WeatherMakerProfileScript oldProfile, WeatherMakerProfileScript newProfile, float transitionDelay, float transitionDuration)
 {
     WindScript.SetWindProfileAnimated(newProfile.WindProfile, transitionDelay, transitionDuration);
 }
示例#10
0
 public void WeatherProfileChanged(WeatherMakerProfileScript oldProfile, WeatherMakerProfileScript newProfile, float transitionDelay, float transitionDuration)
 {
     FogScript.ShowFogAnimated(newProfile.FogProfile, transitionDelay, transitionDuration);
 }
示例#11
0
        private void NotifyThoseInZoneOfProfileChange(WeatherMakerProfileScript oldProfile, WeatherMakerProfileScript newProfile, float transitionDuration)
        {
            // anyone in this zone gets a new profile
            List <Transform> playersInZone;

            if (!zonesAndPlayers.TryGetValue(this, out playersInZone) || !PruneNulls(playersInZone))
            {
                // no players in zone, we are done
                return;
            }
            List <string> connectionIds  = new List <string>();
            bool          hasLocalPlayer = false;

            for (int i = 0; i < playersInZone.Count; i++)
            {
                Transform player = playersInZone[i];
                hasLocalPlayer = WeatherMakerScript.IsLocalPlayer(player);
                connectionIds.Add(WeatherMakerScript.Instance.NetworkConnection.GetConnectionId(player));
            }

            if (hasLocalPlayer)
            {
                WeatherMakerScript.Instance.LastLocalProfile = newProfile;
            }

            // send notification that those in this zone need a new weather profile
            WeatherMakerScript.Instance.RaiseWeatherProfileChanged(oldProfile, newProfile, secondsRemainingTransition,
                                                                   secondsRemainingHold, false, connectionIds.ToArray());
        }
示例#12
0
        private void OnTriggerExit(Collider other)
        {
            if (SingleProfile == null && ProfileGroup == null)
            {
                return;
            }

            bool isServer = WeatherMakerScript.Instance != null && WeatherMakerScript.Instance.NetworkConnection.IsServer;

            if (isServer && gameObject.activeInHierarchy && enabled && WeatherMakerScript.IsPlayer(other.transform))
            {
                List <WeatherMakerWeatherZoneScript> playerZones;
                if (!playersAndZones.TryGetValue(other.transform, out playerZones))
                {
                    playersAndZones[other.transform] = playerZones = new List <WeatherMakerWeatherZoneScript>();
                }

                if (!playerZones.Contains(this))
                {
                    // not in this zone, exit out - sometimes OnTriggerExit is called twice in a row
                    return;
                }

                List <Transform> zonePlayers;
                if (!zonesAndPlayers.TryGetValue(this, out zonePlayers))
                {
                    zonesAndPlayers[this] = zonePlayers = new List <Transform>();
                }

                // if entering a new zone, begin transition to the new zone's current weather
                WeatherMakerProfileScript previousProfile = (playerZones.Count == 0 ? null : playerZones[playerZones.Count - 1].currentProfile);
                WeatherMakerProfileScript newProfile      = null;

                // remove zone from the player zone stack
                playerZones.Remove(this);

                // remove player from the zone player list
                zonePlayers.Remove(other.transform);

                float transitionDuration = 0.0f;

                // add the player to the previous weather zone if any
                WeatherMakerWeatherZoneScript newZone = null;
                if (playerZones.Count != 0)
                {
                    newZone = playerZones[playerZones.Count - 1];
                    if (!zonesAndPlayers.TryGetValue(newZone, out zonePlayers))
                    {
                        zonePlayers = new List <Transform>();
                    }
                    zonePlayers.Add(other.transform);

                    // pick a new duration for the transition
                    if (newZone.currentProfile != null)
                    {
                        transitionDuration = newZone.currentProfile.RandomTransitionDuration();
                        newProfile         = newZone.currentProfile;
                    }
                }
                else
                {
                    Debug.LogError("Exited weather zone into no more zones, please add a global weather zone as a catch all zone");
                    return;
                }

                if (WeatherMakerScript.IsLocalPlayer(other.transform))
                {
                    WeatherMakerScript.Instance.LastLocalProfile = newProfile;
                    WeatherMakerScript.Instance.WeatherZoneChanged.Invoke(newZone);
                }

                string connectionId = WeatherMakerScript.Instance.NetworkConnection.GetConnectionId(other.transform);

                // transition to new weather zone
                // if transition from another zone, multiply the transition duration so we get to the new weather zone weather more quickly
                WeatherMakerScript.Instance.RaiseWeatherProfileChanged(previousProfile, newProfile, transitionDuration * (previousProfile == null ? 1.0f : TransitionDurationMultiplier),
                                                                       secondsRemainingHold, false, (connectionId == null ? null : new string[1] {
                    connectionId
                }));
            }
        }
示例#13
0
        private void OnTriggerEnter(Collider other)
        {
            if (SingleProfile == null && ProfileGroup == null)
            {
                return;
            }

            bool isServer = WeatherMakerScript.Instance != null && WeatherMakerScript.Instance.NetworkConnection.IsServer;

            if (isServer && gameObject.activeInHierarchy && enabled && WeatherMakerScript.IsPlayer(other.transform))
            {
                // ensure we have player zones and zone players lists
                List <WeatherMakerWeatherZoneScript> playerZones;
                if (!playersAndZones.TryGetValue(other.transform, out playerZones))
                {
                    playersAndZones[other.transform] = playerZones = new List <WeatherMakerWeatherZoneScript>();
                }

                if (playerZones.Contains(this))
                {
                    // already in the zone, don't re-process, sometimes OnTriggerEnter is called twice in a row
                    return;
                }

                List <Transform> zonePlayers;
                if (!zonesAndPlayers.TryGetValue(this, out zonePlayers))
                {
                    zonesAndPlayers[this] = zonePlayers = new List <Transform>();
                }

                // remove player from their previous zone
                WeatherMakerWeatherZoneScript prevZone = null;
                if (playerZones.Count != 0)
                {
                    // remove player from previous weather zone
                    prevZone = playerZones[playerZones.Count - 1];
                    List <Transform> prevZonePlayers;
                    if (zonesAndPlayers.TryGetValue(prevZone, out prevZonePlayers))
                    {
                        prevZonePlayers.Remove(other.transform);
                    }
                }

                // see if we have a previous zone, if so we have a previous profile to transition from
                WeatherMakerProfileScript previousProfile = (playerZones.Count == 0 ? null : playerZones[playerZones.Count - 1].currentProfile);
                float transitionDuration = (previousProfile == null ? 0.001f : currentProfile.RandomTransitionDuration());

                // add zone to the player zone stack
                playerZones.Add(this);

                // add player to the zone player list
                zonePlayers.Add(other.transform);

                if (WeatherMakerScript.IsLocalPlayer(other.transform))
                {
                    WeatherMakerScript.Instance.LastLocalProfile = currentProfile;
                    if (prevZone != this)
                    {
                        WeatherMakerScript.Instance.WeatherZoneChanged.Invoke(this);
                    }
                }

                // pick a new duration for the transition
                string connectionId = WeatherMakerScript.Instance.NetworkConnection.GetConnectionId(other.transform);

                // transition to new weather zone
                // if transition from another zone, multiply the transition duration so we get to the new weather zone weather more quickly
                WeatherMakerScript.Instance.RaiseWeatherProfileChanged(previousProfile, currentProfile, transitionDuration * (previousProfile == null ? 1.0f : TransitionDurationMultiplier),
                                                                       secondsRemainingHold, false, (connectionId == null ? null : new string[1] {
                    connectionId
                }));
            }
        }