示例#1
0
    // 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);
    }
示例#4
0
    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!");
            }
        }
    }