简体   繁体   English

无法引用在不同脚本中作为组件加载到游戏对象上的脚本,该脚本也作为组件加载到同一游戏对象上

[英]Can't reference a script that is loaded as a component on a GameObject in a different script that is also loaded as a component on same GameObject

I'm using a plugin to put a built Volumetric Light Beam into my scene.我正在使用插件将内置的体积光束放入我的场景中。

I'd like to control the intensity of the light through another script that is triggering the intensity to go up and down (visually looking as if it's turning off and on, in other words, flickering).我想通过另一个触发强度上下的脚本来控制光的强度(在视觉上看起来好像它正在关闭和打开,换句话说,闪烁)。

My desired outcome is essentially turning the light off and on but without disabling the object so I can have the light animate its rotation while the light intensity is controlled by a separate script.我想要的结果基本上是关闭和打开灯光,但不禁用对象,这样我就可以让灯光为其旋转设置动画,同时灯光强度由单独的脚本控制。

I'm fairly new to coding and haven't been writing any code for the last 3 months so it's a bit confusing just getting back in.我对编码还很陌生,并且在过去的 3 个月里没有编写任何代码,所以刚回来有点困惑。

I have a light GameObject called Spotlight and Beam.我有一个名为 Spotlight 和 Beam 的轻型游戏对象。 Loaded on that GameObject is the Volumetric Dust Particles script (along with the other related scripts from the plugin).加载在该游戏对象上的是 Volumetric Dust Particles 脚本(以及插件中的其他相关脚本)。 Heres an image of that继承人的形象

I have another script loaded on this object called SpotlightFlicker.我在这个对象上加载了另一个脚本,称为 SpotlightFlicker。 I'd like to use that to control the intensity property (that you can see is highlighted in the image above).我想用它来控制强度属性(您可以看到在上图中突出显示)。

I thought that if the scripts were in the same folder(which I moved all the plugin scripts to the Unity scripts folder for this), I'd be able to reference the other script that is loaded as a component on the same GameObject using something like我认为如果脚本在同一个文件夹中(为此,我将所有插件脚本移动到 Unity 脚本文件夹),我就可以使用某些东西引用作为组件加载到同一个 GameObject 上的另一个脚本喜欢

public VolumetricLightBeam FlickeringSpotlight;公共 VolumetricLightBeam 闪烁聚光灯;

however, this appears:但是,这似乎是:

The type or namespace name 'VolumetricLightBeam' could not be found (are you missing a using directive or an assembly reference?) [Assembly-CSharp]csharp(CS0246)找不到类型或命名空间名称“VolumetricLightBeam”(您是否缺少 using 指令或程序集引用?) [Assembly-CSharp]csharp(CS0246)

The VolumetricLightBeam script is written quite differently than I've seen so far using Unity (in my beginner stages). VolumetricLightBeam 脚本的编写方式与我目前使用 Unity 看到的(在我的初学者阶段)完全不同。

using UnityEngine;

namespace VLB
{
    [ExecuteInEditMode]
    [DisallowMultipleComponent]
    [RequireComponent(typeof(VolumetricLightBeam))]
    [HelpURL(Consts.Help.UrlDustParticles)]
    public class VolumetricDustParticles : MonoBehaviour
    {
        public const string ClassName = "VolumetricDustParticles";

        /// <summary>
        /// Max alpha of the particles
        /// </summary>
        [Range(0f, 1f)]
        public float alpha = Consts.DustParticles.AlphaDefault;

        /// <summary>
        /// Max size of the particles
        /// </summary>
        [Range(0.0001f, 0.1f)]
        public float size = Consts.DustParticles.SizeDefault;

        /// <summary>
        /// Direction of the particles.
        /// </summary>
        public ParticlesDirection direction = Consts.DustParticles.DirectionDefault;

        /// <summary>
        /// Movement speed of the particles.
        /// </summary>
        public Vector3 velocity = Consts.DustParticles.VelocityDefault;

        [System.Obsolete("Use 'velocity' instead")]
        public float speed = 0.03f;

        /// <summary>
        /// Control how many particles are spawned. The higher the density, the more particles are spawned, the higher the performance cost is.
        /// </summary>
        public float density = Consts.DustParticles.DensityDefault;

        /// <summary>
        /// The distance range (from the light source) where the particles are spawned.
        /// - Min bound: the higher it is, the more the particles are spawned away from the light source.
        /// - Max bound: the lower it is, the more the particles are gathered near the light source.
        /// </summary>
        [MinMaxRange(0.0f, 1.0f)]
        public MinMaxRangeFloat spawnDistanceRange = Consts.DustParticles.SpawnDistanceRangeDefault;

        [System.Obsolete("Use 'spawnDistanceRange' instead")]
        public float spawnMinDistance = 0f;

        [System.Obsolete("Use 'spawnDistanceRange' instead")]
        public float spawnMaxDistance = 0.7f;

        /// <summary>
        /// Enable particles culling based on the distance to the Main Camera.
        /// We highly recommend to enable this feature to keep good runtime performances.
        /// </summary>
        public bool cullingEnabled = Consts.DustParticles.CullingEnabledDefault;

        /// <summary>
        /// If culling is enabled, the particles will not be rendered if they are further than cullingMaxDistance to the Main Camera.
        /// </summary>
        public float cullingMaxDistance = Consts.DustParticles.CullingMaxDistanceDefault;

        /// <summary>
        /// Is the particle system currently culled (no visible) because too far from the main camera?
        /// </summary>
        public bool isCulled { get; private set; }


        [SerializeField] float m_AlphaAdditionalRuntime = 1.0f;
        public float alphaAdditionalRuntime
        {
            get { return m_AlphaAdditionalRuntime; }
            set { if (m_AlphaAdditionalRuntime != value) { m_AlphaAdditionalRuntime = value; m_RuntimePropertiesDirty = true; } }
        }

        public bool particlesAreInstantiated { get { return m_Particles; } }
        public int particlesCurrentCount { get { return m_Particles ? m_Particles.particleCount : 0; } }
        public int particlesMaxCount { get { return m_Particles ? m_Particles.main.maxParticles : 0; } }
        ParticleSystem m_Particles = null;
        ParticleSystemRenderer m_Renderer = null;
        Material m_Material = null;
        Gradient m_GradientCached = new Gradient();
        bool m_RuntimePropertiesDirty = true;


        /// <summary>Cached version of Camera.main, for performance reasons</summary>
        public Camera mainCamera
        {
            get
            {
                if (!ms_MainCamera)
                {
                    ms_MainCamera = Camera.main;
                    if (!ms_MainCamera && !ms_NoMainCameraLogged)
                    {
                        Debug.LogErrorFormat(gameObject, "In order to use '" + VolumetricDustParticles.ClassName + "' culling, you must have a MainCamera defined in your scene.");
                        ms_NoMainCameraLogged = true;
                    }
                }

                return ms_MainCamera;
            }
        }

        // Cache the main camera, because accessing Camera.main at each frame is very bad performance-wise
        static bool ms_NoMainCameraLogged = false;
        static Camera ms_MainCamera = null;

#if UNITY_EDITOR
        void OnValidate()
        {
            density = Mathf.Clamp(density, Consts.DustParticles.DensityMin, Consts.DustParticles.DensityMax);
            cullingMaxDistance = Mathf.Max(cullingMaxDistance, Consts.DustParticles.CullingMaxDistanceMin);
            Play(); // support instant refresh when modifying properties from inspector
        }
#endif // UNITY_EDITOR

        VolumetricLightBeam m_Master = null;

        void Start()
        {
            isCulled = false;

            m_Master = GetComponent<VolumetricLightBeam>();
            Debug.Assert(m_Master);
            HandleBackwardCompatibility(m_Master._INTERNAL_pluginVersion, Version.Current);

            InstantiateParticleSystem();

            SetActiveAndPlay();
        }

        void InstantiateParticleSystem()
        {
            // If we duplicate (from Editor and Playmode) the VLB, the children are also duplicated (like the dust particles)
            // we have to make sure to properly destroy them before creating our proper procedural particle instance.
            var slaves = GetComponentsInChildren<ParticleSystem>(true);
            for (int i = slaves.Length - 1; i >= 0; --i)
                DestroyImmediate(slaves[i].gameObject);

            m_Particles = Config.Instance.NewVolumetricDustParticles();

            if (m_Particles)
            {
#if UNITY_EDITOR
                if (m_Master)
                {
                    UnityEditor.GameObjectUtility.SetStaticEditorFlags(m_Particles.gameObject, m_Master.GetStaticEditorFlagsForSubObjects());
                    m_Particles.gameObject.SetSameSceneVisibilityStatesThan(m_Master.gameObject);
                }
#endif // UNITY_EDITOR
                m_Particles.transform.SetParent(transform, false);
                m_Particles.transform.localRotation = m_Master.beamInternalLocalRotation;

                m_Renderer = m_Particles.GetComponent<ParticleSystemRenderer>();
                Debug.Assert(m_Renderer);

                m_Material = new Material(m_Renderer.sharedMaterial);
                Debug.Assert(m_Material);
                m_Renderer.material = m_Material;
            }
        }

        void OnEnable()
        {
            SetActiveAndPlay();
        }
        
        void SetActive(bool active)
        {
            if (m_Particles) m_Particles.gameObject.SetActive(active);
        }

        void SetActiveAndPlay()
        {
            SetActive(true);
            Play();
        }

        void Play()
        {
            if (m_Particles)
            {
                SetParticleProperties();
                m_Particles.Simulate(0f);
                m_Particles.Play(true);
            }
        }

        void OnDisable()
        {
            SetActive(false);
        }

        void OnDestroy()
        {
            if (m_Particles)
            {
                DestroyImmediate(m_Particles.gameObject); // Make sure to delete the GAO
                m_Particles = null;
            }

            if (m_Material)
            {
                DestroyImmediate(m_Material);
                m_Material = null;
            }
        }

        void Update()
        {
#if UNITY_EDITOR
            if(!Application.isPlaying)
            {
                if (m_Particles == null)
                    InstantiateParticleSystem();

                Play();
            }
            else
#endif // UNITY_EDITOR
            {
                UpdateCulling();

                Debug.Assert(m_Master);
                if (m_Master.trackChangesDuringPlaytime)
                    SetParticleProperties();
            }

            if (m_RuntimePropertiesDirty && m_Material != null)
            {
                m_Material.SetColor(ShaderProperties.ParticlesTintColor, new Color(1.0f, 1.0f, 1.0f, alphaAdditionalRuntime));
                m_RuntimePropertiesDirty = false;
            }
        }

        void SetParticleProperties()
        {
            if (m_Particles && m_Particles.gameObject.activeSelf)
            {
                var thickness = Mathf.Clamp01(1 - (m_Master.fresnelPow / Consts.Beam.FresnelPowMaxValue));
                
                var coneLength = m_Master.fallOffEnd * (spawnDistanceRange.maxValue - spawnDistanceRange.minValue);
                var ratePerSec = coneLength * density;
                int maxParticles = (int)(ratePerSec * 4);

                var main = m_Particles.main;

                var startLifetime = main.startLifetime;
                startLifetime.mode = ParticleSystemCurveMode.TwoConstants;
                startLifetime.constantMin = 4f;
                startLifetime.constantMax = 6f;
                main.startLifetime = startLifetime;

                var startSize = main.startSize;
                startSize.mode = ParticleSystemCurveMode.TwoConstants;
                startSize.constantMin = size * 0.9f;
                startSize.constantMax = size * 1.1f;
                main.startSize = startSize;
                
                var startColor = main.startColor;

                if (m_Master.usedColorMode == ColorMode.Flat)
                {
                    startColor.mode = ParticleSystemGradientMode.Color;
                    var colorMax = m_Master.color;
                    colorMax.a *= alpha;
                    startColor.color = colorMax;
                }
                else
                {
                    startColor.mode = ParticleSystemGradientMode.Gradient;

                    // Duplicate gradient and apply alpha
                    var gradientRef = m_Master.colorGradient;
                    var colorKeys = gradientRef.colorKeys;
                    var alphaKeys = gradientRef.alphaKeys;

                    for(int i=0; i< alphaKeys.Length; ++i)
                        alphaKeys[i].alpha *= alpha;

                    Debug.Assert(m_GradientCached != null);
                    m_GradientCached.SetKeys(colorKeys, alphaKeys);
                    startColor.gradient = m_GradientCached;
                }
                main.startColor = startColor;

                {
                    var startSpeed = main.startSpeed;
                    startSpeed.constant = (direction == ParticlesDirection.Random) ? Mathf.Abs(velocity.z) : 0.0f;
                    main.startSpeed = startSpeed;
                }

                {
                    var velocityOverLifetime = m_Particles.velocityOverLifetime;
                    velocityOverLifetime.enabled = (direction != ParticlesDirection.Random);
                    velocityOverLifetime.space = (direction == ParticlesDirection.LocalSpace) ? ParticleSystemSimulationSpace.Local : ParticleSystemSimulationSpace.World;
                    velocityOverLifetime.xMultiplier = velocity.x;
                    velocityOverLifetime.yMultiplier = velocity.y;
                    velocityOverLifetime.zMultiplier = velocity.z;
                }

                main.maxParticles = maxParticles;

                {
                    var shape = m_Particles.shape;
                    shape.shapeType = ParticleSystemShapeType.ConeVolume;

                    float coneAngle = m_Master.coneAngle * Mathf.Lerp(0.7f, 1f, thickness);
                    shape.angle = coneAngle * 0.5f;

                    float radiusStart = m_Master.coneRadiusStart * Mathf.Lerp(0.3f, 1.0f, thickness);
                    float radiusEnd = Utils.ComputeConeRadiusEnd(m_Master.fallOffEnd, coneAngle);
                    shape.radius = Mathf.Lerp(radiusStart, radiusEnd, spawnDistanceRange.minValue);

                    shape.length = coneLength;

                    var localOffset = m_Master.fallOffEnd * spawnDistanceRange.minValue;
#if UNITY_2017_1_OR_NEWER
                    shape.position = new Vector3(0f, 0f, localOffset);
#else
                    m_Particles.transform.localPosition = m_Master.beamLocalForward * localOffset;
#endif
                    shape.arc = 360f;
                    shape.randomDirectionAmount = (direction == ParticlesDirection.Random) ? 1f : 0f;
                }

                var emission = m_Particles.emission;
                var rate = emission.rateOverTime;
                rate.constant = ratePerSec;
                emission.rateOverTime = rate;

                if(m_Renderer)
                {
                    m_Renderer.sortingLayerID = m_Master.sortingLayerID;
                    m_Renderer.sortingOrder = m_Master.sortingOrder;
                }
            }
        }

        void HandleBackwardCompatibility(int serializedVersion, int newVersion)
        {
            if (serializedVersion == -1) return;            // freshly new spawned entity: nothing to do
            if (serializedVersion == newVersion) return;    // same version: nothing to do

#pragma warning disable 0618
            if (serializedVersion < 1880)
            {
                // Version 1880 changed the order of ParticlesDirection enum and add WorldSpace option
                if ((int)direction == 0)    direction = (ParticlesDirection)1;
                else                        direction = (ParticlesDirection)0;

                // Version 1880 changed from single float speed to 3D velocity vector
                velocity = new Vector3(0.0f, 0.0f, speed);
            }

            if (serializedVersion < 1940)
            {
                spawnDistanceRange = new MinMaxRangeFloat(spawnMinDistance, spawnMaxDistance);
            }
#pragma warning restore 0618

            Utils.MarkCurrentSceneDirty();
        }

        #region Culling
        void UpdateCulling()
        {
            if (m_Particles)
            {
                bool visible = true;
                if ((cullingEnabled || m_Master.isFadeOutEnabled) && m_Master.hasGeometry)
                {
                    if (mainCamera)
                    {
                        var maxDist = cullingMaxDistance;
                        if (m_Master.isFadeOutEnabled) maxDist = Mathf.Min(maxDist, m_Master.fadeOutEnd);
                        var maxDistSqr = maxDist * maxDist;
                        var distSqr = m_Master.bounds.SqrDistance(mainCamera.transform.position);
                        visible = distSqr <= maxDistSqr;
                    }
                    else
                        cullingEnabled = false;
                }

                if (m_Particles.gameObject.activeSelf != visible)
                {
                    SetActive(visible);
                    isCulled = !visible;
                }

                if (visible && !m_Particles.isPlaying)
                    m_Particles.Play();
            }
        } 
        #endregion
    }
}

Can anyone here help me understand how to reference this other script and also control the intensity variable?这里的任何人都可以帮助我了解如何引用这个其他脚本并控制强度变量吗? Thank you!谢谢!

Add the needed namespace using at the top of your script (i suppose it is VLB ) like在脚本顶部添加所需的命名空间(我想它是VLB ),比如

using System;
using VLB; // add this line

The script you want to add is in another namespace, so you need to tell your script, where to find it before you are able to work with it.您要添加的脚本位于另一个命名空间中,因此您需要告诉您的脚本在哪里可以找到它,然后才能使用它。 Tools like ReSharper for VisualStudio (or Rider IDE that included the same functionality) help a lot with such cases.诸如 ReSharper for VisualStudio(或包含相同功能的 Rider IDE)之类的工具对此类情况有很大帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM