public void OnEvent(SubSpellEventArgs args)
        {
            if (args.Event == SubSpellEvent.Ended)
            {
                OnEndSubSpell(args.Handler);
                return;
            }

            if (args.Event != SpawnEvent)
            {
                return;
            }

            if (InstanceMode == EffectInstancingMode.OnePerSubSpell)
            {
                // If the mode is one per subspell than we need to find existing one
                // and update its target information. And also raise its UpdateEvent
                var existingInstanceIdx = _instances.FindIndex(i => i.Handler.Equals(args.Handler));
                if (existingInstanceIdx >= 0)
                {
                    var existing = _instances[existingInstanceIdx];
                    var instance = new SubSpellEffectInstance
                    {
                        InstanceObject = existing.InstanceObject,
                        Target         = args.Handler.Target,
                        Source         = args.Handler.Source,
                        Handler        = args.Handler,
                        Ray            = existing.Ray
                    };
                    _instances[existingInstanceIdx] = instance;

                    GetRayStartAndEnd(instance, out var src, out var dst);
                    instance.Ray?.RayUpdated(src, dst);
                }
                else
                {
                    // If no existing instance is found, create new
                    CreateRayEffectInstance(out var gameObjectInstance, out var ray);
                    if (ray != null)
                    {
                        var instance = new SubSpellEffectInstance
                        {
                            InstanceObject = gameObjectInstance,
                            Target         = args.Handler.Target,
                            Source         = args.Handler.Source,
                            Handler        = args.Handler,
                            Ray            = ray
                        };
                        _instances.Add(instance);
                        GetRayStartAndEnd(instance, out var src, out var dst);
                        instance.Ray?.RayStarted(src, dst);
                    }
                }
            }
            else if (InstanceMode == EffectInstancingMode.OnePerEventTarget)
            {
                if (args.QueriedTargets != null)
                {
                    foreach (var target in args.QueriedTargets)
                    {
                        CreateRayEffectInstance(out var gameObjectInstance, out var ray);
                        if (ray != null)
                        {
                            var instance = new SubSpellEffectInstance
                            {
                                Ray            = ray,
                                InstanceObject = gameObjectInstance,
                                Source         = args.Handler.Source,
                                Target         = target,
                                Handler        = args.Handler
                            };
                            _instances.Add(instance);
                            GetRayStartAndEnd(instance, out var src, out var dst);
                            ray.RayStarted(src, dst);
                        }
                    }
                }
            }
        }
 private void GetRayStartAndEnd(SubSpellEffectInstance instance, out Vector3 source, out Vector3 destination)
 {
     source      = GetPosition(instance.Source, PreferredSourceNode);
     destination = GetPosition(instance.Target, PreferredTargetNode);
 }