Example #1
0
        protected override void OnUpdate()
        {
            if (!UpdateState())
            {
                return;
            }

            RaycastInput rayInput = RaycastUtils.RaycastInputFromRay(
                _mainCamera.ScreenPointToRay(Input.mousePosition),
                _filter
                );

            var raycastJob = new RaycastUtils.SingleRaycastJob
            {
                raycastInput = rayInput, physicsWorld = _physicsWorld
            };

            raycastJob.Execute();

            if (!raycastJob.hasHit)
            {
                return;
            }

            NativeEventStream.ThreadWriter writer = _eventSystem.CreateEventWriter <TEvent>();
            writer.Write(EventFromRaycastHit(raycastJob.hit, _state));
            _eventSystem.AddJobHandleForProducer <TEvent>(Dependency);
        }
Example #2
0
    public SuperspectiveRaycast GetRaycastHits()
    {
        Vector2 screenPos = PixelPositionOfReticle();

        Ray ray = cam.ScreenPointToRay(screenPos);

        return(RaycastUtils.Raycast(ray.origin, ray.direction, interactionDistance, layerMask));
    }
Example #3
0
    public SuperspectiveRaycast GetAnyDistanceRaycastHits()
    {
        Vector2 reticlePos = Reticle.instance.thisTransformPos;
        Vector2 screenPos  = Vector2.Scale(
            reticlePos,
            new Vector2(SuperspectiveScreen.currentWidth, SuperspectiveScreen.currentHeight)
            );

        Ray ray = cam.ScreenPointToRay(screenPos);

        return(RaycastUtils.Raycast(ray.origin, ray.direction, float.MaxValue, layerMask));
    }
    private void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            onTap(RaycastUtils.raycastObject(Camera.main));
        }

        if (Input.GetMouseButton(0))
        {
            currentSwipe?.onSwipeContinue();
        }

        if (Input.GetMouseButtonUp(0))
        {
            currentSwipe = null;
        }
    }
Example #5
0
    private Unity.Physics.RaycastHit SingleRaycast()
    {
        UnityEngine.Ray ray          = Camera.main.ScreenPointToRay(Input.mousePosition);
        RaycastInput    raycastInput = new RaycastInput {
            Start  = ray.origin,
            End    = ray.GetPoint(2000f),
            Filter = new CollisionFilter()
            {
                BelongsTo    = ~0u,
                CollidesWith = ~0u, // all 1s, so all layers, collide with everything
                GroupIndex   = 0
            }
        };

        Unity.Physics.RaycastHit hit = new Unity.Physics.RaycastHit();
        RaycastUtils.SingleRayCast(_world, raycastInput, ref hit, this.Dependency);
        return(hit);
    }
Example #6
0
        void HandlePointer()
        {
            isPointerUp["currentState"] = RaycastUtils.IsCameraLookingAtObject(this.gameObject, layersToConsider);

            // If state remains unchanged, don't invoke events
            if (isPointerUp["currentState"] == isPointerUp["previousState"])
            {
                return;
            }

            isPointerUp["previousState"] = isPointerUp["currentState"];

            if (isPointerUp["currentState"])
            {
                OnPointerEnter.Invoke();
            }
            else
            {
                OnPointerExit.Invoke();
            }
        }
Example #7
0
        private void Update()
        {
            if (Input.GetMouseButtonDown(0))
            {
                startPosition = RaycastUtils.raycastPositionWith(cam, y: 1);
            }

            if (Input.GetMouseButton(0))
            {
                Vector3?position = RaycastUtils.raycastPositionWith(cam, y: 1);
                if (position.HasValue)
                {
                    onJoystickMove.Invoke(position.Value);
                }
            }

            if (Input.GetMouseButtonUp(0))
            {
                startPosition = null;
                onFingerReleased.Invoke();
            }
        }
Example #8
0
    public void Update(Vector2 dimensions, Direction facingDir)
    {
        const float EPSILON = 0.1f;         //the extra amount to cast -> higher values make snapping more noticeable but provide more reliability and better adhesion to moving platforms.

        var position = transform.position.ToV2();

        float heightOffset = dimensions.y / 3;                                                     //gives our cast more room to detect the ground (guards cases where we overshoot cuz we are falling quickly)
        float castLength   = dimensions.x * Mathf.Tan(MAX_SLOPE_RADIANS) + heightOffset + EPSILON; //detect slopes of up to the maxDetectionAngle
        var   xOffset      = dimensions.x / 2f;

        var centerPoint = position;
        var leftPoint   = new Vector2(position.x - xOffset, position.y);
        var rightPoint  = new Vector2(position.x + xOffset, position.y);

        var centerRay = new Ray2D(position + Vector2.up * heightOffset, Vector2.down);
        var leftRay   = new Ray2D(leftPoint + Vector2.up * heightOffset, Vector2.down);
        var rightRay  = new Ray2D(rightPoint + Vector2.up * heightOffset, Vector2.down);

        CastInfo centerCast = RaycastUtils.Raycast(centerRay, castLength, GameUtils.Layers.GroundMask);
        CastInfo leftCast   = RaycastUtils.Raycast(leftRay, castLength, GameUtils.Layers.GroundMask);
        CastInfo rightCast  = RaycastUtils.Raycast(rightRay, castLength, GameUtils.Layers.GroundMask);

        CastInfo castInfo = centerCast.didHit ? centerCast : (leftCast.didHit ? leftCast : rightCast);

        SetGroundedInfo(castInfo, heightOffset + EPSILON, facingDir);

        CheckForStateChange();

        if (followMovingObjects)
        {
            ///Cover the case of moving platforms!
            if (IsGrounded && castInfo.didHit)
            {
                position.y         = castInfo.hitInfo.point.y;
                transform.position = position.ToV3();
            }
            ///TODO -> still need handling for horizontal movement of platforms; that is a bit more
            ///		involved though so ill leave it for now until some level design decisions are sorted
        }

#if DEBUG_MODE
        ///bottom positions on collider
        DebugUtils.DrawSquare(centerPoint, 0.035f, Color.yellow);
        DebugUtils.DrawSquare(leftPoint, 0.035f, Color.yellow);
        DebugUtils.DrawSquare(rightPoint, 0.035f, Color.yellow);

        if (centerCast.didHit)
        {
            DebugUtils.DrawSquare(centerCast.hitInfo.point, 0.05f, Color.blue);
        }
        if (leftCast.didHit && rightCast.didHit)
        {
            DebugUtils.DrawConnection(leftCast.hitInfo.point, rightCast.hitInfo.point, Color.blue, Color.blue, 0.05f);
        }
        else if (leftCast.didHit)
        {
            DebugUtils.DrawSquare(leftCast.hitInfo.point, 0.05f, Color.blue);
        }
        else if (rightCast.didHit)
        {
            DebugUtils.DrawSquare(rightCast.hitInfo.point, 0.05f, Color.blue);
        }

        DebugUtils.DrawArrow(centerRay.origin, centerRay.GetPoint(castLength), Color.red, 0.1f);
        DebugUtils.DrawArrow(leftRay.origin, leftRay.GetPoint(castLength), Color.red, 0.1f);
        DebugUtils.DrawArrow(rightRay.origin, rightRay.GetPoint(castLength), Color.red, 0.1f);

        DebugUtils.DrawArrow(position, position + GroundSlope * xOffset * 1.5f, Color.green, 0.1f);

        if (castInfo.didHit)
        {
            DebugUtils.DrawSquare(castInfo.hitInfo.point, 0.1f, Color.magenta);
        }
#endif
    }
Example #9
0
    protected override void OnUpdate()
    {
        _physicsWorldSystem = World.DefaultGameObjectInjectionWorld.GetExistingSystem <BuildPhysicsWorld>();
        _world = _physicsWorldSystem.PhysicsWorld.CollisionWorld;

        if (Input.GetMouseButtonDown(1) && !_isDragging)
        {
            Unity.Physics.RaycastHit hit = SingleRaycast();
            if (hit.Entity != Entity.Null)
            {
                // TODO this single raycast needs to hit a VALID terrain piece
                ShowAllDragIndicators();
                _dragStartPos = hit.Position;
                _isDragging   = true;
            }
            else
            {
                HideAllDragIndicators();
                _isDragging = false;
            }
        }
        else if (_isDragging && Input.GetMouseButton(1))
        {
            Unity.Physics.RaycastHit hit = SingleRaycast();
            float3 dragEndPos            = hit.Position;

            // Ignore dragging if some distance threshold is not met
            // Or if there are no selected formations
            if (hit.Entity == Entity.Null || math.distancesq(_dragStartPos, dragEndPos) < 5f)
            {
                isValidDrag = false;
                return;
            }

            // Check if its a valid drag for the # of selected formations
            var selectedFormations = GetSelectedFormations();
            if (!selectedFormations.IsCreated || selectedFormations.Length == 0)
            {
                Debug.Log("No formations selected");
                return;
            }

            var   numSelectedFormations = selectedFormations.Length;
            float dragDist = math.distance(_dragStartPos, dragEndPos);

            // TODO formation width may NOT be evenly split
            float formationWidth = dragDist / numSelectedFormations; // Width for each formation (evenly split)
            if (formationWidth < MIN_FORMATION_WIDTH)
            {
                return;
            }

            // Red line to show the width of drag
            //Debug.DrawLine(dragStartPos, dragEndPos, Color.red, 0f, true);

            // Preparing batch raycasts in between the two drag positions to get curvature of the terrain
            // TODO this can be jobified, right?
            float3     dragDir   = math.normalize(dragEndPos - _dragStartPos);
            quaternion rotateFor = quaternion.AxisAngle(new float3(0f, 1f, 0f), math.radians(-90f));
            float3     dragFor   = math.mul(rotateFor, dragDir);
            _dragForward = dragFor;

            var numSelectedUnits = _selectedFormationUnitQuery.CalculateEntityCount();
            if (!TEMP_SLOT_ASSIGNMENTS.IsCreated)
            {
                TEMP_SLOT_ASSIGNMENTS = new NativeArray <float3>(numSelectedUnits, Allocator.Persistent, NativeArrayOptions.UninitializedMemory);
            }
            else if (TEMP_SLOT_ASSIGNMENTS.Length != numSelectedUnits)
            {
                // Very common case to have to resize
                TEMP_SLOT_ASSIGNMENTS.Dispose();
                TEMP_SLOT_ASSIGNMENTS = new NativeArray <float3>(numSelectedUnits, Allocator.Persistent, NativeArrayOptions.UninitializedMemory);
            }

            var raycastInputs        = new NativeArray <RaycastInput>(numSelectedUnits, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
            var formationUnitIndices = new NativeArray <int>(numSelectedFormations, Allocator.Temp, NativeArrayOptions.UninitializedMemory);

            // TODO Calculate centroid of each formation. Assign formations accordingly.

            var currUnitIndex = 0;
            for (int i = 0; i < selectedFormations.Length; i++)
            {
                var currFormation = selectedFormations[i];

                // Filters to an existing query to calculate unit count for one formation
                _selectedUnitQuery.SetSharedComponentFilter(currFormation);
                int numUnits = _selectedUnitQuery.CalculateEntityCount();

                var raycastInputsSlice = raycastInputs.Slice(currUnitIndex, numUnits);

                numUnitsPerRow = math.clamp((int)(formationWidth / _distanceApart), MIN_FORMATION_WIDTH, MAX_FORMATION_WIDTH);

                // Draws the forward direction of the formation in white
                //Debug.DrawRay(math.lerp(dragStartPos, dragEndPos, 0.5f), dragFor);

                float3 startPoint = math.lerp(_dragStartPos, dragEndPos, (float)i / selectedFormations.Length);

                // TODO not working
                CollisionFilter raycastFilter = new CollisionFilter()
                {
                    BelongsTo    = _walkableLayer,
                    CollidesWith = _walkableLayer,
                    GroupIndex   = 0
                };


                #region Creating raycast inputs
                int    levels = numUnits / numUnitsPerRow;
                float3 forwardOffset;
                for (int currLevel = 0; currLevel < levels; currLevel++)
                {
                    forwardOffset = dragFor * currLevel * _distanceApart;
                    for (int j = 0; j < numUnitsPerRow; j++)
                    {
                        float3 sideOffset  = dragDir * _distanceApart * j;
                        float3 currUnitPos = startPoint + sideOffset - forwardOffset;
                        raycastInputsSlice[j + (numUnitsPerRow * currLevel)] = new RaycastInput {
                            Start  = currUnitPos + new float3(0f, 20f, 0f),
                            End    = currUnitPos - new float3(0f, 20f, 0f),
                            Filter = raycastFilter
                        };
                        // DEBUG
                        //Debug.DrawLine(currUnitPos, currUnitPos + new float3(0f, 1f, 0f), Color.blue);
                    }
                }
                // For the remainder units in the back
                int    calculatedUnits = numUnitsPerRow * levels; // The number of units we have finished calculating
                int    remainderUnits  = numUnits % numUnitsPerRow;
                float3 middlePos       = (startPoint + (dragDir * numUnitsPerRow / 2 * _distanceApart)) - (dragDir * _distanceApart * remainderUnits / 2);
                forwardOffset = dragFor * levels * _distanceApart;
                for (int j = 0; j < remainderUnits; j++)
                {
                    float3 sideOffset  = dragDir * _distanceApart * j;
                    float3 currUnitPos = middlePos + sideOffset - forwardOffset;
                    raycastInputsSlice[calculatedUnits + j] = new RaycastInput {
                        Start  = currUnitPos + new float3(0f, 5f, 0f),
                        End    = currUnitPos - new float3(0f, 5f, 0f),
                        Filter = raycastFilter
                    };

                    // DEBUG
                    //Debug.DrawLine(currUnitPos, currUnitPos + new float3(0f, 1f, 0f), Color.green);
                }

                formationUnitIndices[i] = currUnitIndex;
                currUnitIndex          += numUnits;

                #endregion
            }

            NativeArray <float3> raycastResults = new NativeArray <float3>(numSelectedUnits, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
            // Runs the batch of raycasts
            // TODO schedule these raycasts all at once. This is very slow
            var handle = RaycastUtils.ScheduleBatchRayCastPosition(_world, raycastInputs, raycastResults, Dependency, out var hasFailed);
            handle.Complete();
            raycastInputs.Dispose();

            if (hasFailed)
            {
                Debug.Log("Dragging failed, disposing raycast results");
                raycastResults.Dispose();
                return;
            }

            ShowSelectedDragIndicators();

            var handles = new NativeArray <JobHandle>(selectedFormations.Length, Allocator.TempJob);

            var translations = GetComponentDataFromEntity <Translation>(false);
            var rotations    = GetComponentDataFromEntity <Rotation>(false);
            for (int i = 0; i < selectedFormations.Length; i++)
            {
                var currFormation      = selectedFormations[i];
                var unitPositionsSlice = raycastResults.Slice(formationUnitIndices[i]);

                handles[i] = Entities
                             .WithName("AlignUnitDragIndicators")
                             .WithReadOnly(unitPositionsSlice)
                             .WithAll <DragIndicatorTag, Translation, Rotation>()
                             .WithSharedComponentFilter(currFormation)
                             .WithNativeDisableContainerSafetyRestriction(translations)
                             .WithNativeDisableContainerSafetyRestriction(rotations)
                             .ForEach((Entity entity, int entityInQueryIndex) =>
                {
                    translations[entity] = new Translation
                    {
                        Value = unitPositionsSlice[entityInQueryIndex] + new float3(0f, 0.1f, 0f)
                    };
                    rotations[entity] = new Rotation {
                        Value = quaternion.LookRotation(dragFor, math.up())
                    };
                }).ScheduleParallel(Dependency);
            }

            new CopyFloat3Job
            {
                Output = TEMP_SLOT_ASSIGNMENTS,
                Input  = raycastResults
            }.Schedule(raycastResults.Length, 128, JobHandle.CombineDependencies(handles)).Complete();

            isValidDrag = true;
            handles.Dispose();
            formationUnitIndices.Dispose();
        }
        else if (isValidDrag && Input.GetMouseButtonUp(1))
        {
            isValidDrag = false;

            EaseOfAssignmentUnitAssignment();
            //SpatialUnitAssignmnet();
        }
        else
        {
            _isDragging = false;
            if (Input.GetKey(KeyCode.Space))
            {
                ShowAllDragIndicators();
            }
            else
            {
                HideAllDragIndicators();
            }
        }

        _endSimulationEcbSystem.AddJobHandleForProducer(this.Dependency);
    }
Example #10
0
        private void OnWideSelection(float3 startPos, float3 endPos)
        {
            var upperBound = new float3(
                math.max(startPos.x, endPos.x),
                0f,
                math.min(startPos.z, endPos.z)
                );
            var lowerBound = new float3(
                math.min(startPos.x, endPos.x),
                0f,
                math.max(startPos.z, endPos.z)
                );
            BlobAssetReference <Collider> collider = RaycastUtils.GetBoxCollider(
                upperBound,
                lowerBound,
                new CollisionFilter
            {
                BelongsTo = ~0u, CollidesWith = (uint)CollisionLayer.Grid, GroupIndex = 0
            }
                );
            var maxNewElements = _selectionList.Length * 2 + 1;

            var hits          = new NativeList <ColliderCastHit>(Allocator.TempJob);
            var hitEntities   = new NativeList <Entity>(Allocator.TempJob);
            var entitiesToAdd =
                new NativeList <Entity>(maxNewElements, Allocator.TempJob)
            {
                Length = maxNewElements
            };
            var entitiesToRemove =
                new NativeList <Entity>(maxNewElements, Allocator.TempJob)
            {
                Length = maxNewElements
            };
            var totalEntities = new NativeList <Entity>(Allocator.TempJob);

            JobHandle boxCastJob = new RaycastUtils.ColliderCastJob
            {
                physicsWorld = _physicsWorld,
                hits         = hits,
                origin       = upperBound / 2f + lowerBound / 2f,
                collider     = collider
            }.Schedule(_physicsSystem.GetOutputDependency());
            var boxCastDep = JobHandle.CombineDependencies(
                Dependency,
                _physicsSystem.GetOutputDependency(),
                boxCastJob
                );

            JobHandle convertJob = new ConvertHitsToEntitiesJob
            {
                hits          = hits,
                hitEntities   = hitEntities,
                selectionList = _selectionList,
                totalEntities = totalEntities
            }.Schedule(boxCastDep);
            var convertDep = JobHandle.CombineDependencies(boxCastDep, convertJob);

            hits.Dispose(convertDep);

            JobHandle getSelectionDiffJob = new GetSelectionDiffJob
            {
                totalEntities    = totalEntities,
                selectionList    = _selectionList,
                hitEntities      = hitEntities,
                entitiesToAdd    = entitiesToAdd,
                entitiesToRemove = entitiesToRemove
            }.Schedule(totalEntities, 1, convertDep);
            var getSelectionDiffDep = JobHandle.CombineDependencies(
                convertDep,
                getSelectionDiffJob
                );

            hitEntities.Dispose(getSelectionDiffDep);
            totalEntities.Dispose(getSelectionDiffDep);

            JobHandle selectJob = new SetSelectionJob
            {
                selectionList  = entitiesToAdd,
                select         = true,
                parallelWriter = _ecbSystem.CreateCommandBuffer()
                                 .AsParallelWriter()
            }.Schedule(entitiesToAdd, 1, getSelectionDiffDep);
            JobHandle unselectJob = new SetSelectionJob
            {
                selectionList  = entitiesToRemove,
                select         = false,
                parallelWriter = _ecbSystem.CreateCommandBuffer()
                                 .AsParallelWriter()
            }.Schedule(entitiesToRemove, 1, getSelectionDiffDep);
            var selectionJobDep = JobHandle.CombineDependencies(
                getSelectionDiffDep,
                selectJob,
                unselectJob
                );

            JobHandle updateSelectionJob = new UpdateSelectionJob
            {
                selectionList    = _selectionList,
                entitiesToAdd    = entitiesToAdd,
                entitiesToRemove = entitiesToRemove
            }.Schedule(selectionJobDep);
            var updateSelectionDep = JobHandle.CombineDependencies(
                selectionJobDep,
                updateSelectionJob
                );

            entitiesToAdd.Dispose(updateSelectionDep);
            entitiesToRemove.Dispose(updateSelectionDep);

            _selectionJobHandle = updateSelectionDep;
        }
Example #11
0
        public void Update()
        {
            var hit      = RaycastUtils.CastClickRay(settings.TargetLayers);
            var mousePos = Input.mousePosition;

            //Do we allow draggin? And Is The target the same from the click start?  And has the mouse not moved much?
            bool isDrag = settings.AllowDragging &&
                          (hit.collider == null || hit.collider != mouseDownTarget) &&
                          Vector2.Distance(mousePos, mouseDownPosition) > settings.dragStartDistance;

            //Click Start
            if (Input.GetMouseButtonDown(settings.Button))
            {
                //mouseDownTime = Time.time;
                mouseDownPosition          = Input.mousePosition;
                mouseDownRealWorldPosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
                mouseDownTarget            = hit.collider;
            }
            //Dragging
            else if (Input.GetMouseButton(settings.Button))
            {
                if (!isDrag)
                {
                    if (OnClickHold != null)
                    {
                        OnClickHold(new TargetingArguments(hit.collider, hit.point));
                    }
                }
                else
                {
                    RaycastHit[] allHits = RaycastUtils.BoxSelect(settings.TargetLayers, mouseDownPosition);
                    if (OnMultiSelectHover != null)
                    {
                        OnMultiSelectHover(allHits.Select(h => new TargetingArguments(h.collider, h.point)).ToArray());
                    }
                }
            }
            //Released
            else if (Input.GetMouseButtonUp(settings.Button))
            {
                if (!isDrag)
                {
                    if (OnClicked != null)
                    {
                        OnClicked(new TargetingArguments(hit.collider, hit.point));
                    }
                }
                else
                {
                    RaycastHit[] allHits = RaycastUtils.BoxSelect(settings.TargetLayers, mouseDownPosition);
                    if (OnMultiSelect != null)
                    {
                        OnMultiSelect(allHits.Select(h => new TargetingArguments(h.collider, h.point)).ToArray());
                    }
                }
            }
            else
            //Just Hovering
            {
                if (OnHover != null)
                {
                    OnHover(new TargetingArguments(hit.collider, hit.point));
                }
            }
        }