Inheritance: MonoBehaviour
Exemplo n.º 1
0
        // mark args as ReadOnly as much as possible
        public void Execute(Entity ent, int index, [ReadOnly] ref Translation position,
                            [ReadOnly] ref Rotation rotation)
        {
            DynamicBuffer <AutoShootBuffer> shootBuffer = autoShootBuffers[ent];
            DynamicBuffer <TimePassed>      buffer      = timePassedBuffers[ent];

            for (int i = 0; i < shootBuffer.Length; ++i)
            {
                AutoShoot shoot = shootBuffer[i].val;

                // getting the right TimePassed
                TimePassed timePassed  = buffer[shoot.timeIdx];
                TimePassed volleyCount = buffer[shoot.volleyCountIdx];
                timePassed.time += dt;

                if (timePassed.time > shoot.startDelay)
                {
                    float actualTime = timePassed.time - shoot.startDelay;

                    // EXTRA: add recovery for bullets not fired exactly when they should
                    // fire if above period and not on cooldown
                    while (actualTime >= shoot.period && volleyCount.time < shoot.numVolleys)
                    {
                        // shoot the pattern
                        Fire(ent, index, ref position, ref rotation, ref shoot, actualTime);
                        volleyCount.time += 1;
                        timePassed.time  -= shoot.period;
                        actualTime        = timePassed.time - shoot.startDelay;
                    }

                    // on cooldown, wait for time to pass to reset
                    if (actualTime >= shoot.cooldownDuration && volleyCount.time == shoot.numVolleys)
                    {
                        volleyCount.time = 0;
                        timePassed.time -= shoot.cooldownDuration;
                    }
                }

                // writing updates out
                buffer[shoot.timeIdx]        = timePassed;
                buffer[shoot.volleyCountIdx] = volleyCount;
            }
        }
Exemplo n.º 2
0
    // Lets you convert the editor data representation to the entity optimal runtime representation
    public void Convert(Entity entity, EntityManager dstManager,
                        GameObjectConversionSystem conversionSystem)
    {
        Assert.IsTrue(period > 0);

        // add a TimePassed component
        int timeIdx        = TimePassedUtility.AddDefault(entity, dstManager);
        int volleyCountIdx = TimePassedUtility.AddDefault(entity, dstManager);

        Entity    bulletEnt = conversionSystem.GetPrimaryEntity(bullet);
        AutoShoot shootData = new AutoShoot
        {
            // The referenced prefab will already be converted due to DeclareReferencedPrefabs.
            // so just look up the entity version in the conversion system
            bullet           = bulletEnt,
            startDelay       = startDelay,
            cooldownDuration = cooldownDuration,
            period           = period,
            pattern          = pattern,
            count            = count,

            sourceOffset = new float3(sourceOffset.x, sourceOffset.y, 0),
            numVolleys   = numVolleys,
            angle        = math.radians(angle),
            aimStyle     = aimStyle,
            centerAngle  = math.radians(centerAngle),

            timeIdx        = timeIdx,
            volleyCountIdx = volleyCountIdx,

            moveStatsIdx   = AutoShootUtility.GetOrAddMovementIdx(movementStats),
            damageStatsIdx = AutoShootUtility.GetOrAddDamageIdx(damageStats)
        };

        DynamicBuffer <AutoShootBuffer> buffer = AutoShootUtility.GetOrAddBuffer(entity, dstManager);

        buffer.Add(new AutoShootBuffer {
            val = shootData
        });
    }
Exemplo n.º 3
0
        private void Fire(Entity ent, int index, [ReadOnly] ref Translation position,
                          [ReadOnly] ref Rotation rotation, [ReadOnly] ref AutoShoot shoot,
                          float time)
        {
            float      interval;
            quaternion fireDirection  = quaternion.identity;
            float3     shooterForward = math.forward(rotation.Value);
            float3     spawnPos       = position.Value + shoot.sourceOffset;
            float3     playerPos      = (playerPositions.Length > 0)
                ? playerPositions[ent.Index % playerPositions.Length].Value
                : new float3(0, 0, 0);

            switch (shoot.aimStyle)
            {
            case AimStyle.Forward:
                fireDirection = math.normalize(rotation.Value);
                break;

            case AimStyle.Player:
                if (playerPositions.Length > 0)
                {
                    fireDirection = quaternion.LookRotation(
                        shooterForward,
                        math.normalize(playerPos - spawnPos));
                }
                else      // no player targets, just use rotation
                {
                    fireDirection = math.normalize(rotation.Value);
                }
                break;
            }

            switch (shoot.pattern)
            {
            case ShotPattern.FAN:
                if (shoot.count == 1)
                {
                    InitBulletPosRot(spawnPos, shooterForward, fireDirection,
                                     shoot.centerAngle, time - shoot.period, shoot.moveStatsIdx,
                                     playerPos, out float3 pos, out quaternion rot);
                    CreateBullet(index, shoot.bullet, pos, rot,
                                 shoot.moveStatsIdx, shoot.damageStatsIdx);
                }
                else
                {
                    // space between shots is angle / (count - 1) to have
                    //   shots on edges
                    interval = shoot.angle / (shoot.count - 1);
                    float halfAngle = shoot.angle / 2;
                    for (float rad = -halfAngle; rad <= halfAngle; rad += interval)
                    {
                        InitBulletPosRot(spawnPos, shooterForward, fireDirection,
                                         rad + shoot.centerAngle, time - shoot.period,
                                         shoot.moveStatsIdx, playerPos, out float3 pos, out quaternion rot);
                        CreateBullet(index, shoot.bullet, pos, rot,
                                     shoot.moveStatsIdx, shoot.damageStatsIdx);
                    }
                }
                break;

            case ShotPattern.AROUND:
                interval = (float)(2 * math.PI / shoot.count);
                for (float rad = 0.0f; rad < 2 * math.PI; rad += interval)
                {
                    InitBulletPosRot(spawnPos, shooterForward, fireDirection,
                                     rad + shoot.centerAngle, time - shoot.period,
                                     shoot.moveStatsIdx, playerPos, out float3 pos, out quaternion rot);
                    CreateBullet(index, shoot.bullet, pos, rot,
                                 shoot.moveStatsIdx, shoot.damageStatsIdx);
                }
                break;
            }
        }