Відеоінструкція зі спеціальної системи частинок Unity. Виготовлення ялинки та кривих

Цей відеопосібник про власну функцію системи частинок у Unity Engine. Ця функція дозволяє створювати та керувати даними про частинки в посібнику з системи частинок сюрікен у коді. Це дуже корисна функція, якщо вам потрібно керувати багатьма однаковими об’єктами в сцені. Це дозволяє зробити дуже хорошу оптимізацію продуктивності в деяких випадках.

Автор: Сергій Тарабан

:ad:

У цьому відеоуроці я створюю динамічні криві мотузки та приємні ефекти частинок ялинки.

Усі пов’язані матеріали ви можете знайти в цьому пакетному файлі нижче.

Завантажити файл пакета: CustomParticleSystem.unitypackage

 

Сценарій контролера частинок

Цей сценарій дозволяє вам керувати власною системою частинок.
// Скрипт ParticlesController
// Copyright (C) 2013 Сергій Тарабан 
//
// Цим надається безкоштовний дозвіл будь-якій особі, яка отримує копію цього програмного забезпечення та пов’язаних файлів документації («Програмне забезпечення»), працювати з Програмним забезпеченням без обмежень, включаючи, без обмежень, права на використання, копіювання, зміну, об’єднання, публікацію, розповсюдження, субліцензування та/або продаж копій Програмного забезпечення, а також дозволяти особам, яким надано Програмне забезпечення, робити це за таких умов:
// Наведене вище повідомлення про авторські права та це повідомлення про дозвіл мають бути включені до всіх копій або значних частин Програмного забезпечення.
// ПРОГРАМНЕ ЗАБЕЗПЕЧЕННЯ НАДАЄТЬСЯ «ЯК Є», БЕЗ БУДЬ-ЯКИХ ГАРАНТІЙ, ЯВНИХ АБО НЕПРЯМИХ, ВКЛЮЧАЮЧИ, АРЕМЕ ОБМЕЖУЮЧИСЬ, ГАРАНТІЇ ПРИДАТНОСТІ ДЛЯ ПРОДАЖУ, ВІДПОВІДНОСТІ ДЛЯ КОНКРЕТНОЇ МЕТИ ТА ВІДСУМНОСТІ ПРАВ. АВТОРИ АБО ВЛАСНИКИ АВТОРСЬКИХ ПРАВ НЕ НЕСУТЬ ВІДПОВІДАЛЬНОСТІ ЗА БУДЬ-ЯКІ ПРЕТЕНЗІЇ, ЗБИТКИ АБО ІНШУ ВІДПОВІДАЛЬНІСТЬ В наслідок КОНТРАКТНОЇ ДІЇ, ДЕЛІКТУ ЧИ В ІНШОМУ ВИПАДКУ, ЩО ВИНИКАЄ ПРОГРАМНЕ ЗАБЕЗПЕЧЕННЯ, ВИКОРИСТАННЯ АБО ІНШИМИ ОПЕРАЦІЯМИ, ЧИ У ЗВ’ЯЗКУ З НИМ ПРОГРАМНЕ ЗАБЕЗПЕЧЕННЯ.
//

за допомогою UnityEngine; використання System.Collections; використання System.Collections.Generic; за допомогою системи;

[RequireComponent(typeof(ParticleSystem))] відкритий клас ParticlesController: MonoBehaviour { публічний Колір колір = Color.white; public Vector3 segmentDir = новий Vector3(1.0f, 0, 0); відкритий float StartAngle = 0.0f;

приватна сітка m_Mesh;
private int[] m_Indices;
приватний Vector2[] m_UVs;

ParticleSystem.Particle[] частинки;
ParticleSystem mPrSystem;
int mCurrCount = 0;

static int MaxValueToHide = 10000;

private int mVertexCount = 0;
void Awake ()
{
	mPrSystem = particleSystem;
	mPrSystem.Play();
}

void Start()
{
}

void LateUpdate() {
	Оновити сегменти();
}	

public void UpdateSegments()
{
	if(particles == null) {
		повернення;
	}

	mPrSystem.SetParticles(частинки, mPrSystem.particleCount);
}

public bool IsReadyToUse()
{
	return mPrSystem.particleCount > 0;
}

public void SetVertexCount(int aCount)
{	
	if(particles == null) {
		частинки = нова ParticleSystem.Particle[mPrSystem.particleCount];
		mPrSystem.GetParticles(частинки);
	}

	if(mCurrCount > aCount) {
		for(int i = aCount; i < mPrSystem.particleCount; i++) {
			particles[i].position = new Vector3(0, MaxValueToHide, 0);
		}			
	}mCurrCount = aCount < mPrSystem.particleCount ? aCount : mPrSystem.particleCount;		 		 		if(aCount > mPrSystem.particleCount) {
		Debug.LogError("SetVertexCount(): кількість вершин > кеш частинок");
	}
}

public void SetPosition(int aIndex, Vector3 aPosition)
{
	if(aIndex < 0 || aIndex >= mCurrCount) {
		повернення;
	}	

	particles[aIndex].position = aPosition;
	if(aIndex > 0) {
		Vector3 dir = (particles[aIndex].position - particles[aIndex-1].position);
		particles[aIndex].rotation = AngleAroundAxis(segmentDir, dir) + StartAngle;
		if(aIndex == 1) {
			dir = -(particles[0].position - particles[1].position);
			particles[0].rotation = AngleAroundAxis(segmentDir, dir) + StartAngle;
		} 
	}
}

public void SetColor(int aIndex, Color aColor)
{
	if(aIndex < 0 || aIndex >= mCurrCount) {
		повернення;
	}	

	particles[aIndex].color = aColor;
}

public void SetScale(int aIndex, float scale)
{
	if(aIndex < 0 || aIndex >= mCurrCount) {
		повернення;
	}	

	particles[aIndex].size = масштаб;
}

static float AngleAroundAxis ( Vector3 dirA, Vector3 dirB ) {
	float res = Vector3.Angle(dirA, dirB);
	res *= Vector3.Dot(Vector3.up, Vector3.Cross(dirA, dirB)) < 0.0f ? -1,0f : 1,0f;
	повернення res;
}

}

 

 Скрипт синусоїдальної кривої

3D і 2D криві 3D і 2D криві
// Сценарій RopeTape
// Copyright (C) 2013 Сергій Тарабан 
//
// Цим надається безкоштовний дозвіл будь-якій особі, яка отримує копію цього програмного забезпечення та пов’язаних файлів документації («Програмне забезпечення»), працювати з Програмним забезпеченням без обмежень, включаючи, без обмежень, права на використання, копіювання, зміну, об’єднання, публікацію, розповсюдження, субліцензування та/або продаж копій Програмного забезпечення, а також дозволяти особам, яким надано Програмне забезпечення, робити це за таких умов:
// Наведене вище повідомлення про авторські права та це повідомлення про дозвіл мають бути включені до всіх копій або значних частин Програмного забезпечення.
// ПРОГРАМНЕ ЗАБЕЗПЕЧЕННЯ НАДАЄТЬСЯ «ЯК Є», БЕЗ БУДЬ-ЯКИХ ГАРАНТІЙ, ЯВНИХ АБО НЕПРЯМИХ, ВКЛЮЧАЮЧИ, АРЕМЕ ОБМЕЖУЮЧИСЬ, ГАРАНТІЇ ПРИДАТНОСТІ ДЛЯ ПРОДАЖУ, ВІДПОВІДНОСТІ ДЛЯ КОНКРЕТНОЇ МЕТИ ТА ВІДСУМНОСТІ ПРАВ. АВТОРИ АБО ВЛАСНИКИ АВТОРСЬКИХ ПРАВ НЕ НЕСУТЬ ВІДПОВІДАЛЬНОСТІ ЗА БУДЬ-ЯКІ ПРЕТЕНЗІЇ, ЗБИТКИ АБО ІНШУ ВІДПОВІДАЛЬНІСТЬ В наслідок КОНТРАКТНОЇ ДІЇ, ДЕЛІКТУ ЧИ В ІНШОМУ ВИПАДКУ, ЩО ВИНИКАЄ ПРОГРАМНЕ ЗАБЕЗПЕЧЕННЯ, ВИКОРИСТАННЯ АБО ІНШИМИ ОПЕРАЦІЯМИ, ЧИ У ЗВ’ЯЗКУ З НИМ ПРОГРАМНЕ ЗАБЕЗПЕЧЕННЯ.
//

за допомогою UnityEngine; використання System.Collections;

[RequireComponent(typeof(ParticlesController))] публічний клас RopeTape : MonoBehaviour {

ParticlesController mParticlesController = null;

плаваючий таймер = 0;
float mPhase = 0;

Амплітуда публічного плавання = 10.0f;
публічний float AmplitudeZ = 5.0f;
відкритий float XIncrement = 1.0f;
відкритий float dx = 1.0f;
відкритий float PhaseIncrement = 0,1f;
відкритий float Width = 1.0f;

// Використовуйте це для ініціалізації
void Start () {
	mParticlesController = GetComponent<ParticlesController>();
}// Оновлення викликається один раз на кадр
void Оновити () {
	mPhase += PhaseIncrement*Time.deltaTime*Mathf.PI;
	if(mParticlesController.IsReadyToUse()) 
	{
		таймер += Time.deltaTime;
		int particlesNum = mParticlesController.particleSystem.particleCount;
		mParticlesController.SetVertexCount(particlesNum);
		float t = 0;
		float fy = 0;
		float fz = 0;
		float dl = 0,01f;
		for(int i = 0; i < particlesNum; i++) 
		{
			fy = Амплітуда * Mathf.Sin(t + mPhase);
			fz = AmplitudeZ * Mathf.Sin(t + mPhase);
			mParticlesController.SetPosition(i, transform.position + new Vector3(dx*i, fy, fz));
			t += XIncrement*0,001f*Mathf.PI;
			mParticlesController.SetScale(i, Ширина);
		}
	}
}

}

 

Різдвяна ялинкова стрічка

різдвяна ялинка єдності Різдвяна ялинка з використанням спеціальної системи частинок

Я використовую цей скрипт у своєму підручнику для створення ялинки в Unity.

// Сценарій ChristmasTree
// Copyright (C) 2013 Сергій Тарабан 
//
// Цим надається безкоштовний дозвіл будь-якій особі, яка отримує копію цього програмного забезпечення та пов’язаних файлів документації («Програмне забезпечення»), працювати з Програмним забезпеченням без обмежень, включаючи, без обмежень, права на використання, копіювання, зміну, об’єднання, публікацію, розповсюдження, субліцензування та/або продаж копій Програмного забезпечення, а також дозволяти особам, яким надано Програмне забезпечення, робити це за таких умов:
// Наведене вище повідомлення про авторські права та це повідомлення про дозвіл мають бути включені до всіх копій або значних частин Програмного забезпечення.
// ПРОГРАМНЕ ЗАБЕЗПЕЧЕННЯ НАДАЄТЬСЯ «ЯК Є», БЕЗ БУДЬ-ЯКИХ ГАРАНТІЙ, ЯВНИХ АБО НЕПРЯМИХ, ВКЛЮЧАЮЧИ, АРЕМЕ ОБМЕЖУЮЧИСЬ, ГАРАНТІЇ ПРИДАТНОСТІ ДЛЯ ПРОДАЖУ, ВІДПОВІДНОСТІ ДЛЯ КОНКРЕТНОЇ МЕТИ ТА ВІДСУМНОСТІ ПРАВ. АВТОРИ АБО ВЛАСНИКИ АВТОРСЬКИХ ПРАВ НЕ НЕСУТЬ ВІДПОВІДАЛЬНОСТІ ЗА БУДЬ-ЯКІ ПРЕТЕНЗІЇ, ЗБИТКИ АБО ІНШУ ВІДПОВІДАЛЬНІСТЬ В наслідок КОНТРАКТНОЇ ДІЇ, ДЕЛІКТУ ЧИ В ІНШОМУ ВИПАДКУ, ЩО ВИНИКАЄ ПРОГРАМНЕ ЗАБЕЗПЕЧЕННЯ, ВИКОРИСТАННЯ АБО ІНШИМИ ОПЕРАЦІЯМИ, ЧИ У ЗВ’ЯЗКУ З НИМ ПРОГРАМНЕ ЗАБЕЗПЕЧЕННЯ.
//

за допомогою UnityEngine;
використання System.Collections;

публічний клас ChristmasTree : MonoBehaviour {

	ParticlesController mParticlesController = null;
	float mCurrPhaseOffset = 0.0f;

	public int MaxParticlesNum = 800;
	public bool showAllAprticles = false;
	відкритий float Height = 0.1f;
	загальнодоступний float startRadius = 0,5f;
	public bool fixedLineStep = true;
	відкритий float lineStep = 0,05f;
	відкритий float angleStep = 0,5f;
	public float particleScaleMax = 4.0f;
	public float rotateSpeed ​​= 1.0f;

	плаваючий таймер = 0;
	float mOldCangeColorTime = -10.0f;

	// Використовуйте це для ініціалізації
	void Start () {
		mParticlesController = GetComponent();
		//mParticlesController.SetVertexCount(50);
	}// Оновлення викликається один раз на кадр
	void Оновити () {
		if(mParticlesController.IsReadyToUse()) 
		{
			таймер += Time.deltaTime;
			int particlesNum = showAllAprticles? MaxParticlesNum : (int)Mathf.Lerp(1, MaxParticlesNum, timer/8.0f);
			mParticlesController.SetVertexCount(particlesNum);
			mCurrPhaseOffset += rotateSpeed ​​* Time.deltaTime;
			якщо (mCurrPhaseOffset >= 360.0f) 
			{
				mCurrPhaseOffset = 360 - mCurrPhaseOffset;
			}
			float dAlpha = 0;
			float dL = lineStep;
			float heightOffset = 0,01f;
			float offset = heightOffset;
			bool isChangeColor = ((int)timer - mOldCangeColorTime >= 1.0f);
			if(isChangeColor)
			{
				mOldCangeColorTime = таймер;
			}
			for(int i = 0; i < particlesNum; i++) 
			{
				float R = offset * startRadius;
				плаваючий кут = dAlpha + mCurrPhaseOffset;
				якщо (кут >= 360.0f) {
					кут = 360.0f - кут;
				}

				float x = R * Mathf.Cos(кут);
				float z = R * Mathf.Sin(кут);
				mParticlesController.SetPosition(i, new Vector3(x, Height*i, z) + transform.position);

				float coeff = (float)i/(float)particlesNum;
				if(isChangeColor) {
					Колір Vector3 = новий Vector3(Random.Range(0.0f, 1.0f), Random.Range(0.0f, 1.0f), Random.Range(0.0f, 1.0f));
					колір = колір.нормалізований;
					mParticlesController.SetColor(i, новий колір(color.x, color.y, color.z, 1.0f));
				}

				mParticlesController.SetScale(i, Mathf.Lerp(1.0f, particleScaleMax, coeff));

				якщо (fixedLineStep) 
				{
					dAlpha += dL * 180.0f / (Mathf.PI * R);
				} 
				інше
				{
					dAlpha += angleStep;
				}
				зсув += зсув по висоті;
			}
		}
	}
}

 Автор: Сергій Тарабан

Пов’язані публікації