public WormWayPoint(Vector3 pos, Quaternion rot, bool vis, WormWayPoint nex = null)
 {
     position  = pos;
     rotation  = rot;
     visible   = vis;
     next      = nex;
     milestone = false;
 }
Beispiel #2
0
    //Body movement functions
    #region BodyMovement
    private void SetInitialBodyWayPoints()
    {
        headWayPoint = null;

        if (tailTrf != null)
        {
            headWayPoint = new WormWayPoint(tailTrf.position, tailTrf.rotation, false);
        }

        for (int i = bodySegmentsTrf.Length - 1; i >= 0; --i)
        {
            WormWayPoint segmentWayPoint = new WormWayPoint(bodySegmentsTrf[i].position, bodySegmentsTrf[i].rotation, false, (headWayPoint != null ? headWayPoint : null));
            headWayPoint = segmentWayPoint;
        }

        if (headTrf != null)
        {
            headWayPoint = new WormWayPoint(headTrf.position, headTrf.rotation, false, (headWayPoint != null ? headWayPoint : null));
        }
    }
Beispiel #3
0
    public void UpdateBodyMovement()
    {
        sinDistanceFactor = 360 / WanderingSettingsPhase.sinLongitude;
        sinTimeFactor     = 360 / WanderingSettingsPhase.sinCycleDuration;

        //If head has moved, create a new waypoint and recalculate all segments' position
        if ((headTrf.position != headWayPoint.position))
        {
            //Update sin time
            sinElapsedTime += Time.deltaTime;
            if (sinElapsedTime >= WanderingSettingsPhase.sinCycleDuration)
            {
                sinElapsedTime -= WanderingSettingsPhase.sinCycleDuration;
            }
            sinTimeOffset = sinElapsedTime * sinTimeFactor;

            headWayPoint = new WormWayPoint(headTrf.position, headTrf.rotation, head.IsVisible(), headWayPoint);

            WormWayPoint current = headWayPoint;
            WormWayPoint next    = current.next;
            //if we are in the last waypoint, there is nothing more we can do, so we quit
            if (next == null)
            {
                return;
            }

            float totalDistance        = headToJunctionDistance;                       //Total distance we have to position the element from the head
            float consolidatedDistance = 0f;                                           //Sum of the distances of evaluated waypoints
            float distanceBetween      = (current.position - next.position).magnitude; //Distance between current current and next waypoints

            float effectiveDistance;
            float totalOffset = 0f;
            if (applySinMovement)
            {
                totalOffset       = (Mathf.Sin((totalDistance * sinDistanceFactor) + sinTimeOffset) * WanderingSettingsPhase.sinAmplitude);
                effectiveDistance = totalDistance + totalOffset;
            }
            else
            {
                effectiveDistance = totalDistance;
            }

            //move each body segment through the virtual line
            for (int i = 0; i < bodySegmentsTrf.Length; ++i)
            {
                //---- Junction ----
                //advance through waypoints until we find the proper distance
                while (consolidatedDistance + distanceBetween < effectiveDistance)
                {
                    consolidatedDistance += distanceBetween;

                    current = next;
                    next    = current.next;
                    //if we are in the last waypoint, there is nothing more we can do, so we quit
                    if (next == null)
                    {
                        return;
                    }

                    distanceBetween = (current.position - next.position).magnitude;
                }

                //We reached the line segment where this body part must be, so we calculate the point in current segment
                float   remainingDistance = effectiveDistance - consolidatedDistance;
                Vector3 direction         = (next.position - current.position).normalized * remainingDistance;

                junctionsTrf[i].position = current.position + direction;
                junctionsTrf[i].rotation = Quaternion.Slerp(current.rotation, next.rotation, remainingDistance / distanceBetween);
                //junctionsTrf[i].Translate(0f, -totalOffset, 0f, Space.Self);
                junctionsTrf[i].gameObject.SetActive(current.visible || next.visible);

                //---- Body ----
                totalDistance += segmentToJunctionDistance;
                if (applySinMovement)
                {
                    totalOffset       = (Mathf.Sin((totalDistance * sinDistanceFactor) + sinTimeOffset) * WanderingSettingsPhase.sinAmplitude);
                    effectiveDistance = totalDistance + totalOffset;
                }
                else
                {
                    effectiveDistance = totalDistance;
                }

                //advance through waypoints until we find the proper distance
                while (consolidatedDistance + distanceBetween < effectiveDistance)
                {
                    consolidatedDistance += distanceBetween;

                    current = next;
                    next    = current.next;
                    //if we are in the last waypoint, there is nothing more we can do, so we quit
                    if (next == null)
                    {
                        return;
                    }

                    distanceBetween = (current.position - next.position).magnitude;
                }

                //We reached the line segment where this body part must be, so we calculate the point in current segment
                remainingDistance = effectiveDistance - consolidatedDistance;
                direction         = (next.position - current.position).normalized * remainingDistance;

                bodySegmentsTrf[i].position = current.position + direction;
                bodySegmentsTrf[i].rotation = Quaternion.Slerp(current.rotation, next.rotation, remainingDistance / distanceBetween);
                //bodySegmentsTrf[i].Translate(0f, -totalOffset, 0f, Space.Self);
                bodySegmentControllers[i].SetVisible(current.visible || next.visible);

                //if it was the final body part and there is no tail, release the oldest waypoints
                if (i == bodySegmentsTrf.Length - 1)
                {
                    if (tailTrf == null)
                    {
                        next.next = null; //Remove reference, let garbage collector do its job
                    }
                }
                //else add total distance for the next iteration
                else
                {
                    totalDistance += segmentToJunctionDistance;
                    if (applySinMovement)
                    {
                        totalOffset       = (Mathf.Sin((totalDistance * sinDistanceFactor) + sinTimeOffset) * WanderingSettingsPhase.sinAmplitude);
                        effectiveDistance = totalDistance + totalOffset;
                    }
                    else
                    {
                        effectiveDistance = totalDistance;
                    }
                }
            }

            //finally do the same for the tail
            if (tailTrf != null)
            {
                //---- Junction ----
                totalDistance += segmentToJunctionDistance;
                if (applySinMovement)
                {
                    totalOffset       = (Mathf.Sin((totalDistance * sinDistanceFactor) + sinTimeOffset) * WanderingSettingsPhase.sinAmplitude);
                    effectiveDistance = totalDistance + totalOffset;
                }
                else
                {
                    effectiveDistance = totalDistance;
                }

                //advance through waypoints until we find the proper distance
                while (consolidatedDistance + distanceBetween < effectiveDistance)
                {
                    consolidatedDistance += distanceBetween;

                    current = next;
                    next    = current.next;
                    //if we are in the last waypoint, there is nothing more we can do, so we quit
                    if (next == null)
                    {
                        return;
                    }

                    distanceBetween = (current.position - next.position).magnitude;
                }

                //We reached the line segment where this body part must be, so we calculate the point in current segment
                float   remainingDistance = effectiveDistance - consolidatedDistance;
                Vector3 direction         = (next.position - current.position).normalized * remainingDistance;

                junctionsTrf[junctionsTrf.Length - 1].position = current.position + direction;
                junctionsTrf[junctionsTrf.Length - 1].rotation = Quaternion.Slerp(current.rotation, next.rotation, remainingDistance / distanceBetween);
                junctionsTrf[junctionsTrf.Length - 1].gameObject.SetActive(current.visible || next.visible);

                //---- Tail ----
                totalDistance += tailToJunctionDistance;
                if (applySinMovement)
                {
                    totalOffset       = (Mathf.Sin((totalDistance * sinDistanceFactor) + sinTimeOffset) * WanderingSettingsPhase.sinAmplitude);
                    effectiveDistance = totalDistance + totalOffset;
                }
                else
                {
                    effectiveDistance = totalDistance;
                }

                //advance through waypoints until we find the proper distance
                while (consolidatedDistance + distanceBetween < effectiveDistance)
                {
                    consolidatedDistance += distanceBetween;

                    current = next;
                    next    = current.next;
                    //if we are in the last waypoint, there is nothing more we can do, so we quit
                    if (next == null)
                    {
                        return;
                    }

                    distanceBetween = (current.position - next.position).magnitude;
                }

                //We reached the line segment where this body part must be, so we calculate the point in current segment
                remainingDistance = effectiveDistance - consolidatedDistance;
                direction         = (next.position - current.position).normalized * remainingDistance;

                tailTrf.position = current.position + direction;
                tailTrf.rotation = Quaternion.Slerp(current.rotation, next.rotation, remainingDistance / distanceBetween);
                tailController.SetVisible(current.visible || next.visible);

                //search for milestones
                WormWayPoint aux = next;
                while (aux != null)
                {
                    if (aux.milestone)
                    {
                        aux.milestone        = false;
                        tailReachedMilestone = true;
                        break;
                    }
                    aux = aux.next;
                }
                aux = null;

                //release the oldest waypoints
                next.next = null; //Remove reference, let garbage collector do its job
            }
        }
    }