// This is a lot of complex math on choosing some "random" movement, keeping it near home and handling error cases. private void Movement(float speed, float chaos) { // Initialize a random number generator. Random rng = new Random(); // Pick a direction to start with - mostly in the X/Y plane, but just a little push up. Direction = new Sansar.Vector((float)(0.5 - rng.NextDouble()), (float)(0.5 - rng.NextDouble()), 0.02f, 0.0f); // This will just continually try to move the object (the Wait at the bottom is important!) while (true) { // Calculate how far we are from our home point. var distance = (RigidBody.GetPosition() - Home).GetMagnetude(); // Pick a new direction based on Chaos level, or if we have wandered off too far if (rng.NextDouble() <= Chaos || distance > Range) { // If we are far from home point us at home before adjusting the position. if (distance > Range) { // Move toward the center. Direction = Home - RigidBody.GetPosition(); Direction = Direction.Normalize(); // Note: still letting the randomize adjust the heading. } // This is the most bogus direction adjusting logic you will see today. Direction.X = Direction.X + (float)(0.5 - rng.NextDouble()); Direction.Y = Direction.Y + (float)(0.5 - rng.NextDouble()); Direction.Z = 0.02f; Direction = Direction.Normalize(); } // AddLinearImpulse can be picky on accepted values, especially if any math above breaks or the speed is set too high. // It will throw an exception if it doesn't like it. This will just skip try { Log.Write("PUSH! " + Direction.ToString() + " * " + speed + " => " + (Direction * speed).ToString()); RigidBody.AddLinearImpulse(Direction * speed); } catch (Exception e) { Log.Write("Exception " + e.GetType().ToString() + " in AddLinearImpulse for value: " + (Direction * speed).ToString()); // That direction was bad, so lets choose a new one. Direction.X = (float)(0.5 - rng.NextDouble()); Direction.Y = (float)(0.5 - rng.NextDouble()); Direction.Z = 0.02f; Direction = Direction.Normalize(); } // Wait after each push for between 0.5 and 1.5 seconds. Wait(TimeSpan.FromSeconds(0.5 + rng.NextDouble())); } }
void ApplyImpulse() { if (_resetCoroutine != null) { _resetCoroutine.Abort(); _resetCoroutine = null; } // Apply linear impulse force if (_applyLinearImpulse) { _rb.AddLinearImpulse(LinearImpulseDirection * LinearForce); } // Apply angular impulse force if (_applyAngularImpulse) { // Generate a new random angular impulse Vector angularImpulse = new Vector((float)_rng.NextDouble() * AngularVariance.X, (float)_rng.NextDouble() * AngularVariance.Y, (float)_rng.NextDouble() * AngularVariance.Z); // Apply the angular impulse if it is non-zero if (angularImpulse.LengthSquared() > 0.0f) { _rb.AddAngularImpulse(angularImpulse.Normalized() * AngularForce); } } if ((ResetTimeout > 0.0) && (_applyLinearImpulse || _applyAngularImpulse)) { _resetCoroutine = StartCoroutine(ResetAfterTimeout); } }
void ApplyImpulse() { // Apply linear impulse force if (_applyLinearImpulse) { _rb.AddLinearImpulse(LinearImpulseDirection * LinearForce); } // Apply angular impulse force if (_applyAngularImpulse) { // Generate a new random angular impulse Vector angularImpulse = new Vector((float)_rng.NextDouble() * AngularVariance.X, (float)_rng.NextDouble() * AngularVariance.Y, (float)_rng.NextDouble() * AngularVariance.Z); // Apply the angular impulse if it is non-zero if (angularImpulse.LengthSquared() > 0.0f) { _rb.AddAngularImpulse(angularImpulse.Normalized() * AngularForce); } } }
public override void Init() { if (ObjectPrivate.TryGetFirstComponent(out _rb)) { _rb.SetCanGrab(false); // Disable grabbing for this object if (_rb.GetMotionType() == RigidBodyMotionType.MotionTypeDynamic) { MyInteraction.Subscribe((InteractionData data) => { _rb.AddLinearImpulse(Vector.Up * 100.0f); }); } else { Log.Write(LogLevel.Warning, "RigidBodyImpulseScript not running on a dynamic object!"); } } else { Log.Write(LogLevel.Warning, "RigidBodyImpulseScript not running on an object with a physics volume!"); } }