* 주의 : 이 스크립트는 유니티 에디터에서만 작동하고 런타임 중에는 사용할 수 없습니다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
//This script will only work in editor mode. You cannot adjust the scale dynamically in-game!
using UnityEngine;
using System.Collections;
 
#if UNITY_EDITOR 
using UnityEditor;
#endif
 
[ExecuteInEditMode]
public class ParticleScaler : MonoBehaviour
{
    public float particleScale = 1.0f;
    public bool alsoScaleGameobject = true;
 
    float prevScale;
 
    void Start()
    {
        prevScale = particleScale;
    }
 
    void Update()
    {
#if UNITY_EDITOR
        //check if we need to update
        if (prevScale != particleScale && particleScale > 0)
        {
            if (alsoScaleGameobject)
                transform.localScale = new Vector3(particleScale, particleScale, particleScale);
 
            float scaleFactor = particleScale / prevScale;
 
            //scale legacy particle systems
            ScaleLegacySystems(scaleFactor);
 
            //scale shuriken particle systems
            ScaleShurikenSystems(scaleFactor);
 
            //scale trail renders
            ScaleTrailRenderers(scaleFactor);
 
            prevScale = particleScale;
        }
#endif
    }
 
    void ScaleShurikenSystems(float scaleFactor)
    {
#if UNITY_EDITOR
        //get all shuriken systems we need to do scaling on
        ParticleSystem[] systems = GetComponentsInChildren<ParticleSystem>();
 
        foreach (ParticleSystem system in systems)
        {
            system.startSpeed *= scaleFactor;
            system.startSize *= scaleFactor;
            system.gravityModifier *= scaleFactor;
 
            //some variables cannot be accessed through regular script, we will acces them through a serialized object
            SerializedObject so = new SerializedObject(system);
 
            //unity 4.0 and onwards will already do this one for us
#if UNITY_3_5
            so.FindProperty("ShapeModule.radius").floatValue *= scaleFactor;
            so.FindProperty("ShapeModule.boxX").floatValue *= scaleFactor;
            so.FindProperty("ShapeModule.boxY").floatValue *= scaleFactor;
            so.FindProperty("ShapeModule.boxZ").floatValue *= scaleFactor;
#endif
 
            so.FindProperty("VelocityModule.x.scalar").floatValue *= scaleFactor;
            so.FindProperty("VelocityModule.y.scalar").floatValue *= scaleFactor;
            so.FindProperty("VelocityModule.z.scalar").floatValue *= scaleFactor;
            so.FindProperty("ClampVelocityModule.magnitude.scalar").floatValue *= scaleFactor;
            so.FindProperty("ClampVelocityModule.x.scalar").floatValue *= scaleFactor;
            so.FindProperty("ClampVelocityModule.y.scalar").floatValue *= scaleFactor;
            so.FindProperty("ClampVelocityModule.z.scalar").floatValue *= scaleFactor;
            so.FindProperty("ForceModule.x.scalar").floatValue *= scaleFactor;
            so.FindProperty("ForceModule.y.scalar").floatValue *= scaleFactor;
            so.FindProperty("ForceModule.z.scalar").floatValue *= scaleFactor;
            so.FindProperty("ColorBySpeedModule.range").vector2Value *= scaleFactor;
            so.FindProperty("SizeBySpeedModule.range").vector2Value *= scaleFactor;
            so.FindProperty("RotationBySpeedModule.range").vector2Value *= scaleFactor;
 
            so.ApplyModifiedProperties();
        }
#endif
    }
 
    void ScaleLegacySystems(float scaleFactor)
    {
#if UNITY_EDITOR
        //get all emitters we need to do scaling on
        ParticleEmitter[] emitters = GetComponentsInChildren<ParticleEmitter>();
 
        //get all animators we need to do scaling on
        ParticleAnimator[] animators = GetComponentsInChildren<ParticleAnimator>();
 
        //apply scaling to emitters
        foreach (ParticleEmitter emitter in emitters)
        {
            emitter.minSize *= scaleFactor;
            emitter.maxSize *= scaleFactor;
            emitter.worldVelocity *= scaleFactor;
            emitter.localVelocity *= scaleFactor;
            emitter.rndVelocity *= scaleFactor;
 
            //some variables cannot be accessed through regular script, we will acces them through a serialized object
            SerializedObject so = new SerializedObject(emitter);
 
            so.FindProperty("m_Ellipsoid").vector3Value *= scaleFactor;
            so.FindProperty("tangentVelocity").vector3Value *= scaleFactor;
            so.ApplyModifiedProperties();
        }
 
        //apply scaling to animators
        foreach (ParticleAnimator animator in animators)
        {
            animator.force *= scaleFactor;
            animator.rndForce *= scaleFactor;
        }
#endif
    }
 
    void ScaleTrailRenderers(float scaleFactor)
    {
        //get all animators we need to do scaling on
        TrailRenderer[] trails = GetComponentsInChildren<TrailRenderer>();
 
        //apply scaling to animators
        foreach (TrailRenderer trail in trails)
        {
            trail.startWidth *= scaleFactor;
            trail.endWidth *= scaleFactor;
        }
    }
}
 
cs



ParticleScaler.cs


위 스크립트를 ParticleSystem 오브젝트에 갖다붙이고



    



인스펙터에서 ParticleScale 변수를 조절해주면


모든 설정값들이 스케일 1 기준으로 딱딱딱 바뀌는 것을 볼 수 있습니다.


왼쪽은 원본 파티클이고 오른쪽은 ParticleScaler.cs 로 스케일 2배한 파티클입니다.


참 편리한 녀석이죠?


유용하게 쓰세요!





코드 출처 : https://github.com/hypno2000/starcontrol/blob/master/Assets/ParticleScaler/ParticleScaler.cs



+ Recent posts