public void PushAllEventsWithinDistance(float distance) { foreach (Tuple <float, CollisionEventData> pair in _items) { if (pair.Item1 > distance) { break; } CollisionEventData eventData = pair.Item2; eventData.MainEntity.ReceiveCollision(eventData); } _items.Clear(); }
protected override void OnPhysicsCollision(CollisionEventData eventData) { if (!IsServer) { return; } if (eventData.Entity is SandboxPlayer) { return; } var propData = GetModelPropData(); var minImpactSpeed = propData.MinImpactDamageSpeed; if (minImpactSpeed <= 0.0f) { minImpactSpeed = 500; } var impactDmg = propData.ImpactDamage; if (impactDmg <= 0.0f) { impactDmg = 10; } var speed = eventData.Speed; if (speed > minImpactSpeed) { if (eventData.Entity.IsValid() && eventData.Entity != this) { var damage = speed / minImpactSpeed * impactDmg * 1.2f; eventData.Entity.TakeDamage(DamageInfo.Generic(damage) .WithFlag(DamageFlags.PhysicsImpact) .WithFlag(DamageFlags.Vehicle) .WithAttacker(Driver != null ? Driver : this, Driver != null ? this : null) .WithPosition(eventData.Position) .WithForce(eventData.PreVelocity)); if (eventData.Entity.LifeState == LifeState.Dead && eventData.Entity is not SandboxPlayer) { PhysicsBody.Velocity = eventData.PreVelocity; PhysicsBody.AngularVelocity = eventData.PreAngularVelocity; } } } }
protected void ReflectBall(CollisionEventData eventData, float multiplier) { var reflect = Vector3.Reflect(eventData.PreVelocity.Normal, eventData.Normal.Normal).Normal; var normalDot = eventData.PreVelocity.Normal.Dot(eventData.Normal); // Don't do any reflection if we hit it at such an angle if (normalDot <= 0.10) { return; } // Collision sound happens at this point, not entity var sound = Sound.FromWorld(BounceSound.Name, eventData.Pos); sound.SetVolume(0.2f + Math.Clamp(eventData.Speed / 1250.0f, 0.0f, 0.8f)); sound.SetPitch(0.5f + Math.Clamp(eventData.Speed / 1250.0f, 0.0f, 0.5f)); var particle = Particles.Create("particles/ball_hit.vpcf", eventData.Pos); particle.SetPos(0, eventData.Pos); particle.Destroy(false); var newSpeed = Math.Max(eventData.PreVelocity.Length, eventData.Speed); newSpeed *= multiplier; // Adjust the speed depending on the hit normal, slight hit = more speed newSpeed *= (1 - normalDot / 2); var newVelocity = reflect * newSpeed; // TODO: not a fan of this, should determine by the dot normal newVelocity.z = 0; PhysicsBody.Velocity = newVelocity; PhysicsBody.AngularVelocity = Vector3.Zero; if (Debug) { DebugOverlay.Text(eventData.Pos, $"V {eventData.PreVelocity.Length} -> {newSpeed}", 5f); DebugOverlay.Text(eventData.Pos + Vector3.Up * 8, $"N. {normalDot}", 5f); DebugOverlay.Line(eventData.Pos, eventData.Pos - (eventData.PreVelocity.Normal * 64.0f), 5f); DebugOverlay.Line(eventData.Pos, eventData.Pos + (reflect * 64.0f), 5f); } }
/// <summary> /// Handle CollisionEntered events. /// </summary> /// <param name="evt"> /// The <see cref="IEvent"/> event to handle. /// </param> private void OnCollisionEntered(IEvent evt) { CollisionEventData data = (CollisionEventData)evt.EventData; BallComponent ball; if (!this.Game.ComponentSystem.TryGetComponent <BallComponent>(data.ColliderId, out ball)) { return; } // Why check here again? Because the check before was performed by a Unity bridge component, based on // the component being attached to a game object. You will want to check, whether the component is actually // being tracked by a component manager and probably access its values later. CollidableComponent collidable; if (!this.Game.ComponentSystem.TryGetComponent <CollidableComponent>(data.CollideeId, out collidable)) { return; } // Remember the last player, who touched the ball. PaddleComponent paddle; if (this.Game.ComponentSystem.TryGetComponent <PaddleComponent>(data.CollideeId, out paddle)) { ball.PlayerId = paddle.PlayerId; } // Reflect the ball off the collidable object. Collision collisionInfo = (Collision)data.Context; Vector3 velocity = Vector3.Reflect(ball.Velocity, collisionInfo.contacts[0].normal); // Make sure the velocity in Z direction is always zero. There should actually not ever be a value // zero value in Z as a result of reflecting a vector with value 0 the collision normal first place, // when considering a perfect spherical object, but ours is not a perfect sphere. velocity.z = 0.0f; // Make sure the ball is always moving vertically, as the game may be locked otherwise. velocity.x = Mathf.Max(0.5f, Mathf.Abs(velocity.x)) * Mathf.Sign(velocity.x); velocity.y = Mathf.Max(0.5f, Mathf.Abs(velocity.y)) * Mathf.Sign(velocity.y); ball.Velocity = velocity; }
public void Initialize(ScenarioController controller) { _sceneController = controller; var footData = new CollisionEventData { CollisionEnterAction = OnFootCollisionEnter, CollisionExitAction = OnFootCollisionExit }; _footColliderLogic.Initialize(footData); var frontData = new CollisionEventData { CollisionEnterAction = OnFrontCollisionEnter, CollisionExitAction = OnFrontCollisionExit }; _frontColliderLogic.Initialize(frontData); _rigidbody2D = GetComponent <Rigidbody2D>(); }
protected void NotifyTouchChanged(CollisionEventData col) { }
public void Initialize(CollisionEventData data) { _data = data; _collider = GetComponent <Collider2D>(); _initialized = true; }
public static unsafe float HitTest(ref Collider coll, ref CollisionEventData collEvent, ref DynamicBuffer <BallInsideOfBufferElement> insideOf, in BallData ball, float dTime)
public void CalculateDetailsTest() { // Simple collision event with straight normal and 3 contact points CollisionEventDataRef collisionEventData; unsafe { int length = CollisionEventData.CalculateSize(3); collisionEventData = new CollisionEventDataRef((CollisionEventData *)(UnsafeUtility.Malloc(length, 1, Allocator.Temp))); } collisionEventData.Value.BodyIndices.BodyAIndex = 0; collisionEventData.Value.BodyIndices.BodyBIndex = 1; collisionEventData.Value.ColliderKeys.ColliderKeyA = ColliderKey.Empty; collisionEventData.Value.ColliderKeys.ColliderKeyB = ColliderKey.Empty; collisionEventData.Value.Normal = new float3(0.0f, -1.00000f, 0.0f); collisionEventData.Value.NumNarrowPhaseContactPoints = 3; collisionEventData.Value.SolverImpulse = 1.0f; // Initialize 3 contact points collisionEventData.Value.AccessContactPoint(0) = new ContactPoint { Distance = 0.177905f, Position = new float3(-22.744950f, 2.585318f, -50.108990f) }; collisionEventData.Value.AccessContactPoint(1) = new ContactPoint { Distance = 0.276652f, Position = new float3(-20.731140f, 2.486506f, -50.322240f) }; collisionEventData.Value.AccessContactPoint(2) = new ContactPoint { Distance = 0.278534f, Position = new float3(-20.766140f, 2.484623f, -50.652630f) }; // Wrapping collision event CollisionEvent collisionEvent = new CollisionEvent(); collisionEvent.EventData = collisionEventData; collisionEvent.TimeStep = 1.0f / 60.0f; // Input velocity is obviously separating, but high angular velocity still caused an event collisionEvent.InputVelocityA = new Velocity { Angular = new float3(-0.00064f, 11.17604f, 0.02133f), Linear = new float3(-3.81205f, -0.56607f, 9.14945f) }; collisionEvent.InputVelocityB = new Velocity { Angular = new float3(0.00000f, 0.00000f, 0.00000f), Linear = new float3(0.00000f, 0.00000f, 0.00000f) }; // Allocate a simple world of 1 dynamic and 1 static body var simpleWorld = new Physics.PhysicsWorld(1, 1, 0); var motionVelocities = simpleWorld.MotionVelocities; var motionDatas = simpleWorld.MotionDatas; motionDatas[0] = new MotionData { LinearDamping = 0.0f, AngularDamping = 0.0f, GravityFactor = 1.0f, BodyFromMotion = new RigidTransform(new quaternion(0.0f, 0.0f, 0.0f, 1.0f), new float3(0.0f, 0.0f, 0.0f)), WorldFromMotion = new RigidTransform(new quaternion(0.09212853f, 0.1400256f, -0.006776567f, -0.9858292f), new float3(-22.17587f, 0.5172966f, -52.24425f)) }; motionVelocities[0] = new MotionVelocity { LinearVelocity = new float3(-3.81221f, -1.37538f, -15.41893f), AngularVelocity = new float3(-7.30913f, -4.78899f, 1.14168f), InverseInertia = new float3(0.00045f, 0.00045f, 0.00045f), InverseMass = 0.00018f, AngularExpansionFactor = 2.05061f }; // Calculate the collision event details and make sure 1 contact point is returned var details = collisionEvent.CalculateDetails(ref simpleWorld); Assert.AreEqual(details.EstimatedContactPointPositions.Length, 1); // Dispose the world data simpleWorld.Dispose(); }
/// <summary> /// Collides without triggering the animation, which is what the /// <see cref="Poly3DCollider"/> does. /// </summary> public static void Collide(ref BallData ball, ref NativeQueue <EventData> .ParallelWriter events, ref CollisionEventData collEvent, ref DynamicBuffer <BallInsideOfBufferElement> insideOfs, in Collider coll)
//bool sorted; internal void NotifyTouched(CollisionEventData col) { touchedObjects.Add(col.ColliderData.gameObject); SortList(); parent.Touched?.Invoke(); }
public void Add(float distance, CollisionEventData data) { _items.Add(new Tuple <float, CollisionEventData>(distance, data)); }
public static void Collide(ref BallData ball, ref NativeQueue <EventData> .ParallelWriter events, ref CollisionEventData collEvent, ref BumperRingAnimationData ringData, ref BumperSkirtAnimationData skirtData, in Collider collider, in BumperStaticData data, ref Random random)
protected void NotifyUnTouched(CollisionEventData col) { //if (touch.touchedObjects.Contains(col.ColliderData.gameObject)) touch.touchedObjects.Remove(col.ColliderData.gameObject); UnTouched?.Invoke(col.ColliderData); }
protected override void OnPhysicsCollision( CollisionEventData eventData ) { var speed = eventData.PreVelocity.Length; var direction = Vector3.Reflect( eventData.PreVelocity.Normal, eventData.Normal.Normal ).Normal; Velocity = direction * MathF.Min( speed * SpeedMul, MaxSpeed ); }
protected override void OnPhysicsCollision(CollisionEventData eventData) { return; }
public void ReceiveCollision(CollisionEventData eventData) { OnCollision?.Invoke(eventData); }
internal void NotifyUnTouched(CollisionEventData col) { touchedObjects.Remove(col.ColliderData.gameObject); parent.UnTouched?.Invoke(); }
internal void NotifyTouchChanged(CollisionEventData col) { }