예제 #1
0
        protected void UpdateTrackSlider(out SimpleTransform trackTangent)
        {
            //number of times we've "recursed" (emulated with a goto)
            int iterations = 0;

            Transform cartTransform = transform;
//		Transform cartTransform = guide.transform;

            //Estimate where we'll be in about a frame or so - this allows us to "lead"
            //the constraint's position and minimize error
            Vector3         tickMovement = cartTransform.GetComponent <Rigidbody>().velocity *leadFactor *Time.deltaTime;
            SimpleTransform carSoonPos   = new SimpleTransform(cartTransform);

            carSoonPos.position += tickMovement;
            if (DebugDrawTracking)
            {
                Debug.DrawRay(carSoonPos.position, Vector3.up, Color.yellow);
                Debug.DrawRay(cartTransform.position, Vector3.up, Color.white);
            }

            //DEBUG("now: " << m_rbB.getWorldTransform().position << " mv: " << tickMovement << " predicted: " << (carSoonPos.position + tickMovement));

            //goto label used to emulate a stateful tail-end recursion
            //todo: cars shouldn't be jumping far enough to need tail-end recursion, switch to a closure
            Profiler.BeginSample("Find position");
calculate:
            Track track = _currentTrack;

            //Position of cart
            var localCartPos = track.transform.InverseTransformPoint(carSoonPos.position);

            Profiler.BeginSample("Get current point");
            float pos = track.Curve.GetFraction(localCartPos);

            Profiler.EndSample();


            if (pos < 0)
            {
                //before the start
                //DEBUG("Before the start");
                if (track.PrevTrack && iterations == 0)
                {
                    //Move to the next track and run as that track
                    RollToNextTrack(false);
                    ++iterations;
                    goto calculate;
                }
                else if (track.PrevTrack)
                {
                    //we've hit the iteration limit, just go straight until next frame
                    pos = 0;
                }
                else
                {
                    //We're past the start with no previous.

                    if (_currentTrack.outOfTrack == Track.EndOfLineBehavior.FallOffTrack)
                    {
                        //wait until it's clear of the track (so it doesn't intersect with it), then drop it off
                        //(note that we use the cart's actual instead of projected position here)
                        if (Vector3.Distance(track.transform.position, cartTransform.position) >= clearingDistance)
                        {
                            RemoveFromTrack();
                        }
                    }
                    else if (_currentTrack.outOfTrack == Track.EndOfLineBehavior.ContinueStraight)
                    {
                        //do nothing special here, just keep going
                    }

                    // In all cases, set our guide to line up with the start of the track.
                    pos = 0;
                }
            }
            else if (pos > 1)
            {
                //past the end
                //DEBUG("After the end");
                if (track.NextTrack && iterations == 0)
                {
                    //Move to the next track and run as that track
                    RollToNextTrack(true);
                    ++iterations;
                    goto calculate;
                }
                else if (track.NextTrack)
                {
                    //we've hit the iteration limit, just go straight until next frame
                    pos = 1;
                }
                else
                {
                    //We're past the end with no next.

                    if (_currentTrack.outOfTrack == Track.EndOfLineBehavior.FallOffTrack)
                    {
                        //wait until it's clear of the track (so it doesn't intersect with it), then drop it off
                        if (Vector3.Distance(track.TrackAbsoluteEnd.position, cartTransform.position) >= clearingDistance)
                        {
                            RemoveFromTrack();
                        }
                    }
                    else if (_currentTrack.outOfTrack == Track.EndOfLineBehavior.ContinueStraight)
                    {
                        //do nothing special here, just keep going
                    }

                    // In all cases, set our guide to line up with the end of the track.
                    pos = 1;
                }
            }
            else
            {
                //calculate position normally
            }
            Profiler.EndSample();

            if (DebugDrawTracking)
            {
                var col = new Color(0, 0, 0, .3f);
                Debug.DrawLine(cartTransform.position, track.TrackAbsoluteEnd.position, col);
                Debug.DrawLine(cartTransform.position, track.transform.position, col);
            }
            //Debug.Log("d1: " + d1  + ", d2: " + d2 + " maxDist: " + maxDist);


            //Get position and direction at this point on the track
            Profiler.BeginSample("Get exact point");
            trackTangent = track.Curve.GetPointAt(pos).LocalToAbsolute(track.transform);
            Profiler.EndSample();

            if (cartReversed)
            {
                trackTangent.AboutFace();
            }

            if (DebugDrawTracking && _currentTrack)
            {
                //(these two should be more-or-less on top of each other, if there's a big divergence we have an issue)
                Debug.DrawRay(guide.transform.position, guide.transform.rotation * Vector3.forward, Color.red);
                Debug.DrawRay(guide.transform.position, guide.transform.rotation * Vector3.up, Color.blue);

                Debug.DrawRay(trackTangent.position, trackTangent.rotation * Vector3.forward, Color.red);
                Debug.DrawRay(trackTangent.position, trackTangent.rotation * Vector3.up, Color.blue);
            }


            //We tell the joint what rotation we want by feeding it two (unit) vectors.
            if (trackJoint)
            {
                //to trick Unity into recalculating the targeted internal transformations, we'll switch the rigidbody on the joint
                Rigidbody differentRb = guideJoint.connectedBody ? null : GetComponent <Rigidbody>();
                Rigidbody originalRb  = guideJoint.connectedBody;

                //switch rb so we can change things without fear
                guideJoint.connectedBody = differentRb;

                //move the guide to where we want it to be now
                guide.transform.position = trackTangent.position;
                guide.transform.rotation = trackTangent.rotation;

                //put the rb back as it should, causing Unity to recalculate the desired position for the joint
                guideJoint.connectedBody = originalRb;
            }
        }
예제 #2
0
 public void SwitchCurrentSectionTo(Track track)
 {
     CurrentTrack = track;
 }
 /** Sets our next track to "next" and moves our end to line up with its start. (Alias for SnapTogether(next, true, true).) */
 public void ConnectTo(Track next)
 {
     SnapTogether(next, true, true);
 }