Exemple #1
0
        protected void CreateNativeTransformCollections()
        {
            _nativeTweenStates = new NativeArray <TweenTransformState>(_tweenStates.Length, Allocator.TempJob);
            JTweenTools.CopyTweenStateDirectlyToNativeArray(_tweenStates.buffer, _nativeTweenStates, _tweenStates.Length);

            _nativeTweenPositions = new NativeArray <TweenFloat3>(_tweenPositions.Length, Allocator.TempJob);
            JTweenTools.CopyTween3DirectlyToNativeArray(_tweenPositions.buffer, _nativeTweenPositions, _tweenPositions.Length);

            _nativeTweenRotations = new NativeArray <TweenRotation>(_tweenRotations.Length, Allocator.TempJob);
            JTweenTools.CopyTweenRotationDirectlyToNativeArray(_tweenRotations.buffer, _nativeTweenRotations, _tweenRotations.Length);

            _nativeTweenScales = new NativeArray <TweenFloat3>(_tweenScales.Length, Allocator.TempJob);
            JTweenTools.CopyTween3DirectlyToNativeArray(_tweenScales.buffer, _nativeTweenScales, _tweenScales.Length);

            _nativePositionLifetimes = new NativeArray <TweenLifetime>(_tweenPositionLifetimes.Length, Allocator.TempJob);
            JTweenTools.CopyTweenLifetimeDirectlyToNativeArray(_tweenPositionLifetimes.buffer, _nativePositionLifetimes, _tweenPositionLifetimes.Length);

            _nativeRotationLifetimes = new NativeArray <TweenLifetime>(_tweenRotationLifetimes.Length, Allocator.TempJob);
            JTweenTools.CopyTweenLifetimeDirectlyToNativeArray(_tweenRotationLifetimes.buffer, _nativeRotationLifetimes, _tweenRotationLifetimes.Length);

            _nativeScaleLifetimes = new NativeArray <TweenLifetime>(_tweenScaleLifetimes.Length, Allocator.TempJob);
            JTweenTools.CopyTweenLifetimeDirectlyToNativeArray(_tweenScaleLifetimes.buffer, _nativeScaleLifetimes, _tweenScaleLifetimes.Length);

            _nativePositions = new NativeArray <float3>(_tweenPositions.Length, Allocator.TempJob);
            _nativeRotations = new NativeArray <quaternion>(_tweenRotations.Length, Allocator.TempJob);
            _nativeScales    = new NativeArray <float3>(_tweenScales.Length, Allocator.TempJob);
        }
Exemple #2
0
 protected void CopyNativeCollectionsToManaged()
 {
     JTweenTools.CopyNativeArrayDirectlyToTweenState(_nativeTweenStates, _tweenStates.buffer);
     JTweenTools.CopyNativeArrayDirectlyToTweenLifetime(_nativePositionLifetimes, _tweenPositionLifetimes.buffer);
     JTweenTools.CopyNativeArrayDirectlyToTweenLifetime(_nativeRotationLifetimes, _tweenRotationLifetimes.buffer);
     JTweenTools.CopyNativeArrayDirectlyToTweenLifetime(_nativeScaleLifetimes, _tweenScaleLifetimes.buffer);
 }
        protected override void LateUpdateTweens()
        {
            Profiler.BeginSample(LATE_UPDATE_PROFILE);
            if (!_isJobScheduled)
            {
                Profiler.EndSample();
                return;
            }

            _isJobScheduled = false;

            // Complete the batch process job
            _processBatchJobHandle.Complete();

            JTweenTools.CopyNativeArrayDirectlyToTweenBatch(_nativeTweenBatches, _tweenBatches.buffer);
            JTweenTools.CopyNativeArrayDirectlyToTweenLifetime(_nativeTweenBatchLifetimes, _tweenBatchLifetimes.buffer);

            // Complete the tween job and any dependencies
            applyTweenUpdates.Complete();

            // Get the data we need back from the native collections or if tween completed remove it.
            CopyNativeCollectionsToManaged();

            // Sort batches from earliest index to latest, check for any completed batches,
            // and then remove en masse tweens where their batch is complete.
            for (var i = _tweenBatches.Length - 1; i >= 0; i--)
            {
                var batch = _tweenBatches.buffer[i];

                if (_tweenBatchHandles.buffer[i] != null)
                {
                    _tweenBatchHandles.buffer[i].state = batch.state;
                }

                if (batch.IsCompleted())
                {
                    if (batch.JustEnded())
                    {
                        batch.state            &= ~TweenStateType.JustEnded;
                        _tweenBatches.buffer[i] = batch;

                        if (_tweenBatchHandles.buffer[i] != null)
                        {
                            _tweenBatchHandles.buffer[i].state = batch.state;
                            _tweenHandleCallbackEventQueue.Enqueue(_tweenBatchHandles.buffer[i]);
                        }
                    }

                    if (batch.RequiresRecycling())
                    {
                        var index  = (int)batch.startIndex;
                        var length = (int)batch.length;

                        // We don't have a great option here for removing a range of transforms from this
                        // specific native collection type.
                        for (var j = index + length - 1; j >= index; j--)
                        {
                            Profiler.BeginSample(TRANSFORM_ACCESS_ARRAY_REMOVE_PROFILE);
                            _transformAccessArray.RemoveAtSwapBack(j);
                            Profiler.EndSample();
                        }

                        Profiler.BeginSample(FAST_LIST_REMOVE_RANGE);
                        _transforms.RemoveRange(index, length);
                        _tweenStates.RemoveRange(index, length);
                        _tweenPositions.RemoveRange(index, length);
                        _tweenRotations.RemoveRange(index, length);
                        _tweenScales.RemoveRange(index, length);
                        _tweenPositionLifetimes.RemoveRange(index, length);
                        _tweenRotationLifetimes.RemoveRange(index, length);
                        _tweenScaleLifetimes.RemoveRange(index, length);

                        // Shuffle all batches ahead of the current one so that their start indexes are adjusted back
                        // based on the length of the batch we are removing.
                        for (var j = i + 1; j < _tweenBatches.Length; j++)
                        {
                            var laterTweenBatch = _tweenBatches.buffer[j];
                            laterTweenBatch.startIndex -= batch.length;
                            _tweenBatches.buffer[j]     = laterTweenBatch;
                        }

                        _tweenBatches.RemoveAt(i);
                        _tweenBatchLifetimes.RemoveAt(i);
                        _tweenBatchHandles.RemoveAt(i);
                        Profiler.EndSample();
                    }
                }
            }

            // Properly dispose of the native collections
            DisposeNativeTransformCollections();

            _nativeTweenBatches.Dispose();
            _nativeTweenBatchLifetimes.Dispose();

            Profiler.EndSample();

            Profiler.BeginSample(EVENT_COMPLETED_PROFILE);

            // After all sensitive native work has completed, kick out any and all completed events
            while (_tweenHandleCallbackEventQueue.Count > 0)
            {
                var tweenHandle = _tweenHandleCallbackEventQueue.Dequeue();
                _tweenHandlePool.AddLast(tweenHandle);

                tweenHandle.Completed?.Invoke();
            }

            Profiler.EndSample();
        }
        protected override void UpdateTweens()
        {
            Profiler.BeginSample(UPDATE_PROFILE);
            if (_transforms.Length == 0)
            {
                Profiler.EndSample();
                return;
            }

            while (_tweenHandleActionEventQueue.Count > 0)
            {
                var updateLifetimes   = false;
                var tweenHandleAction = _tweenHandleActionEventQueue.Dequeue();
                if (tweenHandleAction.index >= 0 && tweenHandleAction.index < _tweenBatchHandles.Length)
                {
                    var tweenHandle = _tweenBatchHandles.buffer[tweenHandleAction.index];
                    var tweenBatch  = _tweenBatches.buffer[tweenHandleAction.index];
                    switch (tweenHandle.actionType)
                    {
                    case TweenHandleActionType.Play:
                        if (!tweenBatch.IsCompleted() && tweenBatch.IsPaused())
                        {
                            tweenBatch.state |= TweenStateType.IsPlaying;
                            tweenBatch.state &= ~TweenStateType.IsPaused;
                        }
                        break;

                    case TweenHandleActionType.Pause:
                        if (tweenBatch.IsPlaying())
                        {
                            tweenBatch.state &= ~TweenStateType.IsPlaying;
                            tweenBatch.state |= TweenStateType.IsPaused;
                        }
                        break;

                    case TweenHandleActionType.Stop:
                        if (tweenBatch.IsPlaying() || tweenBatch.IsPaused())
                        {
                            tweenBatch.state &= ~TweenStateType.IsPlaying;
                            tweenBatch.state &= ~TweenStateType.IsPaused;
                            tweenBatch.state |= TweenStateType.IsCompleted;
                            tweenBatch.state |= TweenStateType.JustEnded;
                        }
                        break;

                    case TweenHandleActionType.Recycle:
                        tweenBatch.state &= ~TweenStateType.IsPaused;
                        tweenBatch.state &= ~TweenStateType.IsPlaying;
                        tweenBatch.state &= ~TweenStateType.HasHandle;
                        tweenBatch.state |= TweenStateType.IsCompleted;
                        tweenBatch.state |= TweenStateType.RequiresRecycling;
                        break;

                    case TweenHandleActionType.Rewind:
                        tweenBatch.state = HANDLE_START_PAUSED;
                        var tweenBatchLifetimeRewind = _tweenBatchLifetimes.buffer[tweenHandleAction.index];
                        tweenBatchLifetimeRewind.Restart();
                        _tweenBatchLifetimes.buffer[tweenHandleAction.index] = tweenBatchLifetimeRewind;

                        updateLifetimes = true;
                        break;

                    case TweenHandleActionType.Restart:
                        tweenBatch.state = HANDLE_START_PLAYING;
                        var tweenBatchLifetimeRestart = _tweenBatchLifetimes.buffer[tweenHandleAction.index];
                        tweenBatchLifetimeRestart.Restart();
                        _tweenBatchLifetimes.buffer[tweenHandleAction.index] = tweenBatchLifetimeRestart;

                        updateLifetimes = true;

                        break;

                    case TweenHandleActionType.None:
                    default:
                        throw new NotImplementedException();
                    }

                    for (var i = tweenBatch.startIndex; i < tweenBatch.startIndex + tweenBatch.length; i++)
                    {
                        var tweenState = _tweenStates.buffer[i];
                        tweenState.state       = tweenBatch.state;
                        _tweenStates.buffer[i] = tweenState;

                        if (updateLifetimes)
                        {
                            var tweenPosLifetime = _tweenPositionLifetimes.buffer[i];
                            tweenPosLifetime.Restart();
                            _tweenPositionLifetimes.buffer[i] = tweenPosLifetime;

                            var tweenRotLifetime = _tweenRotationLifetimes.buffer[i];
                            tweenRotLifetime.Restart();
                            _tweenRotationLifetimes.buffer[i] = tweenRotLifetime;

                            var tweenScaleLifetime = _tweenScaleLifetimes.buffer[i];
                            tweenScaleLifetime.Restart();
                            _tweenScaleLifetimes.buffer[i] = tweenScaleLifetime;
                        }
                    }

                    tweenHandle.state = tweenBatch.state;

                    _tweenBatches.buffer[tweenHandleAction.index] = tweenBatch;
                }
                else
                {
                    Debug.LogWarning(RuntimeConstants.HANDLE_BATCH_NOT_FOUND);
                }
            }

            for (var i = 0; i < _tweenBatches.Length; i++)
            {
                var tweenBatch = _tweenBatches.buffer[i];
                if (tweenBatch.IsPlaying() && tweenBatch.JustStarted())
                {
                    tweenBatch.state &= ~TweenStateType.JustStarted;

                    _tweenBatches.buffer[i] = tweenBatch;

                    if (_tweenBatchHandles.buffer[i] != null)
                    {
                        _tweenBatchHandles.buffer[i].state = tweenBatch.state;
                        _tweenHandleCallbackEventQueue.Enqueue(_tweenBatchHandles.buffer[i]);
                    }
                }
            }

            // Create and setup native collections. Copy over existing data
            CreateNativeTransformCollections();

            _nativeTweenBatches = new NativeArray <TweenTransformBatchState>(_tweenBatches.Length, Allocator.TempJob);
            JTweenTools.CopyTweenBatchDirectlyToNativeArray(_tweenBatches.buffer, _nativeTweenBatches, _tweenBatches.Length);

            _nativeTweenBatchLifetimes = new NativeArray <TweenLifetime>(_tweenBatchLifetimes.Length, Allocator.TempJob);
            JTweenTools.CopyTweenLifetimeDirectlyToNativeArray(_tweenBatchLifetimes.buffer, _nativeTweenBatchLifetimes, _tweenBatchLifetimes.Length);

            // Schedule Jobs
            _processBatchJob = new ProcessBatchJob
            {
                deltaTime      = _deltaTime,
                batchLifetimes = _nativeTweenBatchLifetimes,
                tweenBatches   = _nativeTweenBatches
            };

            _processBatchJobHandle = _processBatchJob.Schedule(_tweenBatches.Length, 1);

            SetupJobs();

            _isJobScheduled = true;

            Profiler.EndSample();

            Profiler.BeginSample(EVENT_STARTED_PROFILE);

            // After all sensitive native work has completed, kick out any and all started events
            while (_tweenHandleCallbackEventQueue.Count > 0)
            {
                var tweenEvent = _tweenHandleCallbackEventQueue.Dequeue();
                tweenEvent.Started?.Invoke();
            }

            Profiler.EndSample();
        }
        internal void RotateOnAxis(
            Transform target,
            float angle,
            float duration,
            RotateMode rotateMode,
            SpaceType spaceType,
            EaseType easeType,
            LoopType loopType,
            int loopCount,
            Action onStart,
            Action onComplete,
            bool useTweenHandle,
            out ITweenHandle tweenHandle)
        {
            Assert.IsTrue(rotateMode != RotateMode.XYZ, RuntimeConstants.INVALID_ROTATE_MODE);

            tweenHandle = null;

            _transforms.Add(target);
            _transformAccessArray.Add(target);

            var rotateType = JTweenTools.GetTweenSpaceTypeFromRotateMode(rotateMode);

            _tweenStates.Add(new TweenTransformState
            {
                state         = useTweenHandle ? HANDLE_START_PAUSED : NO_HANDLE_START,
                transformType = TweenTransformType.Rotation,
                spaceType     = spaceType == SpaceType.World
                                        ? TweenSpaceType.WorldRotation | rotateType
                                        : TweenSpaceType.LocalRotation | rotateType
            });
            _tweenPositions.Add(new TweenFloat3());

            var eulerAngles = spaceType == SpaceType.World
                                ? target.eulerAngles
                                : target.localEulerAngles;

            _tweenRotations.Add(new TweenRotation
            {
                from  = new quaternion(eulerAngles.x, eulerAngles.y, eulerAngles.z, 0),
                angle = angle
            });
            _tweenScales.Add(new TweenFloat3());
            _tweenPositionLifetimes.Add(new TweenLifetime());
            _tweenRotationLifetimes.Add(new TweenLifetime
            {
                duration          = Mathf.Max(0, duration),
                easeType          = easeType,
                loopType          = loopType,
                loopCount         = (short)Mathf.Clamp(loopCount, -1, short.MaxValue),
                originalLoopCount = (short)Mathf.Clamp(loopCount, -1, short.MaxValue)
            });
            _tweenScaleLifetimes.Add(new TweenLifetime());
            var hasEvents = onStart != null || onComplete != null;

            if (useTweenHandle || hasEvents)
            {
                var availableTweenHandle = GetNextAvailableTweenHandle();
                availableTweenHandle.state = useTweenHandle ? HANDLE_START_PAUSED : NO_HANDLE_START;
                if (onStart != null)
                {
                    availableTweenHandle.AddOnStartedListener(onStart);
                }

                if (onComplete != null)
                {
                    availableTweenHandle.AddOnCompletedListener(onComplete);
                }

                _tweenHandles.Add(availableTweenHandle);

                // Only populate the out parameter if explicitly called out for.
                if (useTweenHandle)
                {
                    tweenHandle = availableTweenHandle;
                }
            }
            else
            {
                _tweenHandles.Add(null);
            }
        }