// Update is called once per frame void Update() { if (Time.frameCount - startFrame == 50 && !simulationStarted) { Debug.Log("Starting simulation."); ballRigidbody.gameObject.SetActive(true); bulletWorld.AddRigidBody(ballRigidbody); simulationStarted = true; startFrame = BPhysicsWorld.Get().frameCount; //first simulation ============================== ballPositionsOfflineSim = OfflineBallSimulation.SimulateBall(ballRigidbody, ballThrowImpulse, numberOfSimulationSteps, false); //Second simulation ===================== ballRigidbody.AddImpulse(ballThrowImpulse); for (int i = 0; i < ballPositionsOfflineSim.Count; i++) { Instantiate <GameObject>(ballGhostPrefab).transform.position = ballPositionsOfflineSim[i]; } } else if (simulationStarted && ballPositionsRealtime.Count < 500) { ballPositionsRealtime.Add(ballRigidbody.GetCollisionObject().WorldTransform.Origin.ToUnity()); } if (ballPositionsRealtime.Count == 500) { //prevent this clause from executing again ballPositionsRealtime.Add(Vector3.zero); } }
public void ExecuteBlastJump() { blastJumpToken = false; handledThisFrame = true; if (!timer.CheckAndReset()) { return; } BulletSharp.Math.Vector3 from = startRaycastFrom.position.ToBullet(); BulletSharp.Math.Vector3 to = (startRaycastFrom.position + startRaycastFrom.forward * maxBlastJumpRange).ToBullet(); ClosestRayResultCallback callback = new ClosestRayResultCallback(ref from, ref to); BPhysicsWorld.Get().world.RayTest(from, to, callback); if (enableDebugMode) { Debug.DrawLine(from.ToUnity(), to.ToUnity(), Color.green, 2f); } if (callback.HasHit) { float force = 0; Vector3 meToGround = callback.HitPointWorld.ToUnity() - transform.position; float dist = meToGround.magnitude; if (dist < maxBlastJumpRange) { //Falloff curve visual: https://www.desmos.com/calculator/plvrrosegp var b = 1f / (Mathf.Pow(maxBlastJumpRange, 2) * smallestBlastForce); force = blastJumpForce / (1 * maxBlastJumpForce + (falloffStrength * Mathf.Abs(dist)) + (b * Mathf.Pow(Mathf.Abs(dist), 2))); } rigidBody.AddImpulse(-meToGround.normalized * force); #region Debug if (enableDebugMode) { Debug.Log("Blasting off with a force of: " + force); var s = GameObject.CreatePrimitive(PrimitiveType.Sphere); s.transform.localScale = Vector3.one * .1f; s.transform.position = callback.HitPointWorld.ToUnity(); s.GetComponent <MeshRenderer>().material.color = Color.green; } #endregion } }
protected override void doGravity() { /* The gravity impulse code started out locally on the node script, now its defined as a global function on the graph controller, to have control over timing (slower=better) and easy control over it. * Having the impulses node-local and in FixedUpdate() was eating performance and becoming slow with many cubes, so next iteration was to move the function global and step down timing. * As these impulses here were nice tests (e.g. resulting in orbital spinning around center of universe, or framerate-independent braking), keeping them for reference * * // Prepared basic data. We want to apply global gravity pulling node towards center of universe * Vector3 dirToCenter = -1f * this.transform.position; * float distToCenter = dirToCenter.magnitude; * * // Variant 1: * // For usage in FixedUpdate. Simplified versions of dampening by cube self velocity. Did have some periodic pulsing effects. * //Vector3 impulse = dirToCenter - thisBRigidbody.velocity * globalGravity * globalGravityBrake; * //Vector3 impulse = dirToCenter - thisBRigidbody.velocity; * * // Variant 2: * // Apply brake in relation to distance, nearer is more braking power. Needs limiting max for distcenter<1. Using globalGravityBrake is easier, so this was given preference. * // Good for using in FixedUpdate() without need for m_linear_damping, as these permanent pulses will send the cube to universe center. * if (distToCenter < 1) * distToCenter = 1; * Vector3 impulse = dirToCenter - thisBRigidbody.velocity * globalGravity * (1 - 1 / distToCenter); * * // Variant 3: * // This iteration works as oneshot impulse that impulses the cube to the center when using m_linear_damping of 0.63. For using as oneshot, or in a custom-timed gravity function. * Vector3 impulse = dirToCenter * thisBRigidbody.mass; * * //Debug.Log("(FixedUpdate) hasRun: " + hasRun + ". thisBRigidbody: " + thisBRigidbody + ". Position: " + thisBRigidbody.transform.position + ". DistToCenter: " + distToCenter + ". Velocity: " + thisBRigidbody.velocity + ". globalGravity: " + globalGravity + ". nodeGravityBrake: " + globalGravityBrake + "; Adding impulse: " + impulse); * Debug.Log("(FixedUpdate) hasRun: " + hasRun + ". thisBRigidbody: " + thisBRigidbody + ". Position: " + thisBRigidbody.transform.position + ". dirToCenter: " + dirToCenter + ". DistToCenter: " + distToCenter + ". Velocity: " + thisBRigidbody.velocity + "; Adding impulse: " + impulse); * thisBRigidbody.AddImpulse(impulse); */ // See comments above for first version of node-local gravity impulses. These were nice tries @impulses. Node-local seemed too slow, so second version was moved in GraphController as one global function and test performance. // As it turned out that doing Gravity globally does not seem to make much difference, it was moved back local to the nodescript. The global routine did result in a different physical layout. And having it node-local is more elegant OO-wise. // BUT: Doing it a central place to be much more controllable. // Prepared basic data. We want to apply global gravity pulling node towards center of universe Vector3 dirToCenter = -thisBRigidbody.transform.position; float distToCenter = dirToCenter.magnitude; // This iteration works as oneshot impulse that impulses the cube to the center when using m_linear_damping of 0.63. Idea is to use it as oneshot in a custom-timed gravity function which runs less frequent. // Vector3 impulse = dirToCenter * nodeToApplyGravity.mass * globalGravityFactor; // This iteration pulls with equal force, regardless of distance. Slower and smoother. Could maybe still use some falloff towards center. Vector3 impulse = dirToCenter.normalized * thisBRigidbody.mass * graphControl.GlobalGravityBullet * (1 - 1 / distToCenter); // Debug.Log("(GraphController.ApplyGlobalGravity) nodeToGetGravity: " + nodeToApplyGravity + ". Position: " + nodeToApplyGravity.transform.position + ". dirToCenter: " + dirToCenter + ". DistToCenter: " + distToCenter + ". Velocity: " + nodeToApplyGravity.velocity + "; Adding impulse: " + impulse); thisBRigidbody.AddImpulse(impulse); }
private void ExecuteJump() { jumpToken = false; handledThisFrame = true; if (groundedChecker != null) { if (!groundedChecker.IsGrounded()) { return; } } rigidBody.AddImpulse(Vector3.up * jumpForce); jumpSFX.Stop(); jumpSFX.Play(); }
internal void doGravity() { m_collisionObject.WorldTransform = goParentCo.WorldTransform; //m_collisionObject.WorldTransform = ((CollisionObject)thisRb as CollisionObject); //transform.position = goParent.transform.position; for (int i = 0; i < goGhost.NumOverlappingObjects; i++) { CollisionObject otherGoCo = goGhost.GetOverlappingObject(i); // Todo: Check if BRigidBody can be disabled if everything works. Should be filtered by CollisionGroup+Mask if (otherGoCo.UserObject is BRigidBody) { BRigidBody hitRb = (BRigidBody)otherGoCo.UserObject as BRigidBody; if (hitRb != goParentRb) { //Debug.Log("BOnTriggerStay: this: " + this + ". go: " + go + ". goParentRb: " + goParentRb + ". / other: " + other + ". otherGoRb: " + otherGoRb); //Vector3 direction = otherGoCo.WorldTransform.Origin.ToUnity() - goGhost.WorldTransform.Origin.ToUnity(); //Vector3 direction = otherGoRb.gameObject.transform.position - this.transform.position; //Vector3 direction = otherGoRb.transform.position - goParentRb.transform.position; Vector3 direction = (otherGoCo.WorldTransform.Origin - goGhost.WorldTransform.Origin).ToUnity(); float distSqr = direction.sqrMagnitude; // only repulse if within Repulse Sphere Radius // if distSqr > sphRadiusSqr, the following impulseExpoFalloffByDist calc becomes negative. So only use it if distSqr was checked before or add a min/max limit. Otherwise nodes will be applied a negative impulse and go visit Voyager. float impulseExpoFalloffByDist = Mathf.Clamp(1 - (distSqr / sphRadiusSqr), 0, 1); Vector3 impulse = direction.normalized * graphControl.RepulseForceStrength * impulseExpoFalloffByDist; //Debug.Log("goGhostParent: " + goParent + ". goGhostPos: " + goGhost.WorldTransform.Origin.ToUnity() + ". otherGoRb: " + otherGoRb + ". otherGoRbPos: " + otherGoCo.WorldTransform.Origin.ToUnity() + // ". direction: " + direction + ". distanceSqr: " + distSqr + ". sphRadiusSqr: " + sphRadiusSqr + ". RepulseForceStrength: " + graphControl.RepulseForceStrength + ". linearImpulseFalloffByDist: " + impulseExpoFalloffByDist.ToString("F4") + ". Applying Impulse: " + impulse.ToString("F4")); hitRb.AddImpulse(impulse); //hitRb.AddImpulse(impulse * .5f); //thisRb.AddImpulse(-impulse * .5f); } } else { Debug.LogError("other.UserObject: " + otherGoCo + " is not a BRigidbody. Check CollisionGroups/Masks!"); } } }