Example #1
0
    // Instantiate a preset by name reference
    public static PlaygroundParticlesC InstantiateEditorPreset(Object presetObject)
    {
        GameObject           presetGo        = (GameObject)Instantiate(presetObject);
        PlaygroundParticlesC presetParticles = presetGo.GetComponent <PlaygroundParticlesC>();

        if (presetParticles != null)
        {
            if (PlaygroundC.reference == null)
            {
                PlaygroundC.ResourceInstantiate("Playground Manager");
            }
            if (PlaygroundC.reference)
            {
                if (PlaygroundC.reference.autoGroup && presetParticles.particleSystemTransform.parent == null)
                {
                    presetParticles.particleSystemTransform.parent = PlaygroundC.referenceTransform;
                }
                PlaygroundC.particlesQuantity++;
                //PlaygroundC.reference.particleSystems.Add(presetParticles);
                presetParticles.particleSystemId = PlaygroundC.particlesQuantity;
            }
            presetGo.name = presetObject.name;
            return(presetParticles);
        }
        else
        {
            return(null);
        }
    }
 /// <summary>
 /// Scrub to specified time in particle recording. This will linearly interpolate between the closest recorded frames of the passed in time (normalized between 0f - 1f).
 /// </summary>
 /// <param name="normalizedTime">The normalized time (0f to 1f).</param>
 public void Scrub(float normalizedTime)
 {
     if (!HasRecordedFrames())
     {
         return;
     }
     if (_isRecording)
     {
         StopRecording();
     }
     if (!_inPlayback)
     {
         StartPlayback();
     }
     if (multithreading)
     {
         PlaygroundC.RunAsync(() => {
             lock (locker)
             {
                 ScrubInternal(normalizedTime);
             }
         });
     }
     else
     {
         ScrubInternal(normalizedTime);
     }
 }
	public static void Initialize (PlaygroundC targetRef) {
		playgroundScriptReference = targetRef;
		PlaygroundC.reference = targetRef;
		if (playgroundScriptReference==null) return;
		playground = new SerializedObject(playgroundScriptReference);
		particleSystems = playground.FindProperty("particleSystems");
		manipulators = playground.FindProperty("manipulators");
		calculate = playground.FindProperty("calculate");
		pixelFilterMode = playground.FindProperty("pixelFilterMode");
		autoGroup = playground.FindProperty("autoGroup");
		buildZeroAlphaPixels = playground.FindProperty("buildZeroAlphaPixels");
		drawGizmos = playground.FindProperty("drawGizmos");
		drawSourcePositions = playground.FindProperty("drawSourcePositions");
		drawWireframe = playground.FindProperty("drawWireframe");
		drawSplinePreview = playground.FindProperty("drawSplinePreview");
		paintToolbox = playground.FindProperty("paintToolbox");
		showShuriken = playground.FindProperty("showShuriken");
		showSnapshots = playground.FindProperty("showSnapshotsInHierarchy");
		threads = playground.FindProperty("threadMethod");
		threadsTurbulence = playground.FindProperty("turbulenceThreadMethod");
		threadsSkinned = playground.FindProperty("skinnedMeshThreadMethod");
		maxThreads = playground.FindProperty("maxThreads");
		
		playgroundSettings = PlaygroundSettingsC.GetReference();
		playgroundLanguage = PlaygroundSettingsC.GetLanguage();
	}
        /// <summary>
        /// Adds the required particle events to track particles.
        /// </summary>
        public void AddRequiredParticleEvents()
        {
            if (playgroundSystem != null)
            {
                // Hookup events
                birthEvent = GetEventFromType(EVENTTYPEC.Birth);
                if (birthEvent == null)
                {
                    birthEvent = PlaygroundC.CreateEvent(playgroundSystem);
                    birthEvent.broadcastType = EVENTBROADCASTC.EventListeners;
                    birthEvent.eventType     = EVENTTYPEC.Birth;
                }
                birthEvent.particleEvent += OnParticleBirthEvent;

                deathEvent = GetEventFromType(EVENTTYPEC.Death);
                if (deathEvent == null)
                {
                    deathEvent = PlaygroundC.CreateEvent(playgroundSystem);
                    deathEvent.broadcastType = EVENTBROADCASTC.EventListeners;
                    deathEvent.eventType     = EVENTTYPEC.Death;
                }
                deathEvent.particleEvent += OnParticleDeathEvent;

                collisionEvent = GetEventFromType(EVENTTYPEC.Collision);
                if (collisionEvent == null)
                {
                    collisionEvent = PlaygroundC.CreateEvent(playgroundSystem);
                    collisionEvent.broadcastType = EVENTBROADCASTC.EventListeners;
                    collisionEvent.eventType     = EVENTTYPEC.Collision;
                }
                collisionEvent.particleEvent += OnParticleCollisionEvent;
            }
        }
    void Start()
    {
        // Get the event from your particle system
        playgroundEvent = PlaygroundC.GetEvent(0, particles);

        // Subscribe to the event
        AddEventListener();

        // Cache components of this GameObject (helps performance on low-end devices)
        thisTransform = transform;
        thisCollider  = collider;
        thisRenderer  = renderer;

        // Create materials to show if the event listener is active or not
        if (activeMaterial == null)
        {
            activeMaterial       = new Material(Shader.Find("Diffuse"));
            activeMaterial.color = Color.white;
        }
        if (inactiveMaterial == null)
        {
            inactiveMaterial       = new Material(Shader.Find("Diffuse"));
            inactiveMaterial.color = Color.black;
        }

        thisRenderer.sharedMaterial = activeMaterial;
    }
    void Update()
    {
        // Send a Raycast from particle system's source transform forward
        RaycastHit hit;

        if (Physics.Raycast(particles.sourceTransform.position, particles.sourceTransform.forward, out hit, laserMaxDistance, collisionLayer))
        {
            // Set overflow offset z to hit distance (divide by particle count which by default is 1000)
            particles.overflowOffset.z = Vector3.Distance(particles.sourceTransform.position, hit.point) / (1 + particles.particleCount);
        }
        else
        {
            // Render laser to laserMaxDistance on clear sight
            particles.overflowOffset.z = laserMaxDistance / (1 + particles.particleCount);
        }

        // Update the amount of particles if particleCount changes
        if (particleCount != previousParticleCount)
        {
            PlaygroundC.SetParticleCount(particles, particleCount);
            previousParticleCount = particleCount;
        }

        // Update the lifetimeColor if laserColor changes
        if (laserColor != particles.lifetimeColor)
        {
            particles.lifetimeColor = laserColor;
        }
    }
    void Start()
    {
        // Get the first event
        playgroundEvent = PlaygroundC.GetEvent(0, particles);

        // Add listener
        AddListener();
    }
Example #8
0
    ManipulatorObjectC manipulator;                             // Cached manipulator

    void Start()
    {
        // Get the manipulator from the particle system
        manipulator = PlaygroundC.GetManipulator(manipulatorNumber, particles);

        // Set all protected particles within specified ranges from protectedParticles
        SetProtectedParticles();
    }
    public void CreatePresetObject(int i)
    {
        PlaygroundParticlesC instantiatedPreset = PlaygroundC.InstantiatePreset(presetObjects[i].presetObject.name);

        if (instantiatedPreset)
        {
            Selection.activeGameObject = instantiatedPreset.particleSystemGameObject;
        }
    }
Example #10
0
        void Start()
        {
            if (referenceObject == null || particles == null)
            {
                return;
            }

            // Create and setup the birth event
            birthEvent = PlaygroundC.CreateEvent(particles);
            birthEvent.broadcastType = EVENTBROADCASTC.EventListeners;
            birthEvent.eventType     = EVENTTYPEC.Birth;

            // Create and setup the death event
            deathEvent = PlaygroundC.CreateEvent(particles);
            deathEvent.broadcastType = EVENTBROADCASTC.EventListeners;
            deathEvent.eventType     = EVENTTYPEC.Death;

            // Hook up the event listeners to the delegates
            birthEvent.particleEvent += OnParticleDidBirth;
            deathEvent.particleEvent += OnParticleDidDie;

            // Create a parent for all followers (for Hierarchy convenience)
            followerParent        = new GameObject("Followers").transform;
            followerParent.parent = transform;

            // Get the trail renderer (if available) and its time
            referenceTrailRenderer = referenceObject.GetComponent <TrailRenderer>();
            if (referenceTrailRenderer != null)
            {
                trailTime = referenceTrailRenderer.time;
            }

            // Set an extra amount of followers if required (a trail's time will exceed a particle's)
            int extra = followerLifetime <= 0?
                        Mathf.CeilToInt(Mathf.Abs(particles.lifetime - trailTime) + (trailTime - particles.lifetime)) + 2 :
                        Mathf.CeilToInt(Mathf.Abs(particles.lifetime - followerLifetime) + (followerLifetime - particles.lifetime)) + 2;

            if (particles.lifetime <= 1f)
            {
                extra++;
            }

            // Create the follower cache (this will be iterated through and reused whenever a particle rebirths)
            referenceObjectsCache = new PlaygroundFollower[cacheSize > 0? cacheSize : particles.particleCount + Mathf.CeilToInt(particles.particleCount * extra)];
            for (int i = 0; i < referenceObjectsCache.Length; i++)
            {
                GameObject clone = (GameObject)Instantiate(referenceObject);
                referenceObjectsCache[i] = new PlaygroundFollower(clone.transform, clone, clone.GetComponent <TrailRenderer>(), 0, 0);
                referenceObjectsCache[i].transform.parent = followerParent;
                if (referenceObjectsCache[i].trailRenderer != null)
                {
                    referenceObjectsCache[i].trailRenderer.time = 0;
                }
                referenceObjectsCache[i].gameObject.SetActive(false);
            }
        }
Example #11
0
//	private float m_Multiplier;

    public void Awake()
    {
        m_Sprite               = transform.GetComponentInChildren <SpriteRenderer>();
        m_LineRenderer         = transform.GetComponentInChildren <LineRenderer>();
        m_Particles            = transform.GetComponentInChildren <PlaygroundParticlesC>();
        m_ManipulatorTransform = m_Particles.transform.FindChild("Manipulator");

        m_ManipulatorObstruction = PlaygroundC.GetManipulator(0, m_Particles);
        m_ManipulatorColor       = PlaygroundC.GetManipulator(1, m_Particles);
    }
    void Start()
    {
        // Cache the particle system (make sure you have set enough particle count)
        particles = GetComponent <PlaygroundParticlesC>();

        // Create a new skinned world object
        swo = PlaygroundC.SkinnedWorldObject(skinnedMeshTransform);

        // Start emission routine
        StartCoroutine(EmitOverAllVertices());
    }
    // Use this for initialization
    void Start()
    {
        // Events run on a second thread, only use thread-safe methods within the Event Delegate (no GetTransform)
        thisTransform = transform;

        // Get the event from your particle system
        playgroundEvent = PlaygroundC.GetEvent(0, particles);

        // Subscribe to the event
        AddEventListener();
    }
    ManipulatorObjectC manipulator;                     // Cached version of maipulator

    void Start()
    {
        // Set Cache
        if (localManipulator)
        {
            manipulator = PlaygroundC.GetManipulator(manipulatorNumber, particles);
        }
        else
        {
            manipulator = PlaygroundC.GetManipulator(manipulatorNumber);
        }
    }
    List <WorldObject> cachedWorldObjects;                                      // List of cached World Objects

    void Start()
    {
        // Cache the World Objects
        cachedWorldObjects = new List <WorldObject>();
        foreach (Transform wo in worldObjects)
        {
            cachedWorldObjects.Add(PlaygroundC.WorldObject(wo));
        }

        // Assign a World Object by list number (example)
        SwitchWorldObject(0);
    }
Example #16
0
 // Update is called once per frame
 void Update()
 {
     if (Input.GetMouseButtonDown(0))
     {
         Ray        ray = Camera.main.ScreenPointToRay(Input.mousePosition);
         RaycastHit hit;
         if (Physics.Raycast(ray, out hit, 1000f))
         {
             PlaygroundC.Paint(particles, hit.point, hit.normal, hit.transform, color);
         }
     }
 }
Example #17
0
 /// <summary>
 /// Loads frames from the Recorder Data asynchronously.
 /// </summary>
 public void LoadAsync()
 {
     if (recorderData == null)
     {
         Debug.Log("No Playground Recorder Data to load from!", gameObject);
         return;
     }
     PlaygroundC.RunAsync(() => {
         recordedFrames       = recorderData.CloneAsRecordedFrames();
         _hasEditedRecordData = true;
     });
 }
    void Start()
    {
        if (particles == null)
        {
            return;
        }

        // Get the first event
        playgroundEvent = PlaygroundC.GetEvent(0, particles);

        // Add listener
        AddListener();
    }
 public void SerializeAsync(List <RecordedFrame> recordedFrames)
 {
     version = PlaygroundC.version;
     PlaygroundC.RunAsync(() => {
         serializedFrames = null;
         serializedFrames = new SerializedFrame[recordedFrames.Count];
         for (int i = 0; i < serializedFrames.Length; i++)
         {
             serializedFrames[i] = recordedFrames[i].CloneAsSerializedFrame();
         }
     });
             #if UNITY_EDITOR
     UnityEditor.EditorUtility.SetDirty(this);
             #endif
 }
    void Awake()
    {
        // Create and setup the birth event
        birthEvent = PlaygroundC.CreateEvent(particles);
        birthEvent.broadcastType = EVENTBROADCASTC.EventListeners;
        birthEvent.eventType     = EVENTTYPEC.Birth;

        // Create and setup the death event
        deathEvent = PlaygroundC.CreateEvent(particles);
        deathEvent.broadcastType = EVENTBROADCASTC.EventListeners;
        deathEvent.eventType     = EVENTTYPEC.Death;

        // Hook up the event listeners to the delegates
        birthEvent.particleEvent += OnParticleDidBirth;
        deathEvent.particleEvent += OnParticleDidDie;

        // Setup the followers
        followerParent         = new GameObject("Followers").transform;
        followerParent.parent  = transform;
        referenceTrailRenderer = referenceObject.GetComponent <TrailRenderer>();
        if (referenceTrailRenderer != null)
        {
            trailTime = referenceTrailRenderer.time;
        }

        int extra = followerLifetime <= 0?
                    Mathf.CeilToInt(Mathf.Abs(particles.lifetime - trailTime) + (trailTime - particles.lifetime)) + 2 :
                    Mathf.CeilToInt(Mathf.Abs(particles.lifetime - followerLifetime) + (followerLifetime - particles.lifetime)) + 2;

        if (particles.lifetime <= 1f)
        {
            extra++;
        }
        referenceObjectsCache = new PlaygroundFollower[cacheSize > 0? cacheSize : particles.particleCount + Mathf.CeilToInt(particles.particleCount * extra)];
        for (int i = 0; i < referenceObjectsCache.Length; i++)
        {
            GameObject clone = (GameObject)Instantiate(referenceObject);
            referenceObjectsCache[i] = new PlaygroundFollower(clone.transform, clone, clone.GetComponent <TrailRenderer>(), 0, 0);
            referenceObjectsCache[i].transform.parent = followerParent;
            if (referenceObjectsCache[i].trailRenderer != null)
            {
                referenceObjectsCache[i].trailRenderer.time = 0;
            }
            referenceObjectsCache[i].gameObject.SetActive(false);
        }
    }
Example #21
0
    void OnEnable()
    {
        if (_manipulator == null)
        {
            _manipulator = PlaygroundC.GetManipulator(manipulatorIndex, particles);
        }

        // Sanity check
        _targetPosition = target.position;
        _manipulator.particleEventEnter -= Teleport;

        // Enable the Manipulator
        _manipulator.enabled = true;

        // Assign to the event delegate of when a particle is entering the Manipulator
        _manipulator.particleEventEnter += Teleport;
    }
Example #22
0
    public virtual void Awake()
    {
        m_PigmentCircle        = transform.FindChild("Pigment Circle").GetComponent <SpriteRenderer>();
        m_PigmentRing          = transform.FindChild("Pigment Ring").GetComponent <SpriteRenderer>();
        m_CromaticRing         = transform.FindChild("Cromatic Ring").GetComponent <SpriteRenderer>();
        m_Raycast              = transform.FindChild("Raycast");
        m_Particles            = m_Raycast.GetComponentInChildren <PlaygroundParticlesC>();
        m_ManipulatorTransform = m_Particles.transform.FindChild("Manipulator");
        m_LineRenderer         = m_Raycast.GetComponentInChildren <LineRenderer>();
        m_Output = m_Raycast.GetComponentInChildren <SpriteRenderer>();

        m_ManipulatorObstruction = PlaygroundC.GetManipulator(0, m_Particles);
        m_ManipulatorColor       = PlaygroundC.GetManipulator(1, m_Particles);

        m_ParticleRing = GetComponentInChildren <ParticleSystem>();
        m_SoundSource  = GetComponent <AudioSource>();
    }
Example #23
0
    // User created preset
    public void CreatePresetObject(int i)
    {
        PlaygroundParticlesC instantiatedPreset;

        if (!AssetDatabase.GetAssetPath(presetObjects[i].presetObject).Contains("Resources/"))
        {
            instantiatedPreset = InstantiateEditorPreset(presetObjects[i].presetObject);
        }
        else
        {
            instantiatedPreset = PlaygroundC.InstantiatePreset(presetObjects[i].presetObject.name);
        }
        if (instantiatedPreset != null)
        {
            instantiatedPreset.EditorYieldSelect();
        }
    }
Example #24
0
    void AddRemoveInRange()
    {
        RemoveOutOfRange();

        Collider[] inRangeObjects = Physics.OverlapSphere(originTransform.position, radius, layer);
        for (int i = 0; i < inRangeObjects.Length; i++)
        {
            if (!ManipulatorHasTransform(inRangeObjects[i].transform))
            {
                ManipulatorObjectC newManipulator = PlaygroundC.ManipulatorObject(inRangeObjects[i].transform, particles);

                // Setup the added manipulator here
                newManipulator.type     = MANIPULATORTYPEC.Repellent;
                newManipulator.size     = 5f;
                newManipulator.strength = 3f;
            }
        }
    }
	public static void Initialize (PlaygroundC targetRef) {
		if (playgroundScriptReference==null) return;
		playgroundScriptReference = targetRef;
		playground = new SerializedObject(playgroundScriptReference);
		particleSystems = playground.FindProperty("particleSystems");
		manipulators = playground.FindProperty("manipulators");
		calculate = playground.FindProperty("calculate");
		pixelFilterMode = playground.FindProperty("pixelFilterMode");
		garbageCollectOnResize = playground.FindProperty("garbageCollectOnResize");
		autoGroup = playground.FindProperty("autoGroup");
		buildZeroAlphaPixels = playground.FindProperty("buildZeroAlphaPixels");
		drawGizmos = playground.FindProperty("drawGizmos");
		paintToolbox = playground.FindProperty("paintToolbox");
		showShuriken = playground.FindProperty("showShuriken");
		
		manipulatorListFoldout = new List<bool>();
		manipulatorListFoldout.AddRange(new bool[playgroundScriptReference.manipulators.Count]);
	}
Example #26
0
    void Start()
    {
        // Mouse cursor not wanted
#if UNITY_4_3 || UNITY_4_5 || UNITY_4_6 || UNITY_5_0 || UNITY_5_1 || UNITY_5_2
        Screen.showCursor = false;
#else
        Cursor.visible = false;
#endif


        // Make sure particle systems are inactive
        foreach (PlaygroundFxCycleItem p in particleFx)
        {
            p.particles.emit = false;
            p.particles.particleSystemGameObject.SetActive(false);
        }

        // Set initial skybox values
        skyboxColorOnLoad = RenderSettings.skybox.GetColor("_Tint");
        RenderSettings.skybox.SetColor("_Tint", Color.black);

        // Cache up!
        cam                          = Camera.main;
        camTransform                 = cam.transform;
        camFov                       = cam.fieldOfView;
        repellentManipulator         = PlaygroundC.GetManipulator(0);
        repellentManipulator.enabled = false;
        particleBlastClips           = particleBlastSound.GetComponent <SoundFxArray>().sounds;

        // Set initial camera values
        camPivot.position    = camSpline.GetPoint(0f);
        camRotation.rotation = Quaternion.LookRotation(-camRotation.position);

        // Run the intro
        StartCoroutine(FadeIn());

        // Get started right away if no user interaction is required
        if (isSelfRunning)
        {
            pressSpaceText.SetActive(false);
            StartCoroutine(Selfrunning());
        }
    }
Example #27
0
    int pickups = 0;                            // As an example count the amount of pickups made

    void Start()
    {
        // Cache the Local Manipulator
        manipulator = PlaygroundC.GetManipulator(manipulatorIndex, particles);

        // Note that you can set the Manipulator to Type: None in case you have no intention to also modify the particles behavior
        // manipulator.type = MANIPULATORTYPEC.None;

        // Make sure we're tracking particles
        manipulator.trackParticles = true;

        // Make sure we're sending enter events
        manipulator.sendEventEnter = true;

        // Make sure we're using the fastest tracking method
        manipulator.trackingMethod = TrackingMethod.ManipulatorId;

        // Assign your function to the event delegate
        manipulator.particleEventEnter += OnManipulatorEnter;
    }
Example #28
0
    public void Awake()
    {
        m_RaycastLeft  = transform.FindChild("RaycastLeft");
        m_RaycastRight = transform.FindChild("RaycastRight");

        m_LineRendererLeft  = m_RaycastLeft.GetComponentInChildren <LineRenderer>();
        m_LineRendererRight = m_RaycastRight.GetComponentInChildren <LineRenderer>();

        m_ParticleLeft  = m_RaycastLeft.GetComponentInChildren <PlaygroundParticlesC>();
        m_ParticleRight = m_RaycastRight.GetComponentInChildren <PlaygroundParticlesC>();

        m_ManipulatorLeft  = m_ParticleLeft.transform.FindChild("Manipulator");
        m_ManipulatorRight = m_ParticleRight.transform.FindChild("Manipulator");

        m_ManipulatorObstuctionLeft  = PlaygroundC.GetManipulator(0, m_ParticleLeft);
        m_ManipulatorObstuctionRight = PlaygroundC.GetManipulator(0, m_ParticleRight);

        m_ManipulatorColorLeft  = PlaygroundC.GetManipulator(1, m_ParticleLeft);
        m_ManipulatorColorRight = PlaygroundC.GetManipulator(1, m_ParticleRight);
    }
Example #29
0
    public void Awake()
    {
        switch (type)
        {
        case PipeType.Entry:
//			m_Particles = GetComponentInChildren<PlaygroundParticlesC>();
            theSprite.color = new Color(0, 0, 0, 0);
            break;

        case PipeType.Exit:
            m_Raycast              = transform.FindChild("Raycast");
            m_LineRenderer         = m_Raycast.GetComponentInChildren <LineRenderer>();
            m_Particles            = GetComponentInChildren <PlaygroundParticlesC>();
            m_ManipulatorTransform = m_Particles.transform.FindChild("Manipulator");

            m_ManipulatorObstruction = PlaygroundC.GetManipulator(0, m_Particles);
            m_ManipulatorColor       = PlaygroundC.GetManipulator(1, m_Particles);
            break;
        }
    }
    List <Vector3> queuedSystems = new List <Vector3>();                                // The queued list of particle system positions to enable on main-thread

    void Start()
    {
        // Get the event
        PlaygroundEventC mainParticleEvent = PlaygroundC.GetEvent(0, mainParticles);

        // Make sure the event delegate is set to target event listeners
        mainParticleEvent.broadcastType = EVENTBROADCASTC.EventListeners;

        // Hook up to the event delegate
        mainParticleEvent.particleEvent += OnParticleEvent;

        // Cache the particle systems in the pool
        cachedParticles = new List <PlaygroundParticlesC>();
        for (int i = 0; i < quantity; i++)
        {
            GameObject go = (GameObject)Instantiate((Object)particleSystemPoolPrefab);
            cachedParticles.Add(go.GetComponent <PlaygroundParticlesC>());
            cachedParticles[i].particleSystemGameObject.SetActive(false);
        }
    }
Example #31
0
 /// <summary>
 /// Sets the particle system's live particles at normalized time of the recorded frames. If multithreading is enabled this operation will run asynchronously.
 /// </summary>
 public void SetParticleSystemAsRecording(float normalizedTime)
 {
     if (playgroundSystem == null || _playbackParticles == null)
     {
         return;
     }
     if (multithreading)
     {
         PlaygroundC.RunAsync(() => {
             lock (locker)
             {
                 SetParticleSystemAsRecordingInternal(normalizedTime);
             }
         });
     }
     else
     {
         SetParticleSystemAsRecordingInternal(normalizedTime);
     }
 }
    int highestPop;                                                     // Keep track of highest pop

    void Start()
    {
        // Cache the manipulator of bubbleParticles (at list position 0)
        manipulator = PlaygroundC.GetManipulator(0, bubbleParticles);

        // Cache the manipulator transform, this looks a bit awkward at first, however the transform of a
        // manipulator is a thread-safe wrapper class which has a variable containing the Transform component.
        // In this example scene manipulatorTransform = transform; is the same.
        manipulatorTransform = manipulator.transform.transform;

        // Hook up functions to the Event Delegates on the manipulator
        manipulator.particleEventEnter     += OnManipulatorEnter;
        manipulator.particleEventExit      += OnManipulatorExit;
        manipulator.particleEventBirth     += OnManipulatorBirth;
        manipulator.particleEventDeath     += OnManipulatorDeath;
        manipulator.particleEventCollision += OnManipulatorCollision;

        mainCamera   = Camera.main;
        popTextColor = popText.color;
        InvokeRepeating("UpdateGUI", 0, guiUpdateTime);
    }
	//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// MonoBehaviours
	//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	
	// OnEnable is called in both Edit- and Play Mode
	// Initializes all particle systems
	void OnEnable () {

		// Cache the Playground reference
		reference = this;
		referenceTransform = transform;
		referenceGameObject = gameObject;

		// Initialize
		StartCoroutine(InitializePlayground());
	}
	void OnEnable () {

		lastActiveTool = Tools.current;
		isEditingInHierarchy = Selection.activeTransform!=null;

		// Load settings
		playgroundSettings = PlaygroundSettingsC.GetReference();
		
		// Load language
		playgroundLanguage = PlaygroundSettingsC.GetLanguage();
		
		// Playground Particles
		playgroundParticlesScriptReference = target as PlaygroundParticlesC;
		if (playgroundParticlesScriptReference==null) return;
		playgroundParticles = new SerializedObject(playgroundParticlesScriptReference);
		
		shurikenRenderer = playgroundParticlesScriptReference.particleSystemGameObject.GetComponent<ParticleSystem>().GetComponent<Renderer>() as ParticleSystemRenderer;

		// Sorting layers
		Type internalEditorUtilityType = typeof(InternalEditorUtility);
		PropertyInfo sortingLayersProperty = internalEditorUtilityType.GetProperty("sortingLayerNames", BindingFlags.Static | BindingFlags.NonPublic);
		rendererSortingLayers = (string[])sortingLayersProperty.GetValue(null, new object[0]);
		for (int i = 0; i<rendererSortingLayers.Length; i++) {
			if (shurikenRenderer.sortingLayerName == rendererSortingLayers[i])
				selectedSortingLayer = i;
		}

		// UV Module (Texture Sheet Animation)
		shuriken = new SerializedObject(playgroundParticlesScriptReference.shurikenParticleSystem);
		uvModule = shuriken.FindProperty("UVModule");
		uvModule_enabled = uvModule.FindPropertyRelative("enabled");
		uvModule_frameOverTime_scalar = uvModule.FindPropertyRelative("frameOverTime.scalar");
		uvModule_frameOverTime_minCurve = uvModule.FindPropertyRelative("frameOverTime.minCurve");
		uvModule_frameOverTime_maxCurve = uvModule.FindPropertyRelative("frameOverTime.maxCurve");
		uvModule_frameOverTime_minMaxState = uvModule.FindPropertyRelative("frameOverTime.minMaxState");
		uvModule_tilesX = uvModule.FindPropertyRelative("tilesX");
		uvModule_tilesY = uvModule.FindPropertyRelative("tilesY");
		uvModule_animationType = uvModule.FindPropertyRelative("animationType");
		uvModule_rowIndex = uvModule.FindPropertyRelative("rowIndex");
		uvModule_cycles = uvModule.FindPropertyRelative("cycles");
		uvModule_randomRow = uvModule.FindPropertyRelative("randomRow");
		uv_animationType = (AnimationType)uvModule_animationType.intValue;
		uv_minMaxState = (MinMaxState)uvModule_frameOverTime_minMaxState.intValue;


		shurikenRendererSO = new SerializedObject(shurikenRenderer);
		sortingMode = shurikenRendererSO.FindProperty("m_SortMode");
		sortingFudge = shurikenRendererSO.FindProperty("m_SortingFudge");
		sortMode = (SortMode)sortingMode.intValue;

		manipulators = playgroundParticles.FindProperty("manipulators");
		events = playgroundParticles.FindProperty("events");
		snapshots = playgroundParticles.FindProperty("snapshots");
		source = playgroundParticles.FindProperty("source");
		sorting = playgroundParticles.FindProperty("sorting");
		lifetimeSorting = playgroundParticles.FindProperty("lifetimeSorting");
		activeState = playgroundParticles.FindProperty("activeState");
		particleCount = playgroundParticles.FindProperty("particleCount");
		emissionRate = playgroundParticles.FindProperty("emissionRate");
		updateRate = playgroundParticles.FindProperty("updateRate");
		emit = playgroundParticles.FindProperty("emit");
		loop = playgroundParticles.FindProperty("loop");
		disableOnDone = playgroundParticles.FindProperty("disableOnDone");
		disableOnDoneRoutine = playgroundParticles.FindProperty("disableOnDoneRoutine");
		calculate = playgroundParticles.FindProperty("calculate");
		deltaMovementStrength = playgroundParticles.FindProperty("deltaMovementStrength");
		particleTimescale = playgroundParticles.FindProperty("particleTimescale");
		sizeMin = playgroundParticles.FindProperty("sizeMin");
		sizeMax = playgroundParticles.FindProperty("sizeMax");
		overflowOffset = playgroundParticles.FindProperty("overflowOffset");
		overflowMode = playgroundParticles.FindProperty("overflowMode");
		lifetime = playgroundParticles.FindProperty("lifetime");
		lifetimeSize = playgroundParticles.FindProperty("lifetimeSize");
		arraySize = playgroundParticles.FindProperty("particleArraySize");
		turbulenceLifetimeStrength = playgroundParticles.FindProperty("turbulenceLifetimeStrength");
		lifetimeVelocity = playgroundParticles.FindProperty("lifetimeVelocity");
		initialVelocityShape = playgroundParticles.FindProperty("initialVelocityShape");
		initialVelocityMin = playgroundParticles.FindProperty("initialVelocityMin");
		initialVelocityMax = playgroundParticles.FindProperty("initialVelocityMax");
		initialLocalVelocityMin = playgroundParticles.FindProperty("initialLocalVelocityMin");
		initialLocalVelocityMax = playgroundParticles.FindProperty("initialLocalVelocityMax");
		lifetimeColor = playgroundParticles.FindProperty("lifetimeColor");
		lifetimeColors = playgroundParticles.FindProperty ("lifetimeColors");
		arrayColor = playgroundParticles.FindProperty("arrayColorAlpha");
		colorSource = playgroundParticles.FindProperty("colorSource");
		collision = playgroundParticles.FindProperty("collision");
		affectRigidbodies = playgroundParticles.FindProperty("affectRigidbodies");
		mass = playgroundParticles.FindProperty("mass");
		collisionRadius = playgroundParticles.FindProperty("collisionRadius");
		collisionMask = playgroundParticles.FindProperty("collisionMask");
		collisionType = playgroundParticles.FindProperty("collisionType");
		bounciness = playgroundParticles.FindProperty("bounciness");
		states = playgroundParticles.FindProperty("states");
		worldObject = playgroundParticles.FindProperty("worldObject");
		skinnedWorldObject = playgroundParticles.FindProperty("skinnedWorldObject");
		forceSkinnedMeshUpdateOnMainThread = playgroundParticles.FindProperty ("forceSkinnedMeshUpdateOnMainThread");
		sourceTransform = playgroundParticles.FindProperty("sourceTransform");
		worldObjectUpdateVertices = playgroundParticles.FindProperty ("worldObjectUpdateVertices");
		worldObjectUpdateNormals = playgroundParticles.FindProperty("worldObjectUpdateNormals");
		sourcePaint = playgroundParticles.FindProperty("paint");
		sourceProjection = playgroundParticles.FindProperty("projection");
		sourceSplines = playgroundParticles.FindProperty("splines");
		sourceTransforms = playgroundParticles.FindProperty("sourceTransforms");
		lifetimeStretching = playgroundParticles.FindProperty("stretchLifetime");
		threadMethod = playgroundParticles.FindProperty("threadMethod");

		playgroundParticlesScriptReference.shurikenParticleSystem = playgroundParticlesScriptReference.GetComponent<ParticleSystem>();
		playgroundParticlesScriptReference.particleSystemRenderer = playgroundParticlesScriptReference.shurikenParticleSystem.GetComponent<Renderer>();
		particleMaterial = playgroundParticlesScriptReference.particleSystemRenderer.sharedMaterial;
		
		onlySourcePositioning = playgroundParticles.FindProperty("onlySourcePositioning");

		lifetimePositioning = playgroundParticles.FindProperty("lifetimePositioning");
		lifetimePositioningX = lifetimePositioning.FindPropertyRelative("x");
		lifetimePositioningY = lifetimePositioning.FindPropertyRelative("y");
		lifetimePositioningZ = lifetimePositioning.FindPropertyRelative("z");
		lifetimePositioningTimeScale = playgroundParticles.FindProperty ("lifetimePositioningTimeScale");
		lifetimePositioningPositionScale = playgroundParticles.FindProperty ("lifetimePositioningPositionScale");

		applyLifetimeVelocity = playgroundParticles.FindProperty("applyLifetimeVelocity");
		lifeTimeVelocityX = lifetimeVelocity.FindPropertyRelative("x");
		lifeTimeVelocityY = lifetimeVelocity.FindPropertyRelative("y");
		lifeTimeVelocityZ = lifetimeVelocity.FindPropertyRelative("z");
		
		initialVelocityShapeX = initialVelocityShape.FindPropertyRelative("x");
		initialVelocityShapeY = initialVelocityShape.FindPropertyRelative("y");
		initialVelocityShapeZ = initialVelocityShape.FindPropertyRelative("z");
		
		applyInitialVelocity = playgroundParticles.FindProperty("applyInitialVelocity");
		applyInitialLocalVelocity = playgroundParticles.FindProperty("applyInitialLocalVelocity");
		applyVelocityBending = playgroundParticles.FindProperty("applyVelocityBending");
		velocityBendingType = playgroundParticles.FindProperty("velocityBendingType");

		movementCompensationLifetimeStrength = playgroundParticles.FindProperty ("movementCompensationLifetimeStrength");
		
		worldObjectGameObject = worldObject.FindPropertyRelative("gameObject");
		skinnedWorldObjectGameObject = skinnedWorldObject.FindPropertyRelative("gameObject");

		// Lifetime colors
		if (playgroundParticlesScriptReference.lifetimeColors==null)
			playgroundParticlesScriptReference.lifetimeColors = new List<PlaygroundGradientC>();

		// Sorting
		prevLifetimeSortingKeys = playgroundParticlesScriptReference.lifetimeSorting.keys;

		// Events list
		eventListFoldout = new List<bool>();
		eventListFoldout.AddRange(new bool[playgroundParticlesScriptReference.events.Count]);

		// States foldout
		statesListFoldout = new List<bool>();
		statesListFoldout.AddRange(new bool[playgroundParticlesScriptReference.states.Count]);

		previousSource = playgroundParticlesScriptReference.source;
		
		// Playground
		playgroundScriptReference = FindObjectOfType<PlaygroundC>();
		
		
		// Create a manager if no existing instance is in the scene
		if (!playgroundScriptReference && Selection.activeTransform!=null) {
			PlaygroundC.ResourceInstantiate("Playground Manager");
			playgroundScriptReference = FindObjectOfType<PlaygroundC>();
		}
		
		if (playgroundScriptReference!=null) {

			PlaygroundC.reference = playgroundScriptReference;

			// Serialize Playground
			playground = new SerializedObject(playgroundScriptReference);
			
			PlaygroundInspectorC.Initialize(playgroundScriptReference);
			
			
			// Add this PlaygroundParticles if not existing in Playground list
			if (!playgroundParticlesScriptReference.isSnapshot && !playgroundScriptReference.particleSystems.Contains(playgroundParticlesScriptReference) && Selection.activeTransform!=null)
				playgroundScriptReference.particleSystems.Add(playgroundParticlesScriptReference);
				
			// Cache components
			playgroundParticlesScriptReference.particleSystemGameObject = playgroundParticlesScriptReference.gameObject;
			playgroundParticlesScriptReference.particleSystemTransform = playgroundParticlesScriptReference.transform;
			playgroundParticlesScriptReference.particleSystemRenderer = playgroundParticlesScriptReference.GetComponent<Renderer>();
			playgroundParticlesScriptReference.shurikenParticleSystem = playgroundParticlesScriptReference.particleSystemGameObject.GetComponent<ParticleSystem>();
			playgroundParticlesScriptReference.particleSystemRenderer2 = playgroundParticlesScriptReference.particleSystemGameObject.GetComponent<ParticleSystem>().GetComponent<Renderer>() as ParticleSystemRenderer;
			
			// Set manager as parent 
			//if (PlaygroundC.reference.autoGroup && playgroundParticlesScriptReference.particleSystemTransform!=null && playgroundParticlesScriptReference.particleSystemTransform.parent == null && Selection.activeTransform!=null)
			//	playgroundParticlesScriptReference.particleSystemTransform.parent = PlaygroundC.referenceTransform;
			
			// Issue a quick refresh

			if (!EditorApplication.isPlaying && isEditingInHierarchy) {
				foreach (PlaygroundParticlesC p in PlaygroundC.reference.particleSystems) {
					p.Start();
				}
			}
		}

		selectedSort = sorting.intValue;

		// State initial values
		if (addStateTransform==null)
			addStateTransform = (Transform)playgroundParticlesScriptReference.particleSystemTransform;
		
		// Visiblity of Shuriken component in Inspector
		if (!playgroundScriptReference || playgroundScriptReference && !playgroundScriptReference.showShuriken)
			playgroundParticlesScriptReference.shurikenParticleSystem.hideFlags = HideFlags.HideInInspector;
		else
			playgroundParticlesScriptReference.shurikenParticleSystem.hideFlags = HideFlags.None;

		SetWireframeVisibility();

		// Set paint init
		paintLayerMask = sourcePaint.FindPropertyRelative("layerMask");
		paintCollisionType = sourcePaint.FindPropertyRelative("collisionType");
		
		// Set projection init
		projectionMask = sourceProjection.FindPropertyRelative("projectionMask");
		projectionCollisionType = sourceProjection.FindPropertyRelative("collisionType");

		// Snapshots
		if (playgroundParticlesScriptReference.snapshots.Count>0) {
			if (playgroundParticlesScriptReference.snapshots.Count>0) {
				for (int i = 0; i<playgroundParticlesScriptReference.snapshots.Count; i++)
					if (playgroundParticlesScriptReference.snapshots[i].settings==null)
						playgroundParticlesScriptReference.snapshots.RemoveAt(i);
			}
			saveName += " "+(playgroundParticlesScriptReference.snapshots.Count+1).ToString();
		}

		SetMissingKeys();
	}
	void OnEnable () {

		lastActiveTool = Tools.current;
		
		// Playground Particles
		playgroundParticlesScriptReference = target as PlaygroundParticlesC;
		playgroundParticles = new SerializedObject(playgroundParticlesScriptReference);
		
		shurikenRenderer = playgroundParticlesScriptReference.particleSystemGameObject.particleSystem.renderer as ParticleSystemRenderer;
		
		manipulators = playgroundParticles.FindProperty("manipulators");
		events = playgroundParticles.FindProperty("events");
		snapshots = playgroundParticles.FindProperty("snapshots");
		source = playgroundParticles.FindProperty("source");
		sorting = playgroundParticles.FindProperty("sorting");
		lifetimeSorting = playgroundParticles.FindProperty("lifetimeSorting");
		nearestNeighborOrigin = playgroundParticles.FindProperty("nearestNeighborOrigin");
		activeState = playgroundParticles.FindProperty("activeState");
		particleCount = playgroundParticles.FindProperty("particleCount");
		emissionRate = playgroundParticles.FindProperty("emissionRate");
		updateRate = playgroundParticles.FindProperty("updateRate");
		emit = playgroundParticles.FindProperty("emit");
		loop = playgroundParticles.FindProperty("loop");
		disableOnDone = playgroundParticles.FindProperty("disableOnDone");
		calculate = playgroundParticles.FindProperty("calculate");
		deltaMovementStrength = playgroundParticles.FindProperty("deltaMovementStrength");
		particleTimescale = playgroundParticles.FindProperty("particleTimescale");
		sizeMin = playgroundParticles.FindProperty("sizeMin");
		sizeMax = playgroundParticles.FindProperty("sizeMax");
		overflowOffset = playgroundParticles.FindProperty("overflowOffset");
		overflowMode = playgroundParticles.FindProperty("overflowMode");
		lifetime = playgroundParticles.FindProperty("lifetime");
		lifetimeSize = playgroundParticles.FindProperty("lifetimeSize");
		turbulenceLifetimeStrength = playgroundParticles.FindProperty("turbulenceLifetimeStrength");
		lifetimeVelocity = playgroundParticles.FindProperty("lifetimeVelocity");
		initialVelocityShape = playgroundParticles.FindProperty("initialVelocityShape");
		initialVelocityMin = playgroundParticles.FindProperty("initialVelocityMin");
		initialVelocityMax = playgroundParticles.FindProperty("initialVelocityMax");
		initialLocalVelocityMin = playgroundParticles.FindProperty("initialLocalVelocityMin");
		initialLocalVelocityMax = playgroundParticles.FindProperty("initialLocalVelocityMax");
		lifetimeColor = playgroundParticles.FindProperty("lifetimeColor");
		lifetimeColors = playgroundParticles.FindProperty ("lifetimeColors");
		colorSource = playgroundParticles.FindProperty("colorSource");
		collision = playgroundParticles.FindProperty("collision");
		affectRigidbodies = playgroundParticles.FindProperty("affectRigidbodies");
		mass = playgroundParticles.FindProperty("mass");
		collisionRadius = playgroundParticles.FindProperty("collisionRadius");
		collisionMask = playgroundParticles.FindProperty("collisionMask");
		collisionType = playgroundParticles.FindProperty("collisionType");
		bounciness = playgroundParticles.FindProperty("bounciness");
		states = playgroundParticles.FindProperty("states");
		worldObject = playgroundParticles.FindProperty("worldObject");
		skinnedWorldObject = playgroundParticles.FindProperty("skinnedWorldObject");
		sourceTransform = playgroundParticles.FindProperty("sourceTransform");
		worldObjectUpdateVertices = playgroundParticles.FindProperty ("worldObjectUpdateVertices");
		worldObjectUpdateNormals = playgroundParticles.FindProperty("worldObjectUpdateNormals");
		sourcePaint = playgroundParticles.FindProperty("paint");
		sourceProjection = playgroundParticles.FindProperty("projection");
		lifetimeStretching = playgroundParticles.FindProperty("stretchLifetime");

		playgroundParticlesScriptReference.shurikenParticleSystem = playgroundParticlesScriptReference.GetComponent<ParticleSystem>();
		playgroundParticlesScriptReference.particleSystemRenderer = playgroundParticlesScriptReference.shurikenParticleSystem.renderer;
		particleMaterial = playgroundParticlesScriptReference.particleSystemRenderer.sharedMaterial;
		
		onlySourcePositioning = playgroundParticles.FindProperty("onlySourcePositioning");
		
		applyLifetimeVelocity = playgroundParticles.FindProperty("applyLifetimeVelocity");
		lifeTimeVelocityX = lifetimeVelocity.FindPropertyRelative("x");
		lifeTimeVelocityY = lifetimeVelocity.FindPropertyRelative("y");
		lifeTimeVelocityZ = lifetimeVelocity.FindPropertyRelative("z");
		
		initialVelocityShapeX = initialVelocityShape.FindPropertyRelative("x");
		initialVelocityShapeY = initialVelocityShape.FindPropertyRelative("y");
		initialVelocityShapeZ = initialVelocityShape.FindPropertyRelative("z");
		
		applyInitialVelocity = playgroundParticles.FindProperty("applyInitialVelocity");
		applyInitialLocalVelocity = playgroundParticles.FindProperty("applyInitialLocalVelocity");
		applyVelocityBending = playgroundParticles.FindProperty("applyVelocityBending");
		velocityBendingType = playgroundParticles.FindProperty("velocityBendingType");

		movementCompensationLifetimeStrength = playgroundParticles.FindProperty ("movementCompensationLifetimeStrength");
		
		worldObjectGameObject = worldObject.FindPropertyRelative("gameObject");
		skinnedWorldObjectGameObject = skinnedWorldObject.FindPropertyRelative("gameObject");

		// Lifetime colors
		if (playgroundParticlesScriptReference.lifetimeColors==null)
			playgroundParticlesScriptReference.lifetimeColors = new List<PlaygroundGradientC>();

		// Sorting
		prevLifetimeSortingKeys = playgroundParticlesScriptReference.lifetimeSorting.keys;
		
		// Manipulator list
		manipulatorListFoldout = new List<bool>();
		manipulatorListFoldout.AddRange(new bool[playgroundParticlesScriptReference.manipulators.Count]);

		// Events list
		eventListFoldout = new List<bool>();
		eventListFoldout.AddRange(new bool[playgroundParticlesScriptReference.events.Count]);

		// States foldout
		statesListFoldout = new List<bool>();
		statesListFoldout.AddRange(new bool[playgroundParticlesScriptReference.states.Count]);

		previousSource = playgroundParticlesScriptReference.source;
		
		// Playground
		playgroundScriptReference = FindObjectOfType<PlaygroundC>();
		
		
		// Create a manager if no existing instance is in the scene
		if (!playgroundScriptReference && Selection.activeTransform!=null) {
			PlaygroundC.ResourceInstantiate("Playground Manager");
			playgroundScriptReference = FindObjectOfType<PlaygroundC>();
		}
		
		if (playgroundScriptReference!=null) {
			PlaygroundC.reference = playgroundScriptReference;

			// Serialize Playground
			playground = new SerializedObject(playgroundScriptReference);
			
			PlaygroundInspectorC.Initialize(playgroundScriptReference);
			
			
			// Add this PlaygroundParticles if not existing in Playground list
			if (!playgroundParticlesScriptReference.isSnapshot && !playgroundScriptReference.particleSystems.Contains(playgroundParticlesScriptReference) && Selection.activeTransform!=null)
				playgroundScriptReference.particleSystems.Add(playgroundParticlesScriptReference);
				
			// Cache components
			playgroundParticlesScriptReference.particleSystemGameObject = playgroundParticlesScriptReference.gameObject;
			playgroundParticlesScriptReference.particleSystemTransform = playgroundParticlesScriptReference.transform;
			playgroundParticlesScriptReference.particleSystemRenderer = playgroundParticlesScriptReference.renderer;
			playgroundParticlesScriptReference.shurikenParticleSystem = playgroundParticlesScriptReference.particleSystemGameObject.GetComponent<ParticleSystem>();
			playgroundParticlesScriptReference.particleSystemRenderer2 = playgroundParticlesScriptReference.particleSystemGameObject.particleSystem.renderer as ParticleSystemRenderer;
			
			// Set manager as parent 
			if (PlaygroundC.reference.autoGroup && playgroundParticlesScriptReference.particleSystemTransform!=null && playgroundParticlesScriptReference.particleSystemTransform.parent == null && Selection.activeTransform!=null)
				playgroundParticlesScriptReference.particleSystemTransform.parent = PlaygroundC.referenceTransform;
			
			// Issue a quick refresh
			if (!EditorApplication.isPlaying)
				foreach (PlaygroundParticlesC p in PlaygroundC.reference.particleSystems)
					p.Start();
		}

		selectedSort = sorting.intValue;

		// State initial values
		if (addStateTransform==null)
			addStateTransform = (Transform)playgroundParticlesScriptReference.particleSystemTransform;
		
		// Visiblity of Shuriken component in Inspector
		if (!playgroundScriptReference || playgroundScriptReference && !playgroundScriptReference.showShuriken)
			playgroundParticlesScriptReference.shurikenParticleSystem.hideFlags = HideFlags.HideInInspector;
		else
			playgroundParticlesScriptReference.shurikenParticleSystem.hideFlags = HideFlags.None;

		SetWireframeVisibility();

		// Set paint init
		paintLayerMask = sourcePaint.FindPropertyRelative("layerMask");
		paintCollisionType = sourcePaint.FindPropertyRelative("collisionType");
		
		LoadBrushes();
		
		// Set projection init
		projectionMask = sourceProjection.FindPropertyRelative("projectionMask");
		projectionCollisionType = sourceProjection.FindPropertyRelative("collisionType");

		// Snapshots
		if (playgroundParticlesScriptReference.snapshots.Count>0) {
			if (playgroundParticlesScriptReference.snapshots.Count>0) {
				for (int i = 0; i<playgroundParticlesScriptReference.snapshots.Count; i++)
					if (playgroundParticlesScriptReference.snapshots[i].settings==null)
						playgroundParticlesScriptReference.snapshots.RemoveAt(i);
			}
			saveName += " "+(playgroundParticlesScriptReference.snapshots.Count+1).ToString();
		}
	}
	public static void RenderPlaygroundSettings () {
		if (boxStyle==null)
			boxStyle = GUI.skin.FindStyle("box");
		EditorGUILayout.BeginVertical(boxStyle);

		playgroundFoldout = GUILayout.Toggle(playgroundFoldout, "Playground Manager", EditorStyles.foldout);
		if (playgroundFoldout) {
		
		EditorGUILayout.BeginVertical(boxStyle);
		if (playgroundScriptReference==null) {
			 playgroundScriptReference = GameObject.FindObjectOfType<PlaygroundC>();
			if (playgroundScriptReference)
				Initialize(playgroundScriptReference);
		}
		
		if (playgroundFoldout && playgroundScriptReference!=null) {
			playground.Update();
			
			// Particle System List
			if (GUILayout.Button("Particle Systems ("+playgroundScriptReference.particleSystems.Count+")", EditorStyles.toolbarDropDown)) particleSystemsFoldout=!particleSystemsFoldout;
			if (particleSystemsFoldout) {
				
				EditorGUILayout.Separator();
				
				if (playgroundScriptReference.particleSystems.Count>0) {
					for (int ps = 0; ps<playgroundScriptReference.particleSystems.Count; ps++) {
						
						EditorGUILayout.BeginVertical(boxStyle, GUILayout.MinHeight(26));
						EditorGUILayout.BeginHorizontal();
						
						if (playgroundScriptReference.particleSystems[ps].particleSystemGameObject == Selection.activeGameObject) GUILayout.BeginHorizontal(boxStyle);
						
						GUILayout.Label(ps.ToString(), EditorStyles.miniLabel, new GUILayoutOption[]{GUILayout.Width(18)});
						if (GUILayout.Button(playgroundScriptReference.particleSystems[ps].particleSystemGameObject.name, EditorStyles.label)) {
							Selection.activeGameObject = playgroundScriptReference.particleSystems[ps].particleSystemGameObject;
						}
						EditorGUILayout.Separator();
						GUI.enabled = (playgroundScriptReference.particleSystems.Count>1);
						if(GUILayout.Button("U", EditorStyles.toolbarButton, new GUILayoutOption[]{GUILayout.Width(18), GUILayout.Height(16)})){
							particleSystems.MoveArrayElement(ps, ps==0?playgroundScriptReference.particleSystems.Count-1:ps-1);
						}
						if(GUILayout.Button("D", EditorStyles.toolbarButton, new GUILayoutOption[]{GUILayout.Width(18), GUILayout.Height(16)})){
							particleSystems.MoveArrayElement(ps, ps<playgroundScriptReference.particleSystems.Count-1?ps+1:0);
						}
						GUI.enabled = true;
						
						// Clone
						if(GUILayout.Button("+", EditorStyles.toolbarButton, new GUILayoutOption[]{GUILayout.Width(18), GUILayout.Height(16)})){
							GameObject ppsDuplicateGo = Instantiate(playgroundScriptReference.particleSystems[ps].particleSystemGameObject, playgroundScriptReference.particleSystems[ps].particleSystemTransform.position, playgroundScriptReference.particleSystems[ps].particleSystemTransform.rotation) as GameObject;
							PlaygroundParticlesC ppsDuplicate = ppsDuplicateGo.GetComponent<PlaygroundParticlesC>();
							
							// Cache state data
							for (int x = 0; x<ppsDuplicate.states.Count; x++)
								ppsDuplicate.states[x].Initialize();
							
							// Set particle count to initiate all arrays
							PlaygroundC.SetParticleCount(ppsDuplicate, ppsDuplicate.particleCount);
							
							// Add this to Manager
							if (PlaygroundC.reference!=null) {
								PlaygroundC.particlesQuantity++;
								PlaygroundC.reference.particleSystems.Add(ppsDuplicate);
								ppsDuplicate.particleSystemId = PlaygroundC.particlesQuantity;
								if (PlaygroundC.reference.autoGroup && ppsDuplicate.particleSystemTransform.parent==null)
									ppsDuplicate.particleSystemTransform.parent = PlaygroundC.referenceTransform;
							}
						}
						if(GUILayout.Button("-", EditorStyles.toolbarButton, new GUILayoutOption[]{GUILayout.Width(18), GUILayout.Height(16)})){
							if (EditorUtility.DisplayDialog(
								"Remove "+playgroundScriptReference.particleSystems[ps].particleSystemGameObject.name+"?",
								"Are you sure you want to remove this Particle Playground System?", 
								"Yes", "No")) {
									if (Selection.activeGameObject==playgroundScriptReference.particleSystems[ps].particleSystemGameObject)
										Selection.activeGameObject = PlaygroundC.referenceTransform.gameObject;
									PlaygroundC.Destroy(playgroundScriptReference.particleSystems[ps]);
									playground.ApplyModifiedProperties();
									return;
								}
						}
						
						if (playgroundScriptReference.particleSystems[ps].particleSystemGameObject == Selection.activeGameObject) GUILayout.EndHorizontal();
						EditorGUILayout.EndHorizontal();
						EditorGUILayout.EndVertical();
					}
				} else {
					EditorGUILayout.HelpBox("No particle systems created.", MessageType.Info);
				}
				
				if(GUILayout.Button("Create", EditorStyles.toolbarButton, GUILayout.Width(50))){
					PlaygroundParticlesC createdParticles = PlaygroundC.Particle();
					Selection.activeGameObject = createdParticles.particleSystemGameObject;
				}
				
				EditorGUILayout.Separator();
			}
			
			// Manipulators
			if (GUILayout.Button("Global Manipulators ("+playgroundScriptReference.manipulators.Count+")", EditorStyles.toolbarDropDown)) manipulatorsFoldout=!manipulatorsFoldout;
			if (manipulatorsFoldout) {
				
				EditorGUILayout.Separator();
				
				if (manipulators.arraySize>0) {
									
					
					for (int i = 0; i<manipulators.arraySize; i++) {
						string mName;
						if (playgroundScriptReference.manipulators[i].transform) {
							mName = playgroundScriptReference.manipulators[i].transform.name;
							if (mName.Length>24)
								mName = mName.Substring(0, 24)+"...";
						} else mName = "(Missing Transform!)";
						
						EditorGUILayout.BeginVertical(boxStyle);
						
						EditorGUILayout.BeginHorizontal();
						
						GUILayout.Label(i.ToString(), EditorStyles.miniLabel, GUILayout.Width(18));
						manipulatorListFoldout[i] = GUILayout.Toggle(manipulatorListFoldout[i], ManipulatorTypeName(playgroundScriptReference.manipulators[i].type), EditorStyles.foldout, GUILayout.Width(Screen.width/4));
						if (playgroundScriptReference.manipulators[i].transform) {
							if (GUILayout.Button(" ("+mName+")", EditorStyles.label)) {
								Selection.activeGameObject = playgroundScriptReference.manipulators[i].transform.gameObject;
							}
						} else {
							GUILayout.Button(ManipulatorTypeName(playgroundScriptReference.manipulators[i].type)+" (Missing Transform!)", EditorStyles.label);
						}
						EditorGUILayout.Separator();
						GUI.enabled = (playgroundScriptReference.manipulators.Count>1);
						if(GUILayout.Button("U", EditorStyles.toolbarButton, new GUILayoutOption[]{GUILayout.Width(18), GUILayout.Height(16)})){
							manipulators.MoveArrayElement(i, i==0?playgroundScriptReference.manipulators.Count-1:i-1);
						}
						if(GUILayout.Button("D", EditorStyles.toolbarButton, new GUILayoutOption[]{GUILayout.Width(18), GUILayout.Height(16)})){
							manipulators.MoveArrayElement(i, i<playgroundScriptReference.manipulators.Count-1?i+1:0);
						}
						GUI.enabled = true;
						if(GUILayout.Button("+", EditorStyles.toolbarButton, new GUILayoutOption[]{GUILayout.Width(18), GUILayout.Height(16)})){
							PlaygroundC.reference.manipulators.Add(playgroundScriptReference.manipulators[i].Clone());
							manipulatorListFoldout.Add(manipulatorListFoldout[i]);
						}
						if(GUILayout.Button("-", EditorStyles.toolbarButton, new GUILayoutOption[]{GUILayout.Width(18), GUILayout.Height(16)})){
							
							if (EditorUtility.DisplayDialog(
								"Remove "+ManipulatorTypeName(playgroundScriptReference.manipulators[i].type)+" Manipulator "+i+"?",
								"Are you sure you want to remove the Manipulator assigned to "+mName+"? (GameObject in Scene will remain intact)", 
								"Yes", "No")) {
									manipulators.DeleteArrayElementAtIndex(i);
									manipulatorListFoldout.RemoveAt(i);
									playground.ApplyModifiedProperties();
									return;
								}
						}
						
						EditorGUILayout.EndHorizontal();
						
						if (manipulatorListFoldout[i] && i<manipulators.arraySize) {
							RenderManipulatorSettings(playgroundScriptReference.manipulators[i], manipulators.GetArrayElementAtIndex(i), true);
						}
						GUI.enabled = true;
						EditorGUILayout.Separator();
						EditorGUILayout.EndVertical();
					}
					
				} else {
					EditorGUILayout.HelpBox("No manipulators created.", MessageType.Info);
				}
				
				if(GUILayout.Button("Create", EditorStyles.toolbarButton, GUILayout.Width(50))){
					if (Selection.gameObjects.Length>0 && Selection.activeGameObject.transform && Selection.activeTransform!=null)
						PlaygroundC.ManipulatorObject(Selection.activeGameObject.transform);
					else
						manipulators.InsertArrayElementAtIndex(manipulators.arraySize);
					manipulatorListFoldout.Add(true);
					SceneView.RepaintAll();
				}
					
				
				EditorGUILayout.Separator();
								
			}
			
			// Advanced Settings
			if (GUILayout.Button("Advanced", EditorStyles.toolbarDropDown)) advancedSettingsFoldout=!advancedSettingsFoldout;
			if (advancedSettingsFoldout) {
				
				EditorGUILayout.Separator();
				EditorGUILayout.PropertyField(calculate, new GUIContent("Calculate Particles", "Calculate forces on PlaygroundParticles objects. Disabling this overrides independently set values and halts all PlaygroundParticles objects."));
				EditorGUILayout.PropertyField(garbageCollectOnResize, new GUIContent("Garbage Collection", "Issue a GC.Collect when resizing particle lists."));
				EditorGUILayout.PropertyField(autoGroup, new GUIContent("Group Automatically", "Automatically parent a PlaygroundParticles object to Playground Manager if it has no parent."));
				EditorGUILayout.PropertyField(buildZeroAlphaPixels, new GUIContent("Build Zero Alpha Pixels", "Turn this on if you want to build particles from 0 alpha pixels into states."));
				EditorGUILayout.PropertyField(drawGizmos, new GUIContent("Scene Gizmos", "Show gizmos in Scene View for Playground objects."));
				EditorGUILayout.PropertyField(paintToolbox, new GUIContent("Paint Toolbox", "Show Paint toolbox in Scene View when Source is set to Paint"));
				EditorGUILayout.PropertyField(showShuriken, new GUIContent("Show Shuriken", "Show the Shuriken component in Inspector."));
				EditorGUILayout.PropertyField(pixelFilterMode, new GUIContent("Pixel Filter Mode", "Color filtering mode when creating particles from pixels in an image."));
				EditorGUILayout.Separator();
				
				// Time reset
				GUILayout.BeginHorizontal();
				EditorGUILayout.PrefixLabel("Time Simulation");
				if(GUILayout.Button("Reset", EditorStyles.toolbarButton, GUILayout.Width(50))){
					PlaygroundC.TimeReset();
					for (int p = 0; p<playgroundScriptReference.particleSystems.Count; p++)
						playgroundScriptReference.particleSystems[p].Start();
				}
				GUILayout.EndHorizontal();
				
				EditorGUILayout.Separator();
				
				// Limits
				EditorGUILayout.BeginVertical(boxStyle);
				limitsFoldout = GUILayout.Toggle(limitsFoldout, "Editor Limits", EditorStyles.foldout);
				if (limitsFoldout) {
					EditorGUILayout.Separator();
					playgroundScriptReference.maximumAllowedTransitionTime = EditorGUILayout.FloatField("Transition Time", playgroundScriptReference.maximumAllowedTransitionTime);
					EditorGUILayout.Separator();
					playgroundScriptReference.maximumAllowedParticles = EditorGUILayout.IntField("Particle Count", playgroundScriptReference.maximumAllowedParticles);
					playgroundScriptReference.maximumAllowedLifetime = EditorGUILayout.FloatField("Particle Lifetime", playgroundScriptReference.maximumAllowedLifetime);
					playgroundScriptReference.maximumAllowedRotation = EditorGUILayout.FloatField("Particle Rotation", playgroundScriptReference.maximumAllowedRotation);
					playgroundScriptReference.maximumAllowedSize = EditorGUILayout.FloatField("Particle Size", playgroundScriptReference.maximumAllowedSize);
					playgroundScriptReference.maximumAllowedScale = EditorGUILayout.FloatField("Particle Scale", playgroundScriptReference.maximumAllowedScale);
					playgroundScriptReference.maximumAllowedSourceScatter = EditorGUILayout.FloatField("Source Scatter", playgroundScriptReference.maximumAllowedSourceScatter);
					EditorGUILayout.Separator();
					playgroundScriptReference.maximumAllowedDeltaMovementStrength = EditorGUILayout.FloatField("Delta Movement Strength", playgroundScriptReference.maximumAllowedDeltaMovementStrength);
					playgroundScriptReference.maximumAllowedDamping = EditorGUILayout.FloatField("Damping", playgroundScriptReference.maximumAllowedDamping);
					playgroundScriptReference.maximumAllowedInitialVelocity = EditorGUILayout.FloatField("Initial Velocity", playgroundScriptReference.maximumAllowedInitialVelocity);
					playgroundScriptReference.maximumAllowedVelocity = EditorGUILayout.FloatField("Velocity", playgroundScriptReference.maximumAllowedVelocity);
					EditorGUILayout.Separator();
					playgroundScriptReference.maximumAllowedCollisionRadius = EditorGUILayout.FloatField("Collision Radius", playgroundScriptReference.maximumAllowedCollisionRadius);
					playgroundScriptReference.maximumAllowedMass = EditorGUILayout.FloatField("Mass", playgroundScriptReference.maximumAllowedMass);
					playgroundScriptReference.maximumAllowedBounciness = EditorGUILayout.FloatField("Bounciness", playgroundScriptReference.maximumAllowedBounciness);
					EditorGUILayout.Separator();
					playgroundScriptReference.minimumAllowedUpdateRate = EditorGUILayout.IntField("Update Rate", playgroundScriptReference.minimumAllowedUpdateRate);
					playgroundScriptReference.maximumRenderSliders = EditorGUILayout.FloatField("Render Sliders", playgroundScriptReference.maximumRenderSliders);
					EditorGUILayout.Separator();
					playgroundScriptReference.maximumAllowedPaintPositions = EditorGUILayout.IntField("Paint Positions", playgroundScriptReference.maximumAllowedPaintPositions);
					playgroundScriptReference.minimumAllowedBrushScale = EditorGUILayout.FloatField("Brush Size Min", playgroundScriptReference.minimumAllowedBrushScale);
					playgroundScriptReference.maximumAllowedBrushScale = EditorGUILayout.FloatField("Brush Size Max", playgroundScriptReference.maximumAllowedBrushScale);
					playgroundScriptReference.minimumEraserRadius = EditorGUILayout.FloatField("Eraser Size Min", playgroundScriptReference.minimumEraserRadius);
					playgroundScriptReference.maximumEraserRadius = EditorGUILayout.FloatField("Eraser Size Max", playgroundScriptReference.maximumEraserRadius);
					playgroundScriptReference.maximumAllowedPaintSpacing = EditorGUILayout.FloatField("Paint Spacing", playgroundScriptReference.maximumAllowedPaintSpacing);
					EditorGUILayout.Separator();
					playgroundScriptReference.maximumAllowedManipulatorSize = EditorGUILayout.FloatField("Manipulator Size", playgroundScriptReference.maximumAllowedManipulatorSize);
					playgroundScriptReference.maximumAllowedManipulatorStrength = EditorGUILayout.FloatField("Manipulator Strength", playgroundScriptReference.maximumAllowedManipulatorStrength);
					playgroundScriptReference.maximumAllowedManipulatorZeroVelocity = EditorGUILayout.FloatField("Zero Velocity Strength", playgroundScriptReference.maximumAllowedManipulatorZeroVelocity);
					EditorGUILayout.Separator();
				}
				EditorGUILayout.EndVertical();
			}
			
			EditorGUI.indentLevel--;
			
			playground.ApplyModifiedProperties();
			EditorGUILayout.EndVertical();
		} else {
			EditorGUILayout.HelpBox("The Playground Manager runs all Particle Playground Systems in the scene, you need to create one in your scene to get started.", MessageType.Info);
			if(GUILayout.Button("Create", EditorStyles.toolbarButton, GUILayout.Width(50))){
				PlaygroundC.ResourceInstantiate("Playground Manager");
			}
			EditorGUILayout.EndVertical();
		}
		
	}
		EditorGUILayout.EndVertical();
	}
Example #37
0
	public static void RenderPlaygroundSettings () {
		if (boxStyle==null)
			boxStyle = GUI.skin.FindStyle("box");
		EditorGUILayout.BeginVertical(boxStyle);
		
		if (playgroundSettings==null) {
			playgroundSettings = PlaygroundSettingsC.GetReference();
			playgroundLanguage = PlaygroundSettingsC.GetLanguage();
		}
		playgroundSettings.playgroundManagerFoldout = GUILayout.Toggle(playgroundSettings.playgroundManagerFoldout, playgroundLanguage.playgroundManager, EditorStyles.foldout);
		if (playgroundSettings.playgroundManagerFoldout) {
			
			EditorGUILayout.BeginVertical(boxStyle);
			if (playgroundScriptReference==null) {
				playgroundScriptReference = GameObject.FindObjectOfType<PlaygroundC>();
				if (playgroundScriptReference)
					Initialize(playgroundScriptReference);
			}
			
			if (playgroundSettings.playgroundFoldout && playgroundScriptReference!=null) {
				playground.Update();
				
				// Particle System List
				if (GUILayout.Button(playgroundLanguage.particleSystems+" ("+playgroundScriptReference.particleSystems.Count+")", EditorStyles.toolbarDropDown)) playgroundSettings.particleSystemsFoldout=!playgroundSettings.particleSystemsFoldout;
				if (playgroundSettings.particleSystemsFoldout) {
					
					EditorGUILayout.Separator();
					
					if (playgroundScriptReference.particleSystems.Count>0) {
						for (int ps = 0; ps<playgroundScriptReference.particleSystems.Count; ps++) {
							
							EditorGUILayout.BeginVertical(boxStyle, GUILayout.MinHeight(26));
							EditorGUILayout.BeginHorizontal();
							
							if (playgroundScriptReference.particleSystems[ps].particleSystemGameObject == Selection.activeGameObject) GUILayout.BeginHorizontal(boxStyle);
							
							GUILayout.Label(ps.ToString(), EditorStyles.miniLabel, new GUILayoutOption[]{GUILayout.Width(18)});
							if (GUILayout.Button(playgroundScriptReference.particleSystems[ps].particleSystemGameObject.name+" ("+playgroundScriptReference.particleSystems[ps].particleCount+")", EditorStyles.label)) {
								Selection.activeGameObject = playgroundScriptReference.particleSystems[ps].particleSystemGameObject;
							}
							EditorGUILayout.Separator();
							if (playgroundScriptReference.particleSystems[ps].threadMethod!=ThreadMethodLocal.Inherit) {
								GUILayout.Label(playgroundLanguage.thread+": "+playgroundScriptReference.particleSystems[ps].threadMethod.ToString(), EditorStyles.miniLabel);
							}
							GUI.enabled = (playgroundScriptReference.particleSystems.Count>1);
							if(GUILayout.Button(playgroundLanguage.upSymbol, EditorStyles.toolbarButton, new GUILayoutOption[]{GUILayout.Width(18), GUILayout.Height(16)})){
								particleSystems.MoveArrayElement(ps, ps==0?playgroundScriptReference.particleSystems.Count-1:ps-1);
							}
							if(GUILayout.Button(playgroundLanguage.downSymbol, EditorStyles.toolbarButton, new GUILayoutOption[]{GUILayout.Width(18), GUILayout.Height(16)})){
								particleSystems.MoveArrayElement(ps, ps<playgroundScriptReference.particleSystems.Count-1?ps+1:0);
							}
							GUI.enabled = true;
							
							// Clone
							if(GUILayout.Button("+", EditorStyles.toolbarButton, new GUILayoutOption[]{GUILayout.Width(18), GUILayout.Height(16)})){
								GameObject ppsDuplicateGo = Instantiate(playgroundScriptReference.particleSystems[ps].particleSystemGameObject, playgroundScriptReference.particleSystems[ps].particleSystemTransform.position, playgroundScriptReference.particleSystems[ps].particleSystemTransform.rotation) as GameObject;
								PlaygroundParticlesC ppsDuplicate = ppsDuplicateGo.GetComponent<PlaygroundParticlesC>();
								
								// Add this to Manager
								if (PlaygroundC.reference!=null) {
									PlaygroundC.particlesQuantity++;
									ppsDuplicate.particleSystemId = PlaygroundC.particlesQuantity;
									if (PlaygroundC.reference.autoGroup && ppsDuplicate.particleSystemTransform.parent==null)
										ppsDuplicate.particleSystemTransform.parent = PlaygroundC.referenceTransform;
								}
							}
							if(GUILayout.Button("-", EditorStyles.toolbarButton, new GUILayoutOption[]{GUILayout.Width(18), GUILayout.Height(16)})){
								if (EditorUtility.DisplayDialog(
									playgroundLanguage.remove+" "+playgroundScriptReference.particleSystems[ps].particleSystemGameObject.name+"?",
									playgroundLanguage.removeParticlePlaygroundSystem, 
									playgroundLanguage.yes, playgroundLanguage.no)) {
									if (Selection.activeGameObject==playgroundScriptReference.particleSystems[ps].particleSystemGameObject)
										Selection.activeGameObject = PlaygroundC.referenceTransform.gameObject;
									PlaygroundC.Destroy(playgroundScriptReference.particleSystems[ps]);
									playground.ApplyModifiedProperties();
									return;
								}
							}
							
							if (playgroundScriptReference.particleSystems[ps].particleSystemGameObject == Selection.activeGameObject) GUILayout.EndHorizontal();
							EditorGUILayout.EndHorizontal();
							EditorGUILayout.EndVertical();
						}
					} else {
						EditorGUILayout.HelpBox(playgroundLanguage.noParticleSystems, MessageType.Info);
					}
					
					if(GUILayout.Button(playgroundLanguage.create, EditorStyles.toolbarButton, GUILayout.ExpandWidth(false))){
						PlaygroundParticlesC createdParticles = PlaygroundC.Particle();
						Selection.activeGameObject = createdParticles.particleSystemGameObject;
					}
					
					EditorGUILayout.Separator();
				}
				
				// Manipulators
				if (GUILayout.Button(playgroundLanguage.globalManipulators+" ("+playgroundScriptReference.manipulators.Count+")", EditorStyles.toolbarDropDown)) playgroundSettings.globalManipulatorsFoldout=!playgroundSettings.globalManipulatorsFoldout;
				if (playgroundSettings.globalManipulatorsFoldout) {
					
					EditorGUILayout.Separator();
					
					if (manipulators.arraySize>0) {
						
						for (int i = 0; i<manipulators.arraySize; i++) {
							if (!playgroundScriptReference.manipulators[i].enabled)
								GUI.contentColor = Color.gray;
							string mName;
							if (playgroundScriptReference.manipulators[i].transform.available) {
								mName = playgroundScriptReference.manipulators[i].transform.transform.name;
								if (mName.Length>24)
									mName = mName.Substring(0, 24)+"...";
							} else {
								GUI.color = Color.red;
								mName = "("+playgroundLanguage.missingTransform+")";
							}
							
							EditorGUILayout.BeginVertical(boxStyle);
							
							EditorGUILayout.BeginHorizontal();
							
							GUILayout.Label(i.ToString(), EditorStyles.miniLabel, GUILayout.Width(18));
							playgroundScriptReference.manipulators[i].unfolded = GUILayout.Toggle(playgroundScriptReference.manipulators[i].unfolded, ManipulatorTypeName(playgroundScriptReference.manipulators[i].type), EditorStyles.foldout, GUILayout.Width(Screen.width/4));
							if (playgroundScriptReference.manipulators[i].transform.available) {
								if (GUILayout.Button(" ("+mName+")", EditorStyles.label)) {
									Selection.activeGameObject = playgroundScriptReference.manipulators[i].transform.transform.gameObject;
								}
							} else {
								GUILayout.Button(ManipulatorTypeName(playgroundScriptReference.manipulators[i].type)+" ("+playgroundLanguage.missingTransform+")", EditorStyles.label);
							}
							GUI.contentColor = Color.white;
							EditorGUILayout.Separator();
							GUI.enabled = (playgroundScriptReference.manipulators.Count>1);
							if(GUILayout.Button(playgroundLanguage.upSymbol, EditorStyles.toolbarButton, new GUILayoutOption[]{GUILayout.Width(18), GUILayout.Height(16)})){
								manipulators.MoveArrayElement(i, i==0?playgroundScriptReference.manipulators.Count-1:i-1);
							}
							if(GUILayout.Button(playgroundLanguage.downSymbol, EditorStyles.toolbarButton, new GUILayoutOption[]{GUILayout.Width(18), GUILayout.Height(16)})){
								manipulators.MoveArrayElement(i, i<playgroundScriptReference.manipulators.Count-1?i+1:0);
							}
							GUI.enabled = true;
							if(GUILayout.Button("+", EditorStyles.toolbarButton, new GUILayoutOption[]{GUILayout.Width(18), GUILayout.Height(16)})){
								PlaygroundC.reference.manipulators.Add(playgroundScriptReference.manipulators[i].Clone());
							}
							if(GUILayout.Button("-", EditorStyles.toolbarButton, new GUILayoutOption[]{GUILayout.Width(18), GUILayout.Height(16)})){
								
								if (EditorUtility.DisplayDialog(
									playgroundLanguage.remove+" "+ManipulatorTypeName(playgroundScriptReference.manipulators[i].type)+" "+playgroundLanguage.manipulator+" "+i+"?",
									playgroundLanguage.removeManipulator+" "+mName+"? "+playgroundLanguage.gameObjectIntact, 
									playgroundLanguage.yes, playgroundLanguage.no)) {
									manipulators.DeleteArrayElementAtIndex(i);
									playground.ApplyModifiedProperties();
									return;
								}
							}
							
							GUI.color = Color.white;
							
							EditorGUILayout.EndHorizontal();
							
							if (playgroundScriptReference.manipulators[i].unfolded && i<manipulators.arraySize) {
								RenderManipulatorSettings(playgroundScriptReference.manipulators[i], manipulators.GetArrayElementAtIndex(i), true);
							}
							
							GUI.enabled = true;
							EditorGUILayout.Separator();
							EditorGUILayout.EndVertical();
						}
						
					} else {
						EditorGUILayout.HelpBox(playgroundLanguage.noManipulators, MessageType.Info);
					}
					
					if(GUILayout.Button(playgroundLanguage.create, EditorStyles.toolbarButton, GUILayout.ExpandWidth(false))){
						
						if (Selection.gameObjects.Length>0 && Selection.activeGameObject.transform && Selection.activeTransform!=null) {
							Transform mTrans = new GameObject().transform;
							mTrans.parent = PlaygroundC.referenceTransform;
							mTrans.position = Selection.activeGameObject.transform.position+Vector3.up;
							if (manipulators.arraySize>0)
								mTrans.name = "Global Manipulator "+(manipulators.arraySize+1);
							else mTrans.name = "Global Manipulator";
							PlaygroundC.ManipulatorObject(mTrans);
						} else
							manipulators.InsertArrayElementAtIndex(manipulators.arraySize);
						SceneView.RepaintAll();
					}
					
					EditorGUILayout.Separator();
					
				}
				
				// Advanced Settings
				if (GUILayout.Button(playgroundLanguage.advanced, EditorStyles.toolbarDropDown)) playgroundSettings.advancedSettingsFoldout=!playgroundSettings.advancedSettingsFoldout;
				if (playgroundSettings.advancedSettingsFoldout) {
					
					showSnapshotsSettings = PlaygroundC.reference.showSnapshotsInHierarchy;
					
					EditorGUILayout.Separator();
					EditorGUILayout.PropertyField(calculate, new GUIContent(playgroundLanguage.calculateParticles, playgroundLanguage.calculateParticlesDescription));
					EditorGUILayout.PropertyField(autoGroup, new GUIContent(playgroundLanguage.groupAutomatically, playgroundLanguage.groupAutomaticallyDescription));
					EditorGUILayout.PropertyField(buildZeroAlphaPixels, new GUIContent(playgroundLanguage.buildZeroAlphaPixels, playgroundLanguage.buildZeroAlphaPixelsDescription));
					EditorGUILayout.PropertyField(drawGizmos, new GUIContent(playgroundLanguage.sceneGizmos, playgroundLanguage.sceneGizmosDescription));
					GUI.enabled = drawGizmos.boolValue;
					EditorGUILayout.PropertyField(drawSourcePositions, new GUIContent(playgroundLanguage.sourcePositions, playgroundLanguage.sourcePositionsDescription));
					EditorGUILayout.PropertyField(drawSplinePreview, new GUIContent(playgroundLanguage.drawSplinePreview, playgroundLanguage.drawSplinePreviewDescription));
					PlaygroundSpline.drawSplinePreviews = drawSplinePreview.boolValue;
					GUI.enabled = true;
					EditorGUILayout.PropertyField(drawWireframe, new GUIContent(playgroundLanguage.wireframes, playgroundLanguage.wireframesDescription));
					EditorGUILayout.PropertyField(paintToolbox, new GUIContent(playgroundLanguage.paintToolbox, playgroundLanguage.paintToolboxDescription));
					EditorGUILayout.PropertyField(showShuriken, new GUIContent(playgroundLanguage.showShuriken, playgroundLanguage.showShurikenDescription));
					EditorGUILayout.PropertyField(showSnapshots, new GUIContent(playgroundLanguage.advancedSnapshots, playgroundLanguage.advancedSnapshotsDescription));
					EditorGUILayout.PropertyField(pixelFilterMode, new GUIContent(playgroundLanguage.pixelFilterMode, playgroundLanguage.pixelFilterModeDescription));
					EditorGUILayout.Separator();
					GUILayout.BeginVertical(boxStyle);
					EditorGUILayout.LabelField(playgroundLanguage.multithreading+" ("+PlaygroundC.ActiveThreads().ToString()+" "+playgroundLanguage.activeThreads+", "+PlaygroundC.ProcessorCount()+" "+playgroundLanguage.processors+")", EditorStyles.miniLabel);
					EditorGUILayout.PropertyField(threads, new GUIContent(playgroundLanguage.particleThreadMethod, playgroundLanguage.threadMethodDescription));
					EditorGUILayout.PropertyField(threadsTurbulence, new GUIContent(playgroundLanguage.turbulenceThreadMethod, playgroundLanguage.threadMethodDescription));
					EditorGUILayout.PropertyField(threadsSkinned, new GUIContent(playgroundLanguage.skinnedMeshThreadMethod, playgroundLanguage.threadMethodDescription));
					GUI.enabled = playgroundScriptReference.threadMethod==ThreadMethod.Automatic; 
					EditorGUILayout.PropertyField(maxThreads, new GUIContent(playgroundLanguage.maxThreads, playgroundLanguage.maxThreadsDescription));
					GUI.enabled = true;
					switch (playgroundScriptReference.threadMethod) {
					case ThreadMethod.NoThreads:EditorGUILayout.HelpBox(playgroundLanguage.threadInfo01, MessageType.Info);break;
					case ThreadMethod.OnePerSystem:EditorGUILayout.HelpBox(playgroundLanguage.threadInfo02, MessageType.Info);break;
					case ThreadMethod.OneForAll:EditorGUILayout.HelpBox(playgroundLanguage.threadInfo03, MessageType.Info);break;
					case ThreadMethod.Automatic:EditorGUILayout.HelpBox(playgroundLanguage.threadInfo04, MessageType.Info);break;
					}
					GUILayout.EndHorizontal();
					
					EditorGUILayout.Separator();
					
					// Update snapshot visibility
					if (showSnapshots.boolValue != showSnapshotsSettings) {
						UpdateSnapshots();
					}
					
					// Time reset
					GUILayout.BeginHorizontal();
					EditorGUILayout.PrefixLabel(playgroundLanguage.timeSimulation);
					if(GUILayout.Button(playgroundLanguage.reset, EditorStyles.toolbarButton, GUILayout.ExpandWidth(false))){
						PlaygroundC.TimeReset();
						for (int p = 0; p<playgroundScriptReference.particleSystems.Count; p++)
							playgroundScriptReference.particleSystems[p].Boot();
					}
					GUILayout.EndHorizontal();
					
				}
				
				
				
				playground.ApplyModifiedProperties();
				EditorGUILayout.EndVertical();
			} else {
				EditorGUILayout.HelpBox(playgroundLanguage.noPlaygroundManager, MessageType.Info);
				if(GUILayout.Button(playgroundLanguage.create, EditorStyles.toolbarButton, GUILayout.ExpandWidth(false))){
					PlaygroundC.ResourceInstantiate("Playground Manager");
				}
				EditorGUILayout.EndVertical();
			}
			
		}
		EditorGUILayout.EndVertical();
	}