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); }
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); }
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."); }
// 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; }
/// <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; }
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 }); }
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); } } }
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; }
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)); } }
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]); } } } }
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)); }
/// <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); }
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)); }
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)) }; }
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)); }
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); }
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); } }
/// <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); }
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); }
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(); }
/// <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); }