这是Unity3D的一个例子:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ParticleLauncher : MonoBehaviour {
public ParticleSystem particleLauncher;
public ParticleSystem splatterParticles;
public Gradient particleColorGradient;
public ParticleDecalPool splatDecalPool;
List<ParticleCollisionEvent> collisionEvents;
void Start ()
{
collisionEvents = new List<ParticleCollisionEvent> ();
}
void OnParticleCollision(GameObject other)
{
ParticlePhysicsExtensions.GetCollisionEvents (particleLauncher, other, collisionEvents);
for (int i = 0; i < collisionEvents.Count; i++)
{
splatDecalPool.ParticleHit (collisionEvents [i], particleColorGradient);
EmitAtLocation (collisionEvents[i]);
}
}
void EmitAtLocation(ParticleCollisionEvent particleCollisionEvent)
{
splatterParticles.transform.position = particleCollisionEvent.intersection;
splatterParticles.transform.rotation = Quaternion.LookRotation (particleCollisionEvent.normal);
ParticleSystem.MainModule psMain = splatterParticles.main;
psMain.startColor = particleColorGradient.Evaluate (Random.Range (0f, 1f));
splatterParticles.Emit (1);
}
void Update ()
{
if (Input.GetButton ("Fire1"))
{
ParticleSystem.MainModule psMain = particleLauncher.main;
psMain.startColor = particleColorGradient.Evaluate (Random.Range (0f, 1f));
particleLauncher.Emit (1);
}
}
}
您可以在此处找到其余代码:
我的问题是关于EmitAtLocation()函数,在这个函数里面我们有
ParticleSystem.MainModule psMain = splatterParticles.main;
MainModule是一个结构,我知道C#中的结构通过值而不是通过引用传递,但是这里我们有psMain变量,如果我们对该变量进行任何更改,splatterParticles.main将受到影响,它看起来像结构已经通过引用传递,是可能在C#中还是我错过了什么?
答案 0 :(得分:4)
幕后有一个技巧。
首先,让我们看一下ParticleSystem.main
属性:
public ParticleSystem.MainModule main
{
get
{
return new ParticleSystem.MainModule(this);
}
}
我们看到它返回一个新的MainModule
结构,它以this
为参数。
然后让我们看一下MainModule构造函数:
private ParticleSystem m_ParticleSystem;
internal MainModule(ParticleSystem particleSystem)
{
this.m_ParticleSystem = particleSystem;
}
所以我们保持对ParticleSystem的引用(注意ParticleSystem是一个类)。
最后,startColor
属性:
public ParticleSystem.MinMaxGradient startColor
{
set
{
ParticleSystem.MainModule.SetStartColor(this.m_ParticleSystem, ref value);
}
get
{
ParticleSystem.MinMaxGradient gradient = new ParticleSystem.MinMaxGradient();
ParticleSystem.MainModule.GetStartColor(this.m_ParticleSystem, ref gradient);
return gradient;
}
}
简而言之,您的ParticleSystem.MainModule
对象实际上并不存储任何内容。它只是全局共享ParticleSystem
对象的包装器。每当您访问ParticleSystem.MainModule
上的媒体资源时,它都会直接修改共享的ParticleSystem
。因此,你看到的混乱行为。
答案 1 :(得分:3)
考虑使用ref
关键字。有了它,您可以通过引用传递任何值类型参数(而不是通过复制)。
https://www.dotnetperls.com/ref
参考。 ref参数作为引用传递,而不是值。这意味着您可以在被调用的方法中分配参数,并在调用站点分配该参数。
还要考虑阅读out keyword
出。此C#关键字表示引用参数。有时候方法必须返回多个值,而不是存储类状态。
不要在他们之间感到困惑: