public void Execute([ReadOnly] ref Translation pos, [ReadOnly] ref Rotation rot, ref Move move)
            {
                //射线查询
                float3       dirNormal = Math.normalize(Math.mul(rot.Value, new float3(0, 0, 1)));
                RaycastInput input     = new RaycastInput()
                {
                    Ray = new Ray()
                    {
                        Origin    = pos.Value + dirNormal,
                        Direction = dirNormal * 1.1f
                    },
                    Filter = new CollisionFilter()
                    {
                        CategoryBits = ~0u, // all 1s, so all layers, collide with everything
                        MaskBits     = ~0u,
                        GroupIndex   = 0
                    }
                };
                RaycastHit hit = new RaycastHit();

                if (World.CastRay(input, out hit))
                {
                    move.isHit = 1;
                }
                else
                {
                    move.isHit = 0;
                }


                //检测碰撞,重设目标,移动。
                if (move.isHit == 0)
                {
                    if (Math.distancesq(move.targetPos, pos.Value) < 0.01)
                    {
                        move.targetPos = GetRandomTarget();
                        rot.Value      = quaternion.LookRotation(move.targetPos - pos.Value, new float3(0, 1, 0));
                    }
                    #region 加速度
                    if (move.speed < move.maxSpeed)
                    {
                        move.speed += move.acceleratioin * time;
                    }

                    pos.Value += Math.normalize(move.targetPos - pos.Value) * move.speed * time;
                    #endregion
                }
                else //碰到障碍,右转180度/秒
                {
                    move.speed     = 0; //减速
                    move.targetPos = math.rotate(quaternion.AxisAngle(new float3(0, 1, 0), (float)math.PI * time), (move.targetPos - pos.Value)) + pos.Value;
                    rot.Value      = quaternion.LookRotation(move.targetPos - pos.Value, new float3(0, 1, 0));
                }
            }
        // skip the turrets where we still reload
        // raycast currently hits itself. if raycast is shot outwards shoudnt it skip itself?
        // A could be 1) to add turret diameter/extend to Target to RaycastInput Start or 2) make the
        // turret itself not have a collider

        // TODO: turret range in Turret Component

        int GetClosestTarget(float3 position, float turretRange)
        {
            float curClosestDist = turretRange;
            int   curIndex       = -1;
            int   extend         = (int)(turretRange / cellRadius) + 1;

            var boidDictIndex = math.floor(position / cellRadius);

            for (int z = -extend; z <= extend; z++)
            {
                for (int y = -extend; y <= extend; y++)
                {
                    for (int x = -extend; x <= extend; x++)
                    {
                        var hash = (int)math.hash(new int3(boidDictIndex + new int3(x, y, z)));
                        NativeMultiHashMapIterator <int> i;
                        if (boidDict.TryGetFirstValue(hash, out int item, out i))
                        {
                            float dst = math.distance(boidPosition[item], position);
                            if (dst < curClosestDist)
                            {
                                var raycastInput = new RaycastInput {
                                    Start  = position,
                                    End    = boidPosition[item],
                                    Filter = CollisionFilter.Default
                                };
                                if (!physicsWorld.CastRay(raycastInput))
                                {
                                    curClosestDist = dst;
                                    curIndex       = item;
                                }
                            }
                            while (boidDict.TryGetNextValue(out item, ref i))
                            {
                                dst = math.distance(boidPosition[item], position);
                                if (dst < curClosestDist)
                                {
                                    var raycastInput = new RaycastInput {
                                        Start  = position,
                                        End    = boidPosition[item],
                                        Filter = CollisionFilter.Default
                                    };
                                    if (!physicsWorld.CastRay(raycastInput))
                                    {
                                        curClosestDist = dst;
                                        curIndex       = item;
                                    }
                                }
                            }
                        }
                    }
                }
            }

            return(curIndex);
        }
示例#3
0
 public void Execute()
 {
     if (CollectAllHits)
     {
         World.CastRay(RaycastInput, ref RaycastHits);
     }
     else if (World.CastRay(RaycastInput, out RaycastHit hit))
     {
         RaycastHits.Add(hit);
     }
 }
        static void HandleCompletePath(ComponentDataFromEntity <LocalToWorld> localToWorldFromEntity, Entity entity, Rotation rotation, ref NavAgent agent, Parent surface, Translation translation, PhysicsWorld physicsWorld, float elapsedSeconds, EntityCommandBuffer.ParallelWriter commandBuffer, int entityInQueryIndex, NavSettings settings)
        {
            var rayInput = new RaycastInput
            {
                Start  = localToWorldFromEntity[entity].Position + agent.Offset,
                End    = math.forward(rotation.Value) * settings.ObstacleRaycastDistanceMax,
                Filter = new CollisionFilter
                {
                    BelongsTo    = NavUtil.ToBitMask(settings.ColliderLayer),
                    CollidesWith = NavUtil.ToBitMask(settings.ObstacleLayer)
                }
            };

            if (
                !surface.Value.Equals(agent.DestinationSurface) &&
                !NavUtil.ApproxEquals(translation.Value, agent.LocalDestination, settings.StoppingDistance) &&
                !physicsWorld.CastRay(rayInput, out _)
                )
            {
                agent.JumpSeconds = elapsedSeconds;

                commandBuffer.RemoveComponent <NavWalking>(entityInQueryIndex, entity);
                commandBuffer.RemoveComponent <NavSteering>(entityInQueryIndex, entity);
                commandBuffer.AddComponent <NavJumping>(entityInQueryIndex, entity);
                commandBuffer.AddComponent <NavPlanning>(entityInQueryIndex, entity);

                return;
            }

            commandBuffer.RemoveComponent <NavWalking>(entityInQueryIndex, entity);
            commandBuffer.RemoveComponent <NavSteering>(entityInQueryIndex, entity);
            commandBuffer.RemoveComponent <NavDestination>(entityInQueryIndex, entity);
        }
示例#5
0
        public void Raycast_Against_RotatedBox_Test(
            [Values(0f, 10f, -20f, 30f, 40f)] float startX,
            [Values(0f, -10f, 30f, -50f, 70f)] float startY)
        {
            // Simulate the physics.
            SimulatePhysics();

            var aabb = RotatedBox.Aabb;

            Assert.IsTrue(startX < aabb.Min.x);

            var start            = new float2(startX, startY);
            var expectedPosition = new float2(aabb.Min.x + RayEpsilon, 0f);

            // Set-up the query.
            var input = new RaycastInput
            {
                Start = start,
                End   = expectedPosition,

                Filter = CollisionFilter.Default
            };

            // Perform the query.
            var results = PhysicsWorld.CastRay(input, out RaycastHit hit);

            Assert.IsTrue(results);
            Assert.IsTrue(hit.PhysicsBodyIndex != PhysicsBody.Constants.InvalidBodyIndex, "PhysicsBody Index is Invalid.");
            Assert.AreEqual(hit.Entity, RotatedBox.Entity, "Entity is invalid.");
            PhysicsAssert.AreEqual(expectedPosition, hit.Position, QueryEpsilon, "Hit position is incorrect.");
        }
示例#6
0
    // Update is called once per frame
    void LateUpdate()
    {
        if (!enabled)
        {
            return;
        }

        Vector3 newPositionFrom = (LookFrom == null) ? gameObject.transform.position : LookFrom.transform.position;
        Vector3 newPositionTo   = Vector3.forward;

        if (LookTo == null)
        {
            newPositionTo = gameObject.transform.rotation * newPositionTo;
        }
        else
        {
            newPositionTo = LookTo.transform.position;
        }

        PhysicsWorld world = World.Active.GetExistingManager <BuildPhysicsWorld>().PhysicsWorld;

        // check barrier
        {
            var rayInput = new RaycastInput
            {
                Ray    = { Origin = newPositionFrom, Direction = newPositionTo - newPositionFrom },
                Filter = CollisionFilter.Default
            };

            if (world.CastRay(rayInput, out RaycastHit rayResult))
            {
                newPositionFrom = rayResult.Position;
            }
        }

        if (Target != null)
        {
            // add velocity
            var em = World.Active.GetOrCreateManager <EntityManager>();
            var e  = Target.GetComponent <GameObjectEntity>();
            if ((em != null) && (e != null) && (e.Entity != Entity.Null))
            {
                Vector3 lv = world.GetLinearVelocity(world.GetRigidBodyIndex(e.Entity));
                lv *= Time.fixedDeltaTime;
                newPositionFrom += lv;
                newPositionTo   += lv;
            }
        }

        newPositionFrom = Vector3.Lerp(gameObject.transform.position, newPositionFrom, LookFromInterpolateFactor);
        newPositionTo   = Vector3.Lerp(oldPositionTo, newPositionTo, LookToInterpolateFactor);

        Vector3 newForward = newPositionTo - newPositionFrom;

        newForward.Normalize();
        Quaternion newRotation = Quaternion.LookRotation(newForward, Vector3.up);

        gameObject.transform.SetPositionAndRotation(newPositionFrom, newRotation);
        oldPositionTo = newPositionTo;
    }
示例#7
0
            /// <summary>
            /// 射线查询
            /// </summary>
            /// <param name="origin"></param>
            /// <param name="dir"></param>
            /// <returns></returns>
            int RayCast(float3 origin, float3 dir)
            {
                RaycastInput input = new RaycastInput()
                {
                    Ray = new Ray()
                    {
                        Origin    = origin,
                        Direction = dir
                    },
                    Filter = new CollisionFilter()
                    {
                        CategoryBits = ~0u, // all 1s, so all layers, collide with everything
                        MaskBits     = ~0u,
                        GroupIndex   = 0
                    }
                };
                RaycastHit hit = new RaycastHit();

                if (World.CastRay(input, out hit))
                {
                    return(1);
                }
                else
                {
                    return(0);
                }
            }
        public void Execute(Entity entity, int index, [ReadOnly] ref Bullet bullet, ref Translation translation, [ReadOnly] ref Rotation rotation)
        {
            var nextPosition = new Translation {
                Value = translation.Value + dt * bullet.moveSpeed * math.forward(rotation.Value)
            };

            CollisionFilter collisionFilter = new CollisionFilter()
            {
                BelongsTo    = ~0u,
                CollidesWith = ~0u,
                GroupIndex   = 0
            };
            RaycastInput raycastInput = new RaycastInput {
                Start  = translation.Value,
                End    = nextPosition.Value,
                Filter = collisionFilter
            };

            if (physicsWorld.CastRay(raycastInput, out RaycastHit hit))
            {
                Entity targetEntity = physicsWorld.CollisionWorld.Bodies[hit.RigidBodyIndex].Entity;
                var    hash         = (int)math.hash(new int2(targetEntity.Index, targetEntity.Version));
                damageDict.Add(hash, bullet.damage);

                commandBuffer.DestroyEntity(index, entity);
            }

            translation = nextPosition;
        }
示例#9
0
            public void Execute(int index)
            {
                var entity       = Entitys[index];
                var pp           = pps[entity];
                var wbc          = wbcs[entity];
                var localToWorld = localToWorlds[entity];
                var wbi          = wbis[entity];


                wbi.MaxLength = wbc.RestLength + wbc.SpringTravel;
                wbi.MinLength = wbc.RestLength - wbc.SpringTravel;

                var rbID   = physicsWorld.GetRigidBodyIndex(pp.Value);
                var filter = physicsWorld.GetCollisionFilter(rbID);

                RaycastInput input = new RaycastInput
                {
                    Start  = localToWorld.Position,
                    End    = localToWorld.Position + localToWorld.Up * wbi.MaxLength * -1,
                    Filter = filter
                };

                if (!physicsWorld.CastRay(input, out var hit))
                {
                    return;
                }


                wbi.LastLength     = wbi.SpringLength;
                wbi.SpringLength   = math.distance(input.Start, input.End) * hit.Fraction;
                wbi.SpringLength   = math.clamp(wbi.SpringLength, wbi.MinLength, wbi.MaxLength);
                wbi.SpringVelocity = (wbi.LastLength - wbi.SpringLength) / time;

                wbi.SpringForce = wbc.SpringStiffness * (wbc.RestLength - wbi.SpringLength);
                wbi.DamperForce = wbc.DamperStiffness * wbi.SpringVelocity;


                wbi.SuspensionForce = (wbi.SpringForce + wbi.DamperForce) * localToWorld.Up;

                // if ((wbi.SpringForce + wbi.DamperForce) < 0)
                // {
                //     wbi.SuspensionForce = float3.zero;
                // }

                TmpDatas[index] = (new tmpData()
                {
                    entity = entity,
                    wbi = wbi,
                    parentID = rbID,
                    LocalToWorld = localToWorld,
                    parentEntity = pp.Value,
                    hit = hit
                });
            }
示例#10
0
        public void Execute()
        {
            var raycastInput = new RaycastInput
            {
                Start  = transData.Value,
                End    = transData.Value + math.forward(rotData.Value) * laserData.distance,
                Filter = CollisionFilter.Default
            };

            if (collectAll)
            {
                physWorld.CastRay(raycastInput, ref raycastHits);
            }
            else
            {
                if (physWorld.CastRay(raycastInput, out Unity.Physics.RaycastHit hit))
                {
                    raycastHits.Add(hit);
                }
            }
        }
示例#11
0
    private static void FullUpdate(ref Translation position, ref Rotation rotation, ref BoidData boid, NativeArray <BoidData> boidsData,
                                   float agentNeighbourDistance, float agentAvoidDistance, float3 goalPos, float deltaTime,
                                   float minSpeed, float maxSpeed, Bounds bounds, uint baseSeed, float avoidCollidersDistance, PhysicsWorld world)
    {
        float3 direction = float3.zero;
        float3 forward   = math.forward(rotation.Value);
        bool   turning;

        RaycastInput rayInput = new RaycastInput
        {
            Start  = boid.CurrentPosition,
            End    = boid.CurrentPosition + avoidCollidersDistance * forward,
            Filter = CollisionFilter.Default
        };

        if (!bounds.Contains(boid.CurrentPosition)) //handle getting out of bounds
        {
            turning   = true;
            direction = (float3)bounds.center - boid.CurrentPosition;
        }
        else if (world.CastRay(rayInput, out Unity.Physics.RaycastHit hit))
        {
            turning   = true;
            direction = (float3)Vector3.Reflect(forward, hit.SurfaceNormal);
        }
        else
        {
            turning = false;
        }

        if (turning) //adjust path if needed
        {
            rotation.Value = math.slerp(rotation.Value, quaternion.LookRotation(direction, new float3(0, 1, 0)), boid.RotationSpeed * deltaTime);
        }
        else //random direction or direction calculated based on the flocking rules
        {
            Unity.Mathematics.Random rand = new Unity.Mathematics.Random(baseSeed + boid.Index);

            if (rand.NextInt(0, 100) < 10)
            {
                boid.Speed = rand.NextFloat(minSpeed, maxSpeed);
            }
            if (rand.NextInt(0, 100) < 20)
            {
                ApplyBoidRules(ref boid, ref rotation, boidsData, agentNeighbourDistance, agentAvoidDistance, goalPos, deltaTime);
            }
        }

        //move agent forward, along its direction
        position.Value      += boid.Speed * math.forward(rotation.Value) * deltaTime;
        boid.CurrentPosition = position.Value;
    }
        public bool CheckRay(float3 pos, float3 targetDir, ref float3 currentDir)
        {
            if (targetDir.Equals(-currentDir))
            {
                //don't let enemy do an abrupt 180
                return(true);
            }
            var ray = new RaycastInput()
            {
                Start  = pos,
                End    = pos + (targetDir * 0.9f),
                Filter = new CollisionFilter()
                {
                    GroupIndex       = 0,
                    BelongsTo        = 1u << 1,              //bitmasks, so using bitshifts
                        CollidesWith = 1u << 2
                }
            };
            var hit = pw.CastRay(ray, out Unity.Physics.RaycastHit closestHit);

            return(hit);           // ? math.length((closestHit.Position - pos)) : null;
        }
示例#13
0
            public bool CheckRay(float3 pos, float3 direction, float3 currentDirection)
            {
                if (direction.Equals(-currentDirection))
                {
                    return(true);
                }

                var ray = new RaycastInput
                {
                    Start  = pos,
                    End    = pos + direction * .9f,
                    Filter = new CollisionFilter
                    {
                        GroupIndex       = 0,
                        BelongsTo        = 1u << 1,
                            CollidesWith = 1u << 2
                    }
                };
                var ret = pw.CastRay(ray);

                return(pw.CastRay(ray));
            }
        public void Execute([ReadOnly] ref CharacterMovementData movementData, [ReadOnly] ref CharacterInputData inputs, ref Rotation rotation, [ReadOnly] ref Translation translation)
        {
            if (physicsWorld.CastRay(input, out var hit))
            {
                float3 hitPos = new float3(hit.Position.x, translation.Value.y, hit.Position.z);
                var    target = quaternion.LookRotationSafe(math.normalize(hitPos - translation.Value), math.up());
                var    newRot = new Rotation()
                {
                    Value = math.slerp(rotation.Value, target, 1f - math.exp(-movementData.rotationSharpness * deltaTime * movementData.rotationSpeed))
                };

                rotation = newRot;
            }
        }
        void Update()
        {
            if (Input.GetMouseButtonDown(0))
            {
                Ray ray = Camera.ScreenPointToRay(Input.mousePosition);

                var          world        = World.DefaultGameObjectInjectionWorld;
                PhysicsWorld physicsWorld = world.GetExistingSystem <BuildPhysicsWorld>().PhysicsWorld;

                var raycastInput = new RaycastInput
                {
                    Start  = ray.origin,
                    End    = ray.origin + ray.direction * int.MaxValue,
                    Filter = CollisionFilter.Default
                };
                if (!physicsWorld.CastRay(raycastInput, out var result))
                {
                    return;
                }


                EntityManager manager = world.EntityManager;

                //Search path
                var buffer   = manager.GetBuffer <PathBufferElement>(DOTSLocator.AgentEntity);
                var pathData = manager.GetComponentData <FollowPathData>(DOTSLocator.AgentEntity);
                if (pathData.PathStatus == PathStatus.EndOfPathReached)
                {
                    buffer.Clear();
                    manager.SetComponentData(DOTSLocator.AgentEntity, new FollowPathData {
                        PathIndex = 0, PathStatus = PathStatus.Calculated
                    });
                }

                var translation   = manager.GetComponentData <Translation>(DOTSLocator.AgentEntity);
                var requestEntity = manager.CreateEntity();
                manager.AddComponentData(requestEntity, new NavMeshPathfindingRequestData
                {
                    Start       = translation.Value,
                    Destination = result.Position,
                    Status      = PathSearchStatus.Requested,
                    Agent       = DOTSLocator.AgentEntity,
                    Extents     = Vector3.one * 2,
                    AgentTypeId = 0
                });
            }
        }
            public void Execute([ReadOnly] ref Translation pos, [ReadOnly] ref Rotation rot, ref Move move)
            {
                float3       dirNormal = Math.normalize(Math.mul(rot.Value, new float3(0, 0, 1)));
                RaycastInput input     = new RaycastInput()
                {
                    Ray = new Ray()
                    {
                        Origin    = pos.Value + dirNormal * 0.51f,
                        Direction = dirNormal * 1.1f
                    },
                    Filter = new CollisionFilter()
                    {
                        CategoryBits = ~0u, // all 1s, so all layers, collide with everything
                        MaskBits     = ~0u,
                        GroupIndex   = 0
                    }
                };
                RaycastHit hit = new RaycastHit();

                if (World.CastRay(input, out hit))
                {
                    // see hit.Position
                    move.isHit = 1;
                    // Debug.Log(hit.Position);
                }
                else
                {
                    move.isHit = 0;
                }


                //检测碰撞,重设目标,移动。
                if (move.isHit == 0)
                {
                    if (Math.distancesq(move.targetPos, pos.Value) < 0.01)
                    {
                        move.targetPos = GetRandomTarget();
                        rot.Value      = quaternion.LookRotation(move.targetPos - pos.Value, new float3(0, 1, 0));
                    }
                    pos.Value += Math.normalize(move.targetPos - pos.Value) * time;
                }
                else
                {
                    move.targetPos = GetRandomTarget();
                    rot.Value      = quaternion.LookRotation(move.targetPos - pos.Value, new float3(0, 1, 0));
                }
            }
示例#17
0
        public void Execute()
        {
            for (int i = 0; i < Projectiles.Length; i++)
            {
                CollisionFilter filter = CollisionFilter.Default;
                filter.CollidesWith = 4;

                RaycastInput raycastInput = new RaycastInput
                {
                    Start  = Projectiles[i].PreviousPosition,
                    End    = ProjectileTranslations[i].Value,
                    Filter = filter
                };
                MaxHitsCollector <RaycastHit> collector = new MaxHitsCollector <RaycastHit>(1.0f, ref RaycastHits);

                if (PhysicsWorld.CastRay(raycastInput, ref collector))
                {
                    if (collector.NumHits > 0)
                    {
                        RaycastHit closestHit = new RaycastHit();
                        closestHit.Fraction = 2f;

                        for (int j = 0; j < collector.NumHits; j++)
                        {
                            if (RaycastHits[j].Fraction < closestHit.Fraction)
                            {
                                closestHit = RaycastHits[j];
                            }
                        }

                        // Apply damage to hit rigidbody/collider
                        Entity hitEntity = PhysicsWorld.Bodies[closestHit.RigidBodyIndex].Entity;
                        if (HealthsFromEntity.Exists(hitEntity))
                        {
                            Health h = HealthsFromEntity[hitEntity];
                            h.Value -= Projectiles[i].Damage;
                            HealthsFromEntity[hitEntity] = h;
                        }

                        // Destroy projectile
                        entityCommandBuffer.DestroyEntity(ProjectileEntities[i]);
                    }
                }
            }
        }
示例#18
0
            public bool CheckRay(float3 position, float3 direction, float3 currentDirection)
            {
                if (direction.Equals(-currentDirection))
                {
                    return(true);
                }

                var ray = new RaycastInput()
                {
                    Start  = position,
                    End    = position + direction * DistanceDelta,
                    Filter = new CollisionFilter()
                    {
                        GroupIndex       = 0,
                        BelongsTo        = 1u << 1,
                            CollidesWith = 1u << 2
                    }
                };

                return(PhysicsWorld.CastRay(ray));
            }
示例#19
0
        /// <summary>Extension method for PhysicsWorld, checking for a valid
        /// position by raycasting onto the surface layer from the passed
        /// position. Returns true if the raycast is successful and a position
        /// via out.</summary>
        public static bool GetPointOnSurfaceLayer(this PhysicsWorld physicsWorld, LocalToWorld localToWorld, float3 position, out float3 pointOnSurface)
        {
            var rayInput = new RaycastInput()
            {
                Start  = position + localToWorld.Up * NavConstants.OBSTACLE_RAYCAST_DISTANCE_MAX,
                End    = position - localToWorld.Up * NavConstants.OBSTACLE_RAYCAST_DISTANCE_MAX,
                Filter = new CollisionFilter()
                {
                    BelongsTo    = ToBitMask(NavConstants.COLLIDER_LAYER),
                    CollidesWith = ToBitMask(NavConstants.SURFACE_LAYER)
                }
            };

            pointOnSurface = float3.zero;
            if (physicsWorld.CastRay(rayInput, out var hit))
            {
                pointOnSurface = hit.Position;
                return(true);
            }
            return(false);
        }
示例#20
0
        public bool CheckRay(float3 position, float3 direction, float3 currentDirection)
        {
            if (direction.Equals(-currentDirection))
            {
                return(true);
            }

            RaycastInput ray = new RaycastInput()
            {
                Start  = position,
                End    = position + (direction) * 0.9f,
                Filter = new CollisionFilter()
                {
                    BelongsTo        = 1u << 1,
                        CollidesWith = 1u << 2,
                        GroupIndex   = 0
                }
            };

            return(physicsWorld.CastRay(ray));
        }
示例#21
0
        public void Execute()
        {
            var raycastInput = new RaycastInput
            {
                Start  = input[0].RaycastStart,
                End    = input[0].RaycastEnd,
                Filter = new CollisionFilter
                {
                    BelongsTo        = 1 << 8,
                        CollidesWith = (1 << 4) | (1 << 0),
                        GroupIndex   = 0
                }
            };

            physicsWorld.CastRay(raycastInput, out Unity.Physics.RaycastHit closestHit);

            output[0] = new Output
            {
                Visible = (closestHit.RigidBodyIndex == physicsWorld.GetRigidBodyIndex(input[0].TargetEntity))
            };
        }
示例#22
0
        public bool RaycastCheck(float3 position, float3 direction, float3 currentDirection)
        {
            if (direction.Equals(-currentDirection))
            {
                return(true);
            }

            var ray = new RaycastInput()
            {
                Start  = position,
                End    = position + (direction * 0.9f),
                Filter = new CollisionFilter()
                {
                    GroupIndex       = 0,
                    BelongsTo        = 1u << 1,
                        CollidesWith = 1u << 2
                }
            };

            return(pw.CastRay(ray));
        }
示例#23
0
        public bool GetInputPos(out float3 resultPos)
        {
            resultPos = new float3(0, 0, 0);
            Ray ray = Camera.ScreenPointToRay(Input.mousePosition);

            var          world        = World.DefaultGameObjectInjectionWorld;
            PhysicsWorld physicsWorld = world.GetExistingSystem <BuildPhysicsWorld>().PhysicsWorld;

            var raycastInput = new RaycastInput
            {
                Start  = ray.origin,
                End    = ray.origin + ray.direction * int.MaxValue,
                Filter = CollisionFilter.Default
            };

            if (!physicsWorld.CastRay(raycastInput, out var result))
            {
                return(false);
            }
            resultPos = result.Position;
            return(true);
        }
示例#24
0
    private Entity Raycast(float3 fromPosition, float3 toPosition)
    {
        PhysicsWorld physicsWorld = World.DefaultGameObjectInjectionWorld.GetExistingSystem <BuildPhysicsWorld>().PhysicsWorld;

        RaycastInput raycastInput = new RaycastInput()
        {
            Start  = fromPosition,
            End    = toPosition,
            Filter = CollisionFilter.Default
        };

        Unity.Physics.RaycastHit raycastHit;
        if (physicsWorld.CastRay(raycastInput, out raycastHit))
        {
            Entity hitEntity = raycastHit.Entity;
            return(hitEntity);
        }
        else
        {
            return(Entity.Null);
        }
    }
示例#25
0
        /// <summary>Extension method for PhysicsWorld, checking for a valid
        /// position by raycasting onto the surface layer from the passed
        /// position. Returns true if the raycast is successful and a position
        /// via out.</summary>
        public static bool GetPointOnSurfaceLayer(this PhysicsWorld physicsWorld, LocalToWorld localToWorld, float3 position, out float3 pointOnSurface, float obstacleRaycastDistanceMax, int colliderLayer, int surfaceLayer)
        {
            var rayInput = new RaycastInput()
            {
                Start  = position + localToWorld.Up * obstacleRaycastDistanceMax,
                End    = position - localToWorld.Up * obstacleRaycastDistanceMax,
                Filter = new CollisionFilter()
                {
                    BelongsTo    = ToBitMask(colliderLayer),
                    CollidesWith = ToBitMask(surfaceLayer)
                }
            };

            pointOnSurface = float3.zero;

            if (physicsWorld.CastRay(rayInput, out var hit))
            {
                pointOnSurface = hit.Position;
                return(true);
            }

            return(false);
        }
示例#26
0
    protected override void OnUpdate()
    {
        RaycastHit   rayCastInfos;
        PhysicsWorld pw = physicSystem.PhysicsWorld;

        //Get Player InputsComponents
        InputComponent input = entityManager.GetComponentData <InputComponent>(GameVariables.Player.Entity);

        //Create ray cast
        UnityEngine.Ray camRay  = GameVariables.MainCamera.ScreenPointToRay(input.Mouse);
        RaycastInput    rayInfo = new RaycastInput
        {
            Start  = camRay.origin,
            End    = camRay.GetPoint(2000),
            Filter = new CollisionFilter
            {
                BelongsTo        = 1u << 31,
                    CollidesWith = 1u << 30,
                    GroupIndex   = 0
            }
        };

        //Create TargetData
        TargetData target = new TargetData();

        //Do ray cast
        if (pw.CastRay(rayInfo, out rayCastInfos))
        {
            var newPos = rayCastInfos.Position;
            newPos.x    += 0.5f;
            newPos.y     = 0f;
            target.Value = newPos;
        }

        //Set Player new TargetData
        entityManager.SetComponentData(GameVariables.Player.Entity, target);
    }
示例#27
0
        private void HandleUserInput(CharacterControllerComponentData ccComponentData, float3 up, float3 surfaceVelocity, float3 position, quaternion rotation,
                                     ref CharacterControllerInternalData ccInternalData, ref float3 linearVelocity)
        {
            // Reset jumping state and unsupported velocity
            if (ccInternalData.SupportedState == CharacterSupportState.Supported)
            {
                ccInternalData.IsJumping           = false;
                ccInternalData.UnsupportedVelocity = float3.zero;
            }

            // Movement and jumping
            bool   shouldJump = false;
            float3 requestedMovementDirection = float3.zero;
            {
                float3 forward = math.forward(quaternion.identity);
                float3 right   = math.cross(up, forward);

                float horizontal    = ccInternalData.Input.Movement.x;
                float vertical      = ccInternalData.Input.Movement.y;
                bool  jumpRequested = ccInternalData.Input.Jumped > 0;
                bool  haveInput     = (math.abs(horizontal) > float.Epsilon) || (math.abs(vertical) > float.Epsilon);
                if (haveInput)
                {
                    float3 localSpaceMovement = forward * vertical + right * horizontal;
                    float3 worldSpaceMovement = math.rotate(quaternion.AxisAngle(up, ccInternalData.CurrentRotationAngle), localSpaceMovement);
                    requestedMovementDirection = math.normalize(worldSpaceMovement);
                }
                shouldJump = jumpRequested && ccInternalData.SupportedState == CharacterSupportState.Supported;
            }

            // Turning
            {
                var raycastInput = new RaycastInput
                {
                    Start  = cameraWorldPoint,
                    End    = cameraWorldPoint + new float3(0, -20f, 0f),
                    Filter = new CollisionFilter()
                    {
                        BelongsTo      = ~0u,
                        CollidesWith   = 1u << 5,
                            GroupIndex = 0
                    }
                };
                if (!PhysicsWorld.CastRay(raycastInput, out var hit))
                {
                    return;
                }

                var playerToMouse = hit.Position - position;
                playerToMouse.y = 0f;
                playerToMouse   = math.normalize(playerToMouse);

                var forward = math.mul(rotation, new float3(0, 0, 1));

                var angle = MathHelper.SignedAngle(forward, playerToMouse, new float3(0, 1, 0));

                var horizontal = math.clamp(math.remap(-180f, 180f, -ccComponentData.RotationSpeed, ccComponentData.RotationSpeed, angle), -1f, 1f);
                var haveInput  = (math.abs(horizontal) > 0.01f);
                if (haveInput)
                {
                    ccInternalData.CurrentRotationAngle += horizontal * ccComponentData.RotationSpeed * DeltaTime;
                }
            }

            // Apply input velocities
            {
                if (shouldJump)
                {
                    // Add jump speed to surface velocity and make character unsupported
                    ccInternalData.IsJumping           = true;
                    ccInternalData.SupportedState      = CharacterSupportState.Unsupported;
                    ccInternalData.UnsupportedVelocity = surfaceVelocity + ccComponentData.JumpUpwardsSpeed * up;
                }
                else if (ccInternalData.SupportedState != CharacterSupportState.Supported)
                {
                    // Apply gravity
                    ccInternalData.UnsupportedVelocity += ccComponentData.Gravity * DeltaTime;
                }
                // If unsupported then keep jump and surface momentum
                linearVelocity = requestedMovementDirection * ccComponentData.MovementSpeed +
                                 (ccInternalData.SupportedState != CharacterSupportState.Supported ? ccInternalData.UnsupportedVelocity : float3.zero);
            }
        }
    protected override unsafe void OnUpdate()
    {
        Entities.ForEach(
            (ref CharacterControllerBody ccBodyComponentData,
             ref PhysicsCollider collider,
             ref PhysicsVelocity velocity,
             ref Translation position,
             ref Rotation rotation) =>
        {
            float3 up = math.up();

            ref PhysicsWorld world = ref World.Active.GetExistingSystem <BuildPhysicsWorld>().PhysicsWorld;
            // movement and firing
            {
                float x = Input.GetAxis("Horizontal");
                float z = Input.GetAxis("Vertical");
                ccBodyComponentData.IsJumping = Input.GetButtonDown("Jump") && ccBodyComponentData.IsSupported;

                bool haveInput = (Mathf.Abs(x) > Mathf.Epsilon) || (Mathf.Abs(z) > Mathf.Epsilon);
                if (!haveInput)
                {
                    ccBodyComponentData.MovementVector = float3.zero;
                }
                else
                {
                    float3 movement = math.rotate(quaternion.RotateY(ccBodyComponentData.RotationAngle), new float3(x, 0, z));
                    ccBodyComponentData.MovementVector = math.normalize(movement);
                }

                if ((ccBodyComponentData.GunArmEntity != Entity.Null) && EntityManager.HasComponent <Rotation>(ccBodyComponentData.GunArmEntity))
                {
                    float a         = -Input.GetAxis("ShootY");
                    Rotation gunRot = EntityManager.GetComponentData <Rotation>(ccBodyComponentData.GunArmEntity);
                    gunRot.Value    = math.mul(gunRot.Value, quaternion.Euler(math.radians(a), 0, 0));
                    EntityManager.SetComponentData(ccBodyComponentData.GunArmEntity, gunRot);

                    if (EntityManager.HasComponent <PhysicsGun>(ccBodyComponentData.GunArmEntity))
                    {
                        var gunFire      = EntityManager.GetComponentData <PhysicsGun>(ccBodyComponentData.GunArmEntity);
                        gunFire.isFiring = Input.GetButton("Fire1")? 1 : 0;
                        EntityManager.SetComponentData(ccBodyComponentData.GunArmEntity, gunFire);
                    }
                }
            }

            // Rotate
            {
                float x        = Input.GetAxis("ShootX");
                bool haveInput = (Mathf.Abs(x) > Mathf.Epsilon);
                if (haveInput)
                {
                    ccBodyComponentData.RotationAngle += x * ccBodyComponentData.RotationSpeed * Time.deltaTime;
                }

                rotation.Value = quaternion.AxisAngle(math.up(), ccBodyComponentData.RotationAngle);
            }

            // check supported
            {
                float3 rayStart = position.Value;
                float3 rayEnd   = rayStart + (ccBodyComponentData.CharacterHeight * -math.up());
                float3 rayDir   = rayEnd - rayStart;  // math.normalize(rayEnd - rayStart);

                var rayInput           = new RaycastInput();
                rayInput.Ray.Origin    = rayStart;
                rayInput.Ray.Direction = rayDir;
                rayInput.Filter        = collider.Value.Value.Filter;

                Unity.Physics.RaycastHit rayHit;
                bool hit = (world.CastRay(rayInput, out rayHit) && rayHit.SurfaceNormal.y > 0.5);
                if (ccBodyComponentData.IsSupported && !hit)
                {
                    ccBodyComponentData.InitialUnsupportedVelocity = velocity.Linear;
                }
                ccBodyComponentData.IsSupported = hit;
            }

            // tweak velocity
            //this.MovementVector = new float3(1, 0, 0);
            //this.IsJumping = true;
            {
                float3 lv          = velocity.Linear;
                lv                *= ccBodyComponentData.MovementDamping;
                bool bHaveMovement = ccBodyComponentData.IsJumping || (math.lengthsq(ccBodyComponentData.MovementVector) > (ccBodyComponentData.DeadZone * ccBodyComponentData.DeadZone));
                if (bHaveMovement)
                {
                    float y = lv.y;
                    if (ccBodyComponentData.IsSupported)
                    {
                        lv   = ccBodyComponentData.MovementSpeed * ccBodyComponentData.MovementVector;
                        lv.y = y;
                        if (ccBodyComponentData.IsJumping)
                        {
                            lv.y += ccBodyComponentData.JumpSpeed;
                            ccBodyComponentData.IsJumping = false;
                        }
                    }
                    else
                    {
                        ccBodyComponentData.InitialUnsupportedVelocity  *= ccBodyComponentData.MovementDamping;
                        ccBodyComponentData.InitialUnsupportedVelocity.y = y;
                        lv = ccBodyComponentData.InitialUnsupportedVelocity + (ccBodyComponentData.MovementSpeed * ccBodyComponentData.MovementVector);
                    }
                }

                velocity.Linear  = lv;
                velocity.Angular = float3.zero;
            }
        });  // ForEach
    protected override void OnUpdate()
    {
        var commandBuffer = new EntityCommandBuffer(Allocator.TempJob);

        Entities
        .WithName("InitializeCameraOldPositionsJob")
        .WithBurst()
        .WithNone <Initialized>()
        .ForEach((Entity entity, ref CameraSmoothTrackSettings cameraSmoothTrack, in LocalToWorld localToWorld) =>
        {
            commandBuffer.AddComponent <Initialized>(entity);
            cameraSmoothTrack.OldPositionTo = HasComponent <LocalToWorld>(cameraSmoothTrack.LookTo)
                    ? GetComponent <LocalToWorld>(cameraSmoothTrack.LookTo).Position
                    : localToWorld.Position + new float3(0f, 0f, 1f);
        }).Run();
        commandBuffer.Playback(EntityManager);
        commandBuffer.Dispose();

        PhysicsWorld world = m_BuildPhysicsWorld.PhysicsWorld;

        var timestep  = (float)m_RecordMostRecentFixedTime.MostRecentDeltaTime;
        var timeAhead = Time.DeltaTime / timestep;

        Entities
        .WithName("SmoothlyTrackCameraTargetsJob")
        .WithoutBurst()
        .WithAll <Initialized>()
        .WithReadOnly(world)
        .ForEach((CameraSmoothTrack monoBehaviour, ref CameraSmoothTrackSettings cameraSmoothTrack, in LocalToWorld localToWorld) =>
        {
            var worldPosition = (float3)monoBehaviour.transform.position;

            float3 newPositionFrom = HasComponent <LocalToWorld>(cameraSmoothTrack.LookFrom)
                    ? GetComponent <LocalToWorld>(cameraSmoothTrack.LookFrom).Position
                    : worldPosition;

            float3 newPositionTo = HasComponent <LocalToWorld>(cameraSmoothTrack.LookTo)
                    ? GetComponent <LocalToWorld>(cameraSmoothTrack.LookTo).Position
                    : worldPosition + localToWorld.Forward;

            // check barrier
            var rayInput = new RaycastInput
            {
                Start  = newPositionFrom,
                End    = newPositionTo,
                Filter = CollisionFilter.Default
            };

            if (world.CastRay(rayInput, out RaycastHit rayResult))
            {
                newPositionFrom = rayResult.Position;
            }

            if (cameraSmoothTrack.Target != Entity.Null)
            {
                // add velocity
                float3 lv        = world.GetLinearVelocity(world.GetRigidBodyIndex(cameraSmoothTrack.Target));
                lv              *= timeAhead;
                newPositionFrom += lv;
                newPositionTo   += lv;
            }

            newPositionFrom = math.lerp(worldPosition, newPositionFrom, cameraSmoothTrack.LookFromInterpolateFactor);
            newPositionTo   = math.lerp(cameraSmoothTrack.OldPositionTo, newPositionTo, cameraSmoothTrack.LookToInteroplateFactor);

            float3 newForward      = newPositionTo - newPositionFrom;
            newForward             = math.normalizesafe(newForward);
            quaternion newRotation = quaternion.LookRotation(newForward, math.up());

            monoBehaviour.transform.SetPositionAndRotation(newPositionFrom, newRotation);
            cameraSmoothTrack.OldPositionTo = newPositionTo;
        }).Run();
    }
示例#30
0
        /// <summary>Gets a point on a navigable surface (either the current surface or a jumpable one) for the provided agent entity via the out hit parameter. Returns true if there is a navigable surface, false if not.</summary>
        public static bool GetPointOnNavigableSurface(Vector3 point, Entity agentEntity, Camera cam, PhysicsWorld physicsWorld, float raycastDistance, EntityManager entityManager, CollisionFilter filter, out Unity.Physics.RaycastHit hit)
        {
            var screenPointToRay = cam.ScreenPointToRay(point);

            var rayInput = new RaycastInput
            {
                Start  = screenPointToRay.origin,
                End    = screenPointToRay.GetPoint(raycastDistance),
                Filter = filter
            };

            if (!physicsWorld.CastRay(rayInput, out hit) || hit.RigidBodyIndex == -1)
            {
                return(false);
            }

            if (!NavMesh.SamplePosition(hit.Position, out var navMeshHit, 1, NavMesh.AllAreas))
            {
                return(false);
            }

            var hitSurfaceEntity = physicsWorld.Bodies[hit.RigidBodyIndex].Entity;

            if (hitSurfaceEntity == Entity.Null)
            {
                return(false);
            }

            if (!entityManager.HasComponent <Parent>(agentEntity))
            {
                return(false);
            }

            var surfaceEntity = entityManager.GetComponentData <Parent>(agentEntity).Value;

            if (surfaceEntity == Entity.Null)
            {
                return(false);
            }

            if (surfaceEntity == hitSurfaceEntity)
            {
                return(true);
            }

            if (!entityManager.HasComponent <NavJumpableBufferElement>(surfaceEntity))
            {
                return(false);
            }

            var jumpableSurfaces = entityManager.GetBuffer <NavJumpableBufferElement>(surfaceEntity);

            for (var i = 0; i < jumpableSurfaces.Length; ++i)
            {
                if (hitSurfaceEntity == jumpableSurfaces[i])
                {
                    return(true);
                }
            }

            return(false);
        }