Access Terrain Wind Setting and Wind Zone in Unity3D 3.0.02f

I am trying to access terrain wind settings for bending factors in realtime, however it’s not avalible.

Same goes for the wind turblence script that’s in Unity 3.0, I don’t see a way to access that script either.

How Can I get any access to this?
is no access to these properties in the terrain or terrain data class.

Which shader under terrain would I need to modify,
Do I have to first find the shader manipulating the brushes, then using a script access that shader and then bending it through that script by setting a new variable I create?

So far, WindZone is solved.

Accessing WindZone (keywords):
Class: WindZone
Parameters: windPulseMagnitude, windPulseFrequency, etc.

why have unity guys changed the WindZone class to something else or private, I can’t find the namespace WindZone anymore or access it in script in 3.0.02f-_-', any documentation on it?

WindZone is in the scripting manual (Object > Component > Wind Zone).

Not sure what you mean, I mean I can’t call the WindZone class under script and adjust those WindZone parameters in realtime in 3.0.02f

No there is not such thing as WindZone in the Scripting Manual. Nor is there information anywhere on how/if we can hook up other things to wind zones (I’m guessing a vertex map is used to find which vertices should move and how much?).

Yeah that’s pretty annoying. I think windzones are a good idea, however we need to access to them if we are to make use of them for custom objects. I have some rain which is affected by the wind, including some faux turbulence, however there is no way to link this with the Unity windzones because I can’t access it through scripting. Another annoying thing is that the detail objects on the terrain aren’t affected by windzones… they’re almost unusable for that reason alone.

Wind Zones need to become accessable. not just for the required dynamic environments (which up to a given degree can be compensated for through the terrain wind settings) but also because they are fundamental for anything like a visually appealing explosion on a terrain where a spherical windzone just is a must.

Exactly. It seems impossible to fake it with scripts too as particles from a single emitter don’t have independent velocities. I am racking my brain thinking how to make a snow “flurry”… perhaps I have to use multiple emitters. I really wish that objects had a physics property to them which enabled them to be affected by windzones.

Yes. The windzone should be public.

Hint: Wind can be controlled using WindZone’s rotation: it looks forward ― full wind, it looks down ― zero wind. All other WindZone’s features can be easily simulated using this technique.

Hmm, I as well need access to the wind settings, as they play a vital part in my weather simulations.
Im going to do some digging and see if I can find anyway to access the windzone via reflection.

After a fair bit of work digging around with the reflection system, I created a class that gives you control over a WindZone, and a child class that gives you a clean script to program in as well as example code of usage.
Be sure to attach the “WindZoneController.cs” script to the same game object that has a windzone component, and remember to call base.Init() in the Start() function

Note: I did not link against the Mode setting

ScriptableWindzoneInterface.cs

using UnityEngine;
using System.Collections;
using System.Reflection ;

// Provides a scriptable interface to a windzone
/* Change Log
 * 05/25/11	Created by Nividica
 * 			As Unity provides no way to access a windzone via
 * 				script, I am digging around in the reflections
 * 				to pull out its memeber information and write
 * 				getter and setter methods.
 * 			Finished writing the get/set methods for everything
 * 				except the Mode.
 */
public class ScriptableWindzoneInterface : MonoBehaviour {	
	// Private vars ===================================
	
	// The windzone component
	private Component m_WindzoneComponent ;
	
	// The system qualified type of the windzone
	private System.Type m_WindzoneType ;
	
	// Used to pass an argument to WindZone setter functions
	object[] m_WindZoneArgs = new object[1] ;
	
	// Public properties ==============================
	
	// `radius`
	public float Radius {
		get
		{
			// Return the value of `radius`
			return (float)GetWindZoneValue( "get_radius" ) ;
		}
		set
		{
			// Set the argument
			m_WindZoneArgs[0] = value ;
			
			// Set the value of `windMain`
			SetWindZoneValue( "set_radius" , m_WindZoneArgs ) ;
		}
	}
	
	// `windMain`
	public float WindMain {
		get
		{
			// Return the value of `windMain`
			return (float)GetWindZoneValue( "get_windMain" ) ;
		}
		set
		{
			// Set the argument
			m_WindZoneArgs[0] = value ;
			
			// Set the value of `windMain`
			SetWindZoneValue( "set_windMain" , m_WindZoneArgs ) ;
		}
	}
	
	// `windTurbulence`
	public float WindTurbulence {
		get
		{
			// Return the value of `windTurbulence`
			return (float)GetWindZoneValue( "get_windTurbulence" ) ;
		}
		set
		{
			// Set the argument
			m_WindZoneArgs[0] = value ;
			
			// Set the value of `windTurbulence`
			SetWindZoneValue( "set_windTurbulence" , m_WindZoneArgs ) ;
		}
	}
	
	// `windPulseMagnitude`
	public float WindPulseMagnitude {
		get
		{
			// Return the value of `windPulseMagnitude`
			return (float)GetWindZoneValue( "get_windPulseMagnitude" ) ;
		}
		set
		{
			// Set the argument
			m_WindZoneArgs[0] = value ;
			
			// Set the value of `windPulseMagnitude`
			SetWindZoneValue( "set_windPulseMagnitude" , m_WindZoneArgs ) ;
		}
	}
	
	// `windPulseFrequency`
	public float WindPulseFrequency {
		get
		{
			// Return the value of `windPulseFrequency`
			return (float)GetWindZoneValue( "get_windPulseFrequency" ) ;
		}
		set
		{
			// Set the argument
			m_WindZoneArgs[0] = value ;
			
			// Set the value of `windPulseMagnitude`
			SetWindZoneValue( "set_windPulseFrequency" , m_WindZoneArgs ) ;
		}
	}
	
	// Public functions ===============================
	
	// Find and link against the windzone
	public void Init () {
		
		// Get the windzone of this game object
		m_WindzoneComponent = GetComponent("WindZone");
		
		// Ensure there was a windzone to link to
		if ( m_WindzoneComponent == null ) {
			// Log the error
			Debug.LogError( "Could not find a wind zone to link to: " + this ) ;
			
			// Disable this script for the remainder of the run
			this.enabled = false;
			
			// Stop here
			return ;
		}
		
		// Get the system qualified type
		m_WindzoneType = m_WindzoneComponent.GetType() ;
		
	}
	
	// Private functions =============================
	
	// Set a WindZone property value
	void SetWindZoneValue ( string MemberName , object[] args ){
		// Call the setter
		m_WindzoneType.InvokeMember(
		                            MemberName ,
		                            BindingFlags.InvokeMethod | BindingFlags.Instance ,
		                            null ,
		                            m_WindzoneComponent ,
		                            args ) ;
	}
	
	// Get a WindZone property value
	object GetWindZoneValue ( string MemberName ){
		// Call the getter
		return m_WindzoneType.InvokeMember(
		                                   MemberName ,
		                                   BindingFlags.InvokeMethod | BindingFlags.Instance ,
		                                   null ,
		                                   m_WindzoneComponent ,
		                                   null ) ;
	}
}

WindZoneController.cs

using UnityEngine;
using System.Collections;

// Allows Control Over WindZone Component

// Note: The WindZone  This Script Must Be Attached To The Same Game Object

public class WindzoneController : ScriptableWindzoneInterface {

	// Use this for initialization
	void Start () {
		// Tell the ScriptableWindzoneInterface to initialize
		base.Init() ;
		
		// Example: Log the current settings
		Debug.Log( "The Starting Settings Of The Windzone Are: Main=" + WindMain
		          + ", Turbulence=" + WindTurbulence
		          + ", Pulse Magnitude=" + WindPulseMagnitude
		          + ", Pulse Frequency=" + WindPulseFrequency ) ;
	}
	
	// Update is called once per frame
	void Update () {
		
		// Example: Setting each of the values
		WindMain = Mathf.PingPong( ( Time.time / 2.0F ) , 1.0F ) ;
		WindTurbulence = WindMain ;
		WindPulseMagnitude = WindMain ;
		WindPulseFrequency = WindMain ;
		Radius = WindMain;
	}
}

If you have any questions or problems let me know :smile:

I would preplan accordingly if you use this “hack”.
Its common for Unity that UT if they decide to not allow you on a function for the time or generally will make the class protected sealed cutting you out which basically prevents you from switching to any new version of Unity at all then.
A lot of people had to learn this lesson the hard way when UT made many functions and classes protected or even private as well as sealed in 3.0 vs 2.6

So if you use this you need to preplan for the situation where you might be forced to remain on the unity version you are using at the time, no 3.4 and newer.

If you want long term savety, you might want to consider implementing a system that completely replaces the wind system and dynamically feeds a vertex shader for example, at least until WindZones become officially exposed

Its true this a total hack-meat solution to the problem, and im genuinely hoping that in a future release the windzone component will indeed be scriptable. For now, and mostly for me, it will have to work. The weather system im working on already had the ability to determine the speed and direction of the wind, but no way to effect the tree’s, which adds that touch of polish im looking for.
(Should have mentioned this before) But if anyone does use it, please be advised this is not guaranteed to work with any future versions of unity. Just found a solution to my problem and decided to share.
Thanks dreamora for pointing out the forward compatibility issues.

No prob and sorry if above came over in any way as harsh or alike. Edited above posting to reflect better what I wanted to imply and less what it potentially “transfered”

Its definitely not meant like it.
Wanted to thank you for sharing this “dirty” solution cause for those working on something thats meant to happen soon, its definitely going to work fine for the time being and for larger and longer projects you normally consider twice if you upgrade the engine midway through the project as bugs and generally regression can have nightmare side effects.

Hey Guys,

I have a different workaround to this problem that worked for me when I needed to make some explosions on terrains. It’s not as flexible as Nividica’s script but at the same time it shouldn’t break with new releases.

So, what I did was:

  • Attached animation component to the object with the windzone;
  • Disabled the wz and set the first frame to start with 0 values across all wz settings;
  • Played with the time line and various settings to get the desired effect;
  • Set Enabled to 1 in the frame where I wanted the effect to start;
  • Set Enabled to 0 in the last frame to disable the wz;

Finally I triggered the animation to start playing in a collision event handler in one of my other scripts.

At first I didn’t think this would work but the end result was far better than what I expected. There is tons of funky stuff you can do in the animation editor to make some very very nice explosion shock waves and such.

Hope someone finds this useful.

Another annoying thing is that the absence of WindZone as a type makes it impossible to work in UnityScript with #pragma strict active. With #pragma strict not turned on, it is possible, however, to do

var wz = GetComponent("WindZone");

which means the WindZone component is accessible, though not through the type system.

I very much doubt that the Unity developers purposely have decided not to expose WindZones, especially since there are recommendations in the manual on how to make trees respond to explosions by animating WindZone attributes in real time. However, this cannot be done in any way other than in UnityScript using dynamic typing. Looks like an oversight which ought to be corrected ASAP.

I’m hoping WindZone gets exposed to script officially too.

I think this is one of the things they’ve left behind. I was thinking the windzone should affect grass, particles, and cloth too.

This doesn’t work in a web build. Perhaps System.Reflection is not included in the web build subset of the mono runtime?