开启辅助访问
 找回密码
 注册帐号

扫一扫,访问微社区

蛮牛译馆

关注:553

当前位置:游戏蛮牛 技术专区 蛮牛译馆

查看: 1744|回复: 18

[Unity教程] Unity开发技巧:使用脚本修改粒子

[复制链接]  [移动端链接]
排名
7711
昨日变化
5

213

主题

250

帖子

1362

积分

Rank: 15Rank: 15Rank: 15Rank: 15Rank: 15Rank: 15

UID
159865
好友
9
蛮牛币
3259
威望
0
注册时间
2016-8-1
在线时间
597 小时
最后登录
2017-8-17

蛮牛译员

发表于 2017-7-12 13:34:16 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?注册帐号

x
本帖最后由 manew_JR 于 2017-7-12 13:37 编辑

Unity开发技巧:使用脚本修改粒子
01.jpg
Unity 3D提供了一个巨大的API,它提供了操纵游戏中绝大多数对象的方法。然而,有些特性并不如您所希望的那样强大。举个例子,例如,部分系统类。比方说,你有一个粒子系统。您需要使用脚本修改粒子系统的形状半径。在快速浏览一下Unity  ParticleSystem的文档之后,您可以假设您可以使用分区ParticleSystem.shape.radius来改变粒子系统的半径。然而,当我们试图这样做的时候,问题就出现了。Unity给了我们一个错误,告诉我们这个部分。半径是只读的。这意味着它不能通过代码进行修改(至少在我看来是这样)。我们现在如何解决?这是我提出的解决方案。


如何使用脚本修改Unity中的粒子
以下是我为解决这个问题所采取的步骤。让我们开始使用序列化的对象。

使用序列化对象
老实说,我没有一个很好的方法来描述SerializedObject类。我能总结的最好方法是,它允许您访问通常无法访问或修改的组件模块。因此,我们可以使用这个类来访问我们的粒子系统的形状模块并对它做出改变。让我们来看看如何做到这一点。我假设你们已经建立了一个Unity项目包括一些你们想要操作的粒子系统。在我的例子中,我使用的是一个锥形的粒子系统。

1。选择您的ParticleSystem部分,并添加一个新的C#脚本,给它命名为ParticleScript.
2。将这些代码复制到您的脚本中(我已经尽可能多地注释了这段代码):

下面是代码:

[C#] 纯文本查看 复制代码
using UnityEngine;

using System.Collections;

using UnityEditor; // Need this to access SerializedObject

public class ParticleScript : MonoBehaviour {

    SerializedObject thisParticle; // This will be our modifiable particle system

    bool isChanging; // Used as a flag for a coroutine

    //Set these values in the inspector. Will modify angle and radius of Particle System

    public float MAX_ANGLE, MIN_ANGLE, MAX_RADIUS, MIN_RADIUS, transitionSpeed;

    void Start ()

    {

        /* Initialize and Assign thisParticle as a SerializedObject that takes properties

         * from the ParticleSystem attached to this game object. */

        thisParticle = new SerializedObject (GetComponent<ParticleSystem>());

        thisParticle.FindProperty("ShapeModule.radius").floatValue = MAX_RADIUS;

        thisParticle.FindProperty("ShapeModule.angle").floatValue = MAX_ANGLE;

        thisParticle.ApplyModifiedProperties(); // This basically updates the particles with any changes that have been made

        isChanging = false;

    }

    void Update ()

    {

        if(Input.GetKeyDown(KeyCode.R) && !isChanging)

            StartCoroutine(ChangeRadius());

        else if(Input.GetKeyDown(KeyCode.A) && !isChanging)

            StartCoroutine(ChangeAngle());

    }

    IEnumerator ChangeRadius()

    {

        isChanging = true; // set true so user can't spam the coroutine

        //This code will make the radius smaller if the radius is at its maximum already

        if(thisParticle.FindProperty("ShapeModule.radius").floatValue >= MAX_RADIUS)

        {

            while(thisParticle.FindProperty("ShapeModule.radius").floatValue > MIN_RADIUS)

            {

                //grab the radius value and subtract it

                thisParticle.FindProperty("ShapeModule.radius").floatValue -= Time.deltaTime * transitionSpeed;

                thisParticle.ApplyModifiedProperties(); // This is used to apply the new radius value

                yield return null;

            }

        }

        //This code will make radius larger if radius is already at its minimum

        else if(thisParticle.FindProperty("ShapeModule.radius").floatValue <= MIN_RADIUS)

        {

            while(thisParticle.FindProperty("ShapeModule.radius").floatValue < MAX_RADIUS)

            {

                //grab the radius variable and increase it

                thisParticle.FindProperty("ShapeModule.radius").floatValue += Time.deltaTime * transitionSpeed;

                thisParticle.ApplyModifiedProperties(); // Apply new radius value

                yield return null;

            }

        }

        isChanging = false; // set to false so user can input again.

        yield return null;

    }

    IEnumerator ChangeAngle()

    {

        isChanging = true;

        //This code will make the angle smaller if the angle is at its maximum already

        if(thisParticle.FindProperty("ShapeModule.angle").floatValue >= MAX_ANGLE)

        {

            while(thisParticle.FindProperty("ShapeModule.angle").floatValue > MIN_ANGLE)

            {

                //grab angle value and subtract it

                thisParticle.FindProperty("ShapeModule.angle").floatValue -= Time.deltaTime * (transitionSpeed * 2);

                thisParticle.ApplyModifiedProperties(); // apply new value to angle

                yield return null;

            }

        }

        //This code will make angle larger if angle is already at its minimum

        else if(thisParticle.FindProperty("ShapeModule.angle").floatValue <= MIN_ANGLE)

        {

            while(thisParticle.FindProperty("ShapeModule.angle").floatValue < MAX_ANGLE)

            {

                // grab angle value and increase it

                thisParticle.FindProperty("ShapeModule.angle").floatValue += Time.deltaTime * (transitionSpeed * 2);

                thisParticle.ApplyModifiedProperties(); // apply new value to angle

                yield return null;

            }

        }

        isChanging = false;

        yield return null;

    }

}


使用序列化对象的下一步步骤:
现在您已经有了代码,接下来要做的是:

1。单击层次结构中的粒子系统,并在检查器中找到该分区的对象。您将注意到几个公共变量。为了快速测试,将您的变量设置为和我一样的:

02.png

2。现在,如果你运行你的游戏,按R或A,你应该看到半径或角度的变化,这取决于你按哪个键。请注意,由于我编写代码的方式,您只能一次更改一个变量。你可以很容易地修改它,这样你就可以同时运行两个coroutines。

我如何知道要修改的模块的名称?
当我第一次把序列化的对象弄乱时,我很难理解“ShapeModule.radius”从哪里来。文档包含这个字符串在SerializedObject.FindProperty()函数内部,但它没有解释从哪里得到该字符串。我发现,如果您在Unity中切换到Debug视图,您将能够看到与组件相关联的属性列表。要打开Debug视图,请单击检查器右上角的第三行图标,并选择“Debug”:

03.png

然后你会发现所有的组件分解成更复杂的部分:
04.png

您将注意到“Shape Module” 部分。如果你展开它,你会看到构成形状模块的所有变量,其中一些不会出现在正常视图中。在这里,您可以找到可以操作的变量。

05.png

现在,我可以说thisParticle.FindProperty(“ShapeModule.radius”)。floatValue = Time.deltaTime;

一种奇怪的格式是在“ShapeModule.radius”中。半径变量名是不可以大写的,即使它显示在检查器中的形状模块组件中。我试着用一个大写的半径变量名来执行我的代码,但这是行不通的。考虑到这一点,我将假定模块名称在必要时是大写的,但该模块的成员不是。

最后,当使用浮点数,布尔值等依赖于变量的类型。解决这个问题的最简单方法是在检查器中上下拖动这个值,看看它是否有小数。如果它有小数,则需要使用浮动值来修改值。如果没有,那么您将使用intValue。同样地,如果一个值显示为真或假,那么您将需要使用布尔值。因此,如果我在检查器中拖放半径,很快就会发现这个值中有小数。因此,我将希望使用
SerializedObject.FindProperty(“ShapeModule.radius”浮点数来修改该值。

结论
希望这篇文章能帮助你理解你在游戏中控制对象的其他方法。如果您发现Unity自身的库对您想要做的事情没有足够的能力解决,那么您可能需要尝试创建一个序列化的对象来访问您所需要的变量。



原文标题:Unity Tip: Use Scripts to Modify Particles
原文链接:https://www.studica.com/blog/unity-tip-use-scripts-to-modify-particles





       蛮牛译林军福利多多哦!

扫描下方二维码关注游戏蛮牛官方微信~每日都有精选干货与你分享呦~
153151xf2z3s2w76q27z72.png.thumb.jpg









评分

参与人数 1鲜花 +3 收起 理由
sunkai + 3 很给力!

查看全部评分

本帖被以下淘专辑推荐:


回复

使用道具 举报

7日久生情
1622/5000
排名
861
昨日变化
1

4

主题

122

帖子

1622

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
29196
好友
0
蛮牛币
2384
威望
0
注册时间
2014-6-11
在线时间
573 小时
最后登录
2017-7-30
发表于 2017-7-12 17:13:01 | 显示全部楼层
这篇完全瞎扯.//不是针对译者,原博主瞎扯,
                     //译者无私无偿翻译外国文献供我们学习,值得称赞.
                    // 正确操作 ParticleSystem 的方式如下
无法直接更改 是因为他用了属性访问器,只有get权限 ,没有set权限
但是把它保存在一个临时变量里就行了.
void Start () {
        ParticleSystem ps = GetComponent<ParticleSystem>();
        var sh = ps.shape;
        sh.shapeType = ParticleSystemShapeType.Sphere;  //改变发射器形状
        sh.radius = 3;                                                             //改变发射器半径
    }

学习的时候优先先看官方文档  文档里都有正确的操作方式 文档链接
https://docs.unity3d.com/ScriptReference/ParticleSystem-shape.html
//大家共同进步

回复 支持 3 反对 0

使用道具 举报

排名
20829
昨日变化
20

2

主题

11

帖子

41

积分

Rank: 1

UID
189772
好友
0
蛮牛币
2
威望
0
注册时间
2016-12-5
在线时间
14 小时
最后登录
2017-8-14
发表于 2017-7-12 17:41:37 | 显示全部楼层
什么时候Unity能够去除编程障碍,而将重点都放在设计上呢?

回复 支持 反对

使用道具 举报

6蛮牛粉丝
1121/1500
排名
2420
昨日变化
8

0

主题

385

帖子

1121

积分

Rank: 6Rank: 6Rank: 6

UID
164723
好友
0
蛮牛币
2266
威望
0
注册时间
2016-8-29
在线时间
288 小时
最后登录
2017-8-17
发表于 2017-7-13 09:28:50 | 显示全部楼层

回复

使用道具 举报

5熟悉之中
793/1000
排名
4713
昨日变化
43

0

主题

420

帖子

793

积分

Rank: 5Rank: 5

UID
156480
好友
0
蛮牛币
1249
威望
0
注册时间
2016-7-12
在线时间
149 小时
最后登录
2017-8-17
发表于 2017-7-13 10:29:22 | 显示全部楼层
看不懂  

回复 支持 反对

使用道具 举报

5熟悉之中
836/1000
排名
3038
昨日变化
3

11

主题

123

帖子

836

积分

Rank: 5Rank: 5

UID
83836
好友
2
蛮牛币
965
威望
0
注册时间
2015-3-24
在线时间
316 小时
最后登录
2017-8-17
QQ
发表于 2017-7-13 13:54:49 | 显示全部楼层
wonkmy 发表于 2017-7-12 17:41
什么时候Unity能够去除编程障碍,而将重点都放在设计上呢?

那我要转行了
[发帖际遇]: NEW小三 乐于助人,奖励 1 蛮牛币. 幸运榜 / 衰神榜

回复 支持 反对

使用道具 举报

3偶尔光临
173/300
排名
7711
昨日变化
5

0

主题

21

帖子

173

积分

Rank: 3Rank: 3Rank: 3

UID
32447
好友
1
蛮牛币
346
威望
0
注册时间
2014-7-4
在线时间
42 小时
最后登录
2017-7-14
发表于 2017-7-13 15:17:23 | 显示全部楼层
我来就看看,不说话

回复 支持 反对

使用道具 举报

2初来乍到
124/150
排名
10086
昨日变化
7

2

主题

22

帖子

124

积分

Rank: 2Rank: 2

UID
224492
好友
2
蛮牛币
157
威望
0
注册时间
2017-5-31
在线时间
30 小时
最后登录
2017-8-16
发表于 2017-7-13 21:33:32 | 显示全部楼层
厉害了 赞赞赞

回复

使用道具 举报

3偶尔光临
288/300
排名
9935
昨日变化
144

1

主题

179

帖子

288

积分

Rank: 3Rank: 3Rank: 3

UID
119154
好友
0
蛮牛币
450
威望
0
注册时间
2015-8-21
在线时间
36 小时
最后登录
2017-8-16
发表于 2017-7-13 22:01:46 | 显示全部楼层
谢谢楼主大大。

回复

使用道具 举报

5熟悉之中
528/1000
排名
6461
昨日变化
2

0

主题

266

帖子

528

积分

Rank: 5Rank: 5

UID
209046
好友
0
蛮牛币
839
威望
0
注册时间
2017-3-30
在线时间
116 小时
最后登录
2017-8-11
发表于 2017-7-15 09:44:59 | 显示全部楼层
很棒

回复

使用道具 举报

3偶尔光临
197/300
排名
8460
昨日变化
107

3

主题

58

帖子

197

积分

Rank: 3Rank: 3Rank: 3

UID
224651
好友
0
蛮牛币
650
威望
0
注册时间
2017-6-1
在线时间
42 小时
最后登录
2017-8-16
发表于 2017-7-17 08:07:42 | 显示全部楼层
收藏一波

回复

使用道具 举报

4四处流浪
354/500
排名
7386
昨日变化
72

0

主题

136

帖子

354

积分

Rank: 4

UID
206337
好友
2
蛮牛币
792
威望
0
注册时间
2017-6-5
在线时间
96 小时
最后登录
2017-8-17
发表于 2017-7-17 09:14:03 | 显示全部楼层
这么做修改angle没问题,但是修改radio为啥会报一个type is not a supported int value
UnityEditor.SerializedProperty:set_intValue(Single)的错误,但是我并不能在unity里找到single类型的....
[发帖际遇]: 一个袋子砸在了 懒人起烂名 头上,懒人起烂名 赚了 1 蛮牛币. 幸运榜 / 衰神榜

回复 支持 反对

使用道具 举报

排名
11493
昨日变化
11

0

主题

10

帖子

79

积分

Rank: 2Rank: 2

UID
230204
好友
0
蛮牛币
175
威望
0
注册时间
2017-7-4
在线时间
15 小时
最后登录
2017-8-17
发表于 2017-7-17 10:08:00 | 显示全部楼层
看着很牛逼

回复

使用道具 举报

5熟悉之中
989/1000
排名
2361
昨日变化
14

2

主题

90

帖子

989

积分

Rank: 5Rank: 5

UID
81708
好友
1
蛮牛币
1029
威望
0
注册时间
2015-3-19
在线时间
443 小时
最后登录
2017-8-16
发表于 2017-7-17 10:17:15 | 显示全部楼层
bitcht 发表于 2017-7-12 17:13
这篇完全瞎扯.//不是针对译者,原博主瞎扯,
                     //译者无私无偿翻译外国文献供我们学习,值 ...

确实好像多此一举。但是谨慎的说是不是多了一个思路。

回复 支持 反对

使用道具 举报

5熟悉之中
754/1000
排名
4677
昨日变化
29

12

主题

414

帖子

754

积分

Rank: 5Rank: 5

UID
206456
好友
1
蛮牛币
1159
威望
0
注册时间
2017-2-14
在线时间
154 小时
最后登录
2017-8-17
发表于 2017-7-17 10:24:14 | 显示全部楼层

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册帐号

本版积分规则

快速回复 返回顶部 返回列表