Beispiel #1
0
        protected override void OnUpdate()
        {
            Entities.With(_queryFollowMovement).ForEach(
                (Entity entity, AbilityFollowMovement follow, ref ActorFollowMovementData followData) =>
            {
                if (follow.Target == null)
                {
                    var properties = follow.findTargetProperties;

                    var targets = GetTargetList(follow.Actor, properties.targetType,
                                                properties.actorWithComponentName, properties.targetTag);

                    if (properties.ignoreSpawner && targets.Contains(follow.Actor.Spawner.GameObject.transform))
                    {
                        targets.Remove(follow.Actor.Spawner.GameObject.transform);
                    }

                    follow.Target =
                        FindActorsUtils.ChooseActor(follow.gameObject.transform, targets, properties.strategy);

                    if (follow.Target == null)
                    {
                        return;
                    }
                }

                followData.Origin = follow.Target.position;
                PostUpdateCommands.RemoveComponent <ActorNoFollowTargetMovementData>(entity);
            }
                );

            Entities.With(_queryFollowRotation).ForEach(
                (Entity entity, AbilityFollowRotation follow, ref ActorFollowRotationData followData) =>
            {
                if (follow.target == null)
                {
                    var targets = GetTargetList(follow.Actor, follow.followTarget,
                                                follow.actorWithComponentName, follow.targetTag);

                    follow.target =
                        FindActorsUtils.ChooseActor(follow.gameObject.transform, targets, follow.strategy);

                    if (follow.target == null)
                    {
                        return;
                    }
                }

                followData.Origin = follow.target.rotation.eulerAngles;
                PostUpdateCommands.RemoveComponent <ActorNoFollowTargetRotationData>(entity);
                var t = typeof(ActorNoFollowTargetRotationData);
                PostUpdateCommands.RemoveComponent(entity, t);
            }
                );

            Entities.With(_queryAutoAim).ForEach(
                (Entity entity, Actor actor, ref FindAutoAimTargetData findAutoAimTargetData) =>
            {
                var autoAimData = findAutoAimTargetData;
                var weapon      = actor.Abilities.OfType <AbilityWeapon>()
                                  .FirstOrDefault(a => a.componentName == autoAimData.WeaponComponentName);

                if (weapon == null)
                {
                    PostUpdateCommands.RemoveComponent <FindAutoAimTargetData>(entity);
                    return;
                }

                var properties = weapon.findTargetProperties;

                var targets = GetTargetList(weapon.Actor, properties.targetType,
                                            properties.actorWithComponentName, properties.targetTag);

                if (properties.ignoreSpawner && targets.Contains(weapon.Actor.GameObject.transform))
                {
                    targets.Remove(weapon.Actor.GameObject.transform);
                }

                var targetTransform =
                    FindActorsUtils.ChooseActor(weapon.gameObject.transform, targets, properties.strategy);

                if (targetTransform == null || properties.strategy == ChooseTargetStrategy.Nearest && properties.maxDistanceThreshold > 0f &&
                    math.distancesq(targetTransform.position, weapon.Actor.GameObject.transform.position) >
                    properties.maxDistanceThreshold * properties.maxDistanceThreshold)
                {
                    properties.SearchCompleted = true;
                    PostUpdateCommands.RemoveComponent <FindAutoAimTargetData>(entity);

                    weapon.Spawn();
                    return;
                }

                weapon.DisposableSpawnCallback = go =>
                {
                    var targetActor = go.GetComponent <Actor>();
                    if (targetActor == null)
                    {
                        return;
                    }

                    targetActor.ChangeActorForceMovementData(go.transform.forward);
                    weapon.DisposableSpawnCallback = null;
                };

                weapon.SpawnPointsRoot.LookAt(targetTransform.position);
                properties.SearchCompleted = true;
                weapon.Spawn();
                PostUpdateCommands.RemoveComponent <FindAutoAimTargetData>(entity);
            }
                );
        }
Beispiel #2
0
        public static List <GameObject> Spawn(IActorSpawnerSettings spawnSettings, IActor spawner = null,
                                              IActor owner = null)
        {
            if (spawnSettings.SpawnerDisabled)
            {
                return(null);
            }

            Vector3    tempPos = Vector3.zero;
            Quaternion tempRot = Quaternion.Euler(Vector3.zero);
            GameObject tempObj;

            int spawnCount;

            List <Component>  sampledComponents = new List <Component>();
            List <GameObject> spawnedObjects    = new List <GameObject>();

            if (spawnSettings.SpawnPosition == SpawnPosition.UseSpawnPoints &&
                spawnSettings.SpawnPointsFrom == SpawnPointsSource.FindByTag)
            {
                spawnSettings.SpawnPoints = GameObject.FindGameObjectsWithTag(spawnSettings.SpawnPointTag).ToList();
                if (spawnSettings.SpawnPoints.Count == 0)
                {
                    Debug.LogError("[LEVEL ACTOR SPAWNER] No spawn points found with tag: " +
                                   spawnSettings.SpawnPointTag + ". Aborting!");
                    return(null);
                }
            }

            switch (spawnSettings.FillSpawnPoints)
            {
            case FillMode.UseEachObjectOnce:
                spawnCount = spawnSettings.ObjectsToSpawn.Count;
                break;

            case FillMode.FillAllSpawnPoints:
                spawnCount = spawnSettings.SpawnPoints.Count;
                break;

            case FillMode.PlaceEachObjectXTimes:
                spawnCount = spawnSettings.ObjectsToSpawn.Count * spawnSettings.X;
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            if (spawnSettings.SkipBusySpawnPoints && spawnSettings.SpawnPosition == SpawnPosition.UseSpawnPoints)
            {
                for (var i = 0; i < spawnSettings.SpawnPoints.Count; i++)
                {
                    var actorSpawnedOnPoint = spawnSettings.SpawnPoints[i].GetComponent <ActorSpawnedOnPoint>();

                    if (actorSpawnedOnPoint != null && actorSpawnedOnPoint.actor != null)
                    {
                        spawnSettings.SpawnPoints.RemoveAt(i);
                        spawnCount--;
                        i--;
                    }
                }
            }

            if (spawnSettings.SpawnPointsFillingMode == FillOrder.RandomOrder)
            {
                spawnSettings.ObjectsToSpawn =
                    spawnSettings.ObjectsToSpawn.OrderBy(item => spawnSettings.Rnd.Next()).ToList();
                spawnSettings.SpawnPoints =
                    spawnSettings.SpawnPoints.OrderBy(item => spawnSettings.Rnd.Next()).ToList();
            }

            for (var i = 0; i < spawnCount; i++)
            {
                switch (spawnSettings.SpawnPosition)
                {
                case SpawnPosition.UseSpawnPoints:
                {
                    if (spawnSettings.SpawnPoints.Count == 0)
                    {
                        Debug.LogError(
                            $"[ACTOR SPAWNER] In Use Spawn Points mode you have to provide some spawning points! \n" +
                            $"Spawner is {spawner}, and object is {spawnSettings.ObjectsToSpawn[0]}");
                        return(null);
                    }

                    tempPos = spawnSettings.SpawnPoints[i % spawnSettings.SpawnPoints.Count].transform.position;
                    if (spawnSettings.RotationOfSpawns == RotationOfSpawns.UseSpawnPointRotation)
                    {
                        tempRot = spawnSettings.SpawnPoints[i % spawnSettings.SpawnPoints.Count].transform.rotation;
                    }

                    break;
                }

                case SpawnPosition.RandomPositionOnNavMesh:
                    tempPos = NavMeshRandomPointUtil.GetRandomLocation();
                    break;

                case SpawnPosition.UseSpawnerPosition:
                    if (spawner == null)
                    {
                        Debug.LogError("[ACTOR SPAWNER] You are using Use Spawner Position, but Spawner is NULL!");
                        return(null);
                    }

                    if (spawner.GameObject == null)
                    {
                        return(null);
                    }

                    tempPos = spawner.GameObject.transform.position;
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }

                switch (spawnSettings.RotationOfSpawns)
                {
                case RotationOfSpawns.UseRandomRotationY:
                    tempRot = Quaternion.Euler(0f, spawnSettings.Rnd.Next() % 360f, 0f);
                    break;

                case RotationOfSpawns.UseRandomRotationXYZ:
                    tempRot = Quaternion.Euler(spawnSettings.Rnd.Next() % 360f, spawnSettings.Rnd.Next() % 360f,
                                               spawnSettings.Rnd.Next() % 360f);
                    break;

                case RotationOfSpawns.UseSpawnPointRotation:
                    if (spawnSettings.SpawnPosition == SpawnPosition.UseSpawnerPosition)
                    {
                        tempRot = spawner.GameObject.transform.rotation;
                    }

                    break;

                case RotationOfSpawns.UseZeroRotation:
                    tempRot = Quaternion.Euler(Vector3.zero);
                    break;

                case RotationOfSpawns.SpawnerMovement:
                    try
                    {
                        var spawnerMovementData =
                            World.DefaultGameObjectInjectionWorld.EntityManager.GetComponentData <ActorMovementData>(
                                spawner.ActorEntity);
                        tempRot = spawnerMovementData.Input.Equals(float3.zero)?Quaternion.Euler(Vector3.zero): Quaternion.LookRotation(Vector3.Normalize(spawnerMovementData.Input));
                    }
                    catch
                    {
                        Debug.LogError(
                            "[ACTOR SPAWNER] To get Rotation from Spawner Movement, you need IActor Spawner and ActorMovementData on it!");
                        tempRot = Quaternion.Euler(Vector3.zero);
                    }

                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }

                if (spawnSettings.CopyComponentsFromSamples.Count > 0)
                {
                    sampledComponents = new List <Component>();

                    foreach (var sample in spawnSettings.CopyComponentsFromSamples)
                    {
                        if (sample == null)
                        {
                            continue;
                        }

                        foreach (var component in sample.GetComponents <Component>())
                        {
                            if (component == null || component is Transform || component is IActor)
                            {
                                continue;
                            }
                            switch (spawnSettings.CopyComponentsOfType)
                            {
                            case ComponentsOfType.OnlyAbilities when !(component is IActorAbility):
                                continue;

                            case ComponentsOfType.OnlySimpleBehaviours when component is IActorAbility:
                                continue;

                            case ComponentsOfType.AllComponents:
                            default:
                                sampledComponents.Add(component);
                                break;
                            }
                        }
                    }

                    if (sampledComponents.Count == 0)
                    {
                        Debug.LogError("[LEVEL ACTOR SPAWNER] No suitable components found in sample game objects!");
                    }
                }

                tempObj = UnityEngine.Object.Instantiate(
                    spawnSettings.ObjectsToSpawn[i % spawnSettings.ObjectsToSpawn.Count], tempPos, tempRot);

                var actors = tempObj.GetComponents <IActor>();

                if (spawnSettings.ParentOfSpawns != TargetType.None)
                {
                    var parents = FindActorsUtils.GetActorsList(tempObj, spawnSettings.ParentOfSpawns,
                                                                spawnSettings.ActorWithComponentName, spawnSettings.ParentTag);

                    var parent = FindActorsUtils.ChooseActor(tempObj.transform, parents, spawnSettings.ChooseStrategy);

                    tempObj.transform.SetParent(parent);
                }

                if (sampledComponents.Count > 0)
                {
                    if (spawnSettings.DeleteExistingComponents)
                    {
                        foreach (var component in tempObj.GetComponents <Component>())
                        {
                            if (component is Transform || component is IActor)
                            {
                                continue;
                            }
                            Object.Destroy(component);
                        }
                    }

                    tempObj.CopyComponentsWithLinks(sampledComponents);
                }

                if (actors.Length > 1)
                {
                    Debug.LogError("[ACTOR SPAWNER] Only one IActor Component for Actor allowed!");
                }
                else if (actors.Length == 1)
                {
                    if (spawner != null)
                    {
                        spawner.ChildrenSpawned++;
                        actors.First().ActorId = spawner.ActorId;
                    }

                    actors.First().Spawner = spawner;
                    actors.First().Owner   = owner ?? spawner ?? actors.First();
                    actors.First().Setup();
                }

                if (spawnSettings.SpawnPosition == SpawnPosition.UseSpawnPoints && spawnSettings.SkipBusySpawnPoints)
                {
                    spawnSettings.SpawnPoints[i % spawnSettings.SpawnPoints.Count].AddComponent <ActorSpawnedOnPoint>()
                    .actor = tempObj;
                }

                spawnedObjects.Add(tempObj);
            }

            return(spawnedObjects);
        }