Пример #1
0
    // Use this for initialization
    void Start()
    {
        m_creature         = GetComponent <Creature>();
        m_creatureFeet     = new List <Foot>();
        m_feetCountPerHip  = new Dictionary <BoneJoint, int>();
        m_movingFeetPerHip = new Dictionary <BoneJoint, int>();
        for (int i = 0; i < m_creature.m_feet.Count; i++)
        {
            Foot foot = new Foot(m_creature.m_feet[i].m_boneJoint);
            m_creatureFeet.Add(foot);
            if (m_feetCountPerHip.ContainsKey(foot.joint.closestBodyJoint))
            {
                m_feetCountPerHip[foot.joint.closestBodyJoint]++;
            }
            else
            {
                m_feetCountPerHip.Add(foot.joint.closestBodyJoint, 1);
                m_movingFeetPerHip.Add(foot.joint.closestBodyJoint, 0);
            }
        }
        m_debugJoint = m_creature.m_head;

        headHeight = 0;
        BoneJoint current = m_creature.m_head.m_boneJoint;

        while (current.nextJoints.Count > 0)
        {
            current     = current.nextJoints[0];
            headHeight += current.distanceFromLastBone;
        }
    }
Пример #2
0
 Sprite GetCorrectSprite(BoneJoint joint)
 {
     if (joint.isPartOfBody())
     {
         if (joint.previousJoint == null)
         {
             return(m_headSprite);
         }
         else
         {
             return(m_bodySprite);
         }
     }
     else
     {
         if (joint.nextJoints == null || joint.nextJoints.Count == 0)
         {
             return(m_feetSprite);
         }
         else
         {
             return(m_legSprite);
         }
     }
 }
Пример #3
0
    void MoveBodyJointTo(Vector2 finalPosition, Joint leadingJoint)
    {
        Vector2 constrainedPosition = finalPosition;
        float   headBob             = AddBobbing(leadingJoint.transform.position.x);

        headBob *= Mathf.Clamp01(Vector2.Distance(finalPosition, leadingJoint.transform.position) - m_headBobbingFadeOut);
        constrainedPosition.y += headBob;
        float distFromTarget = Vector2.Distance(leadingJoint.transform.position, finalPosition);

        for (int i = 0; i < m_creature.m_feet.Count; i++)
        {
            Joint     currentFoot          = m_creature.m_feet[i];
            Transform currentFootTransform = currentFoot.transform;
            BoneJoint closestBodyJoint     = currentFoot.m_boneJoint.closestBodyJoint;
            //Ignore this foot if it's closer to the target than the leading joint.
            if (Vector2.Distance(currentFoot.transform.position, finalPosition) < distFromTarget)
            {
                continue;
            }

            Vector2 constrainedToBodyJoint = GetPosLocked(currentFootTransform.position, closestBodyJoint.transform.position, currentFoot.m_boneJoint.maxDistanceFromBodyJoint);
            float   distance = closestBodyJoint.maxDistanceFromHead;
            distance           += currentFoot.m_boneJoint.maxDistanceFromBodyJoint - Vector2.Distance(currentFootTransform.position, closestBodyJoint.transform.position); //add any remaining distance
            constrainedPosition = GetPosLocked(constrainedToBodyJoint, constrainedPosition, distance);
        }
        Debug.DrawLine(leadingJoint.transform.position, constrainedPosition);
        float feetMovingRatio = m_creatureFeet.Count > 0 ? (m_currentMovingFeetCount / (1f * m_creatureFeet.Count)) : 1;
        float speed           = m_movementSpeed * Mathf.Lerp(m_nonMovingFeetSpeedFactor.x, m_nonMovingFeetSpeedFactor.y, 1f - feetMovingRatio);

        leadingJoint.transform.position = Vector2.MoveTowards(leadingJoint.transform.position, constrainedPosition, speed * Time.deltaTime);
        UpdatePosToNeighbours(leadingJoint);
    }
Пример #4
0
    public GameObject CreateSkeletonGameObject(Skeleton s, System.Random random)
    {
        GameObject creature = Instantiate(m_creaturePrefab);

        creature.GetComponent <Creature>().m_skeleton = s;
        List <BoneJoint> jointsToVisit = new List <BoneJoint>();

        jointsToVisit.Add(s.head);
        GameObject lastJointGO           = creature;
        float      bodyLineRendererScale = Mathf.Lerp(m_bodyLineRendererScaleMinMax.x, m_bodyLineRendererScaleMinMax.y, (float)random.NextDouble());
        float      legsLineRendererScale = Mathf.Lerp(m_legsLineRendererScaleMinMax.x, m_legsLineRendererScaleMinMax.y, (float)random.NextDouble());

        while (jointsToVisit.Count > 0)
        {
            BoneJoint currentJoint = jointsToVisit[0];
            if (currentJoint.previousJoint != null)
            {
                lastJointGO = currentJoint.previousJoint.gameObject;
            }
            GameObject currentJointGO = Instantiate(m_jointPrefab);
            currentJointGO.transform.parent     = creature.transform;// lastJointGO.transform;
            currentJointGO.transform.localScale = currentJoint.scale;
            currentJointGO.transform.position   = lastJointGO.transform.position;

            Vector2 pos = Utility.PolarToCartesian(currentJoint.distanceFromLastBone, currentJoint.angleFromLastBone);
            currentJointGO.transform.position += new Vector3(pos.x, pos.y, 0);
            currentJointGO.GetComponent <SpriteRenderer>().material.color = currentJoint.color;
            if (m_useSprites)
            {
                Sprite correctSprite = GetCorrectSprite(currentJoint);
                if (correctSprite != null)
                {
                    currentJointGO.GetComponent <SpriteRenderer>().sprite = correctSprite;
                }
            }
            Joint joint = currentJointGO.AddComponent <Joint>();
            joint.m_boneJoint = currentJoint;

            LineRenderer lr = currentJointGO.GetComponent <LineRenderer>();
            lr.SetPosition(0, currentJointGO.transform.position);
            lr.startColor = currentJoint.color;
            lr.startWidth = currentJoint.scale.x * (currentJoint.isPartOfBody() ? bodyLineRendererScale : legsLineRendererScale);
            lr.SetPosition(1, lastJointGO.transform.position);
            if (currentJoint.previousJoint != null)
            {
                lr.endWidth = currentJoint.previousJoint.scale.x * (currentJoint.previousJoint.isPartOfBody() ? bodyLineRendererScale : legsLineRendererScale);
                lr.endColor = currentJoint.previousJoint.color;
            }
            currentJoint.gameObject = currentJointGO;
            currentJoint.transform  = currentJointGO.transform;
            jointsToVisit.RemoveAt(0);
            if (currentJoint.nextJoints != null)
            {
                jointsToVisit.AddRange(currentJoint.nextJoints);
            }
        }
        return(creature);
    }
Пример #5
0
    public void StepForward(Foot foot, Vector2 targetDestination)
    {
        BoneJoint footJoint = foot.joint;

        if (foot.stepTargetDefined == false) // if this is the first frame in this step, figure out where the foot is going
        {
            bool foundSuitableNextStep = DefineNextStep(foot, targetDestination);
            if (foundSuitableNextStep == false)
            {
                return;
            }

            m_movingFeetPerHip[foot.joint.closestBodyJoint]++;
        }
        Vector2 footToTarget = (foot.currentTarget - ((Vector2)footJoint.transform.position));

        footToTarget = footToTarget.normalized;

        Vector2 pathToTarget;
        float   speed             = m_feetSpeed * Mathf.Lerp(m_nonMovingFeetSpeedFactor.x, m_nonMovingFeetSpeedFactor.y, 1f - (m_currentMovingFeetCount / (1f * m_creatureFeet.Count)));
        float   diffFromLastFrame = (speed * Time.deltaTime);

        pathToTarget.y = footJoint.transform.position.y + (diffFromLastFrame * footToTarget.y); //  targetIsAbove);
        pathToTarget.x = footJoint.transform.position.x + (diffFromLastFrame * footToTarget.x); // targetIsToTheRight);


        if (Vector2.Distance(footJoint.transform.position, pathToTarget) > Vector2.Distance(footJoint.transform.position, foot.currentTarget))
        {
            pathToTarget = foot.currentTarget;
        }
        else
        {
            // float xToYRatio = 1;
            // if (foot.currentTarget.y - foot.startStepPos.y != 0)
            //     xToYRatio = Mathf.Abs((foot.currentTarget.x - foot.startStepPos.x) / (foot.currentTarget.y - foot.startStepPos.y));

            float xDist = Mathf.Clamp01(Mathf.Abs((footJoint.transform.position.x - foot.currentTarget.x) / (foot.startStepPos.x - foot.currentTarget.x)));
            foot.stepCompleteness = completeness = 1f - xDist;
            Vector2 animationCurve = Vector2.zero;
            //  animationCurve.x = (m_legHeightCurve.Evaluate(foot.stepCompleteness) * foot.currentStepHeight);// * (1 - xToYRatio));
            animationCurve.y = (m_legHeightCurve.Evaluate(foot.stepCompleteness) * foot.currentStepHeight) * (speed * Time.deltaTime);// * xToYRatio);
            pathToTarget    += animationCurve;
        }

        m_targetVec = pathToTarget;
        footJoint.transform.position = Vector2.MoveTowards(footJoint.transform.position, pathToTarget, m_feetSpeed * Time.deltaTime);
        if (((Vector2)footJoint.transform.position) == foot.currentTarget)
        {
            foot.isGrounded        = true;
            foot.stepTargetDefined = false;
            m_movingFeetPerHip[foot.joint.closestBodyJoint]--;
        }
        else
        {
            foot.isGrounded = false;
        }
    }
Пример #6
0
    public BoneJoint GenerateRandomBoneJoint(BoneJoint previousJoint, float minJointScale, float maxJointScale, float minDist, float maxDist, float minAngleDiff, float maxAngleDiff, float perlinNoiseX, float perlinNoiseY, List <Color> ColorPalette, bool isLegJoint)
    {
        float dist   = minDist + (Mathf.PerlinNoise(perlinNoiseX, perlinNoiseY) * (maxDist - minDist));
        float angle  = minAngleDiff + (Mathf.PerlinNoise(perlinNoiseX, (perlinNoiseY + 0.1f)) * (maxAngleDiff - minAngleDiff));
        float xScale = minJointScale + (Mathf.PerlinNoise(perlinNoiseX, perlinNoiseY) * (maxJointScale - minJointScale));
        float yScale = xScale;
        Color color  = ColorPalette[(int)(Mathf.PerlinNoise(perlinNoiseX, perlinNoiseY) * ColorPalette.Count)];

        return(new BoneJoint(previousJoint, dist, angle, xScale, yScale, color, isLegJoint));
    }
Пример #7
0
    public void GenerateLeg(int jointCount, BoneJoint previousLegJoint, float perlinNoiseSeed, float perlinOffset, List <Color> palette)
    {
        float legScale        = m_minLegJointScale + (Mathf.PerlinNoise(perlinNoiseSeed, perlinNoiseSeed + 0.15f) * (m_maxLegJointScale - m_minLegJointScale));
        float legPerlinNoiseX = 0f;

        for (int k = 0; k < jointCount; k++)
        {
            BoneJoint newLegJoint = GenerateRandomBoneJoint(previousLegJoint, legScale, legScale, m_minLegDist, m_maxLegDist, m_minLegAngleDiff, m_maxLegAngleDiff, perlinNoiseSeed + perlinOffset + legPerlinNoiseX, perlinNoiseSeed + perlinOffset, palette, true);
            previousLegJoint.nextJoints.Add(newLegJoint);
            previousLegJoint = newLegJoint;
            legPerlinNoiseX  = (k * 1f) / jointCount;
        }
    }
Пример #8
0
    public BoneJoint GenerateRandomSkeletonJoints(int jointCount, int legCount, int legJointCount, List <Color> palette)
    {
        float     perlinNoiseSeed    = RandomFloat();       //without this we would get the same result every time
        float     perlinNoiseXOffset = RandomFloat() * 10f; //for nicer results we get a random subsection of the perlin noise
        float     perlinNoiseX       = 0f;
        BoneJoint firstJoint         = GenerateRandomBoneJoint(null, m_minJointScale, m_maxJointScale, 0, 0, 0, 0, perlinNoiseSeed + perlinNoiseX + perlinNoiseXOffset, perlinNoiseSeed + 0f, palette, false);

        if (jointCount == 1)
        {//if only a head and no other body joints, attach legs to head, otherwise never have head to leg connection
            for (int i = 0; i < legCount; i++)
            {
                GenerateLeg(legJointCount, firstJoint, perlinNoiseSeed, ((i * 1f) / legCount), palette);
            }
        }
        BoneJoint previousFrameJoint = firstJoint;
        int       leg = 0;

        int[] legIndexes = RandomIntArray(legCount, 1, jointCount - 1);
        for (int i = 1; i < jointCount; i++)
        {
            perlinNoiseX = (i * 1f + 1f) / jointCount;
            BoneJoint newJoint = GenerateRandomBoneJoint(previousFrameJoint, m_minJointScale, m_maxJointScale, m_minDist, m_maxDist, m_minAngleDiff, m_maxAngleDiff, perlinNoiseSeed + perlinNoiseX, perlinNoiseSeed + 0f, palette, false);
            previousFrameJoint.nextJoints.Add(newJoint);
            previousFrameJoint = newJoint;
            if (leg < legIndexes.Length)
            {
                for (int j = 0; j < legCount; j++)
                {
                    if (legIndexes[j] == i)
                    {
                        GenerateLeg(legJointCount, newJoint, perlinNoiseSeed, ((leg * 1f) / legCount), palette);
                        leg++;
                    }
                }
            }
        }
        return(firstJoint);
    }
Пример #9
0
 public float maxDistanceFromBodyJoint; //Only populated and used for feet
 public BoneJoint(BoneJoint previous, float distLastBone, float angLastBone, float xScale, float yScale, Color col, bool isPartOfLeg)
 {
     previousJoint        = previous;
     scale                = new Vector2(xScale, yScale);
     distanceFromLastBone = distLastBone;
     angleFromLastBone    = angLastBone;
     nextJoints           = new List <BoneJoint>();
     color                = col;
     if (isPartOfLeg)
     {
         type = BoneJointType.Leg;
     }
     else
     {
         type = BoneJointType.Body;
     }
     //  isLegJoint = isPartOfLeg;
     closestBodyJoint         = null;
     attachedFoot             = null;
     maxDistanceFromBodyJoint = 0;
     maxDistanceFromHead      = 0;
     distanceFromFoot         = 0;
 }
Пример #10
0
    private bool DefineNextStep(Foot foot, Vector2 targetDestination)
    {
        BoneJoint footJoint = foot.joint;

        foot.stepTargetDefined = true;
        Vector3 stepTarget        = footJoint.closestBodyJoint.transform.position;
        float   xDistTargetToFoot = targetDestination.x - footJoint.transform.position.x;
        float   stepWidth         = Random.Range(m_minFootStepWidth, m_maxFootStepWidth);

        stepTarget.x          += ((xDistTargetToFoot > 0) ? 1 : -1) * (stepWidth * footJoint.maxDistanceFromBodyJoint);
        stepTarget.y           = m_floorY;                                              //DEBUG until I implement raycasts
        foot.currentStepHeight = m_footStepHeight * footJoint.maxDistanceFromBodyJoint; // Random.Range(minRand, maxRand);
        foot.currentTarget     = GetPosLocked(footJoint.closestBodyJoint.transform.position, stepTarget, footJoint.maxDistanceFromBodyJoint * 0.8f);
        foot.currentTarget.y   = m_floorY;
        m_target = foot.currentTarget;

        m_vector2Gizmos       = foot.currentTarget;
        foot.stepCompleteness = 0;
        foot.startStepPos     = footJoint.transform.position;

        if (foot.startStepPos == foot.currentTarget) // if we are already here
        {
            Debug.LogError("oddly we are already here");
            foot.isGrounded        = true;
            foot.stepTargetDefined = false;
            return(false);
        }
        if (Vector3.Distance(foot.currentTarget, targetDestination) > Vector3.Distance(footJoint.transform.position, targetDestination))
        {
            //Debug.Log("the next step would be worse or equal");
            foot.isGrounded        = true;
            foot.stepTargetDefined = false;
            return(false);
        }
        return(true);
    }
Пример #11
0
    public void SetupFromHead()
    {
        feet = new List <BoneJoint>();
        List <BoneJoint> bodyJointsToVisit = new List <BoneJoint>();

        bodyJointsToVisit.Add(head);
        boneCount = 0;
        float     maxDistFromBodyJoint = 0f;
        float     maxDistFromHead      = 0f;
        BoneJoint latestBodyJoint      = null;

        while (bodyJointsToVisit.Count > 0)
        {
            BoneJoint currentJoint = bodyJointsToVisit[0];
            boneCount++;
            maxDistFromHead += currentJoint.distanceFromLastBone;
            currentJoint.maxDistanceFromHead = maxDistFromHead;
            latestBodyJoint      = currentJoint;
            maxDistFromBodyJoint = 0f;
            if (baseOfNeck == null)
            {
                if (currentJoint.nextJoints != null && currentJoint.nextJoints.Count >= 2)
                {
                    baseOfNeck = currentJoint;
                }
            }
            else if (currentJoint.nextJoints != null)
            {
                baseOfTail = currentJoint;
            }
            if (baseOfTail == null)
            {
                baseOfTail = currentJoint;
            }

            endOfTail = currentJoint;
            for (int i = 0; i < currentJoint.nextJoints.Count; i++)
            {
                BoneJoint nextJoint = currentJoint.nextJoints[i];
                if (nextJoint.isPartOfLeg())
                {
                    while (nextJoint != null)
                    {
                        boneCount++;
                        maxDistFromBodyJoint              += nextJoint.distanceFromLastBone;
                        nextJoint.maxDistanceFromHead      = maxDistFromHead + maxDistFromBodyJoint;
                        nextJoint.maxDistanceFromBodyJoint = maxDistFromBodyJoint;
                        nextJoint.closestBodyJoint         = latestBodyJoint;
                        if (nextJoint.nextJoints == null || nextJoint.nextJoints.Count == 0)
                        {
                            nextJoint.type = BoneJoint.BoneJointType.Foot;
                            feet.Add(nextJoint);
                            maxDistFromBodyJoint = 0f;
                            nextJoint            = null;
                        }
                        else
                        {
                            nextJoint = nextJoint.nextJoints[0];// No need to worry about other next joints as only a body joint can have multiple next joints
                        }
                    }
                }
                else
                {
                    bodyJointsToVisit.Add(nextJoint);
                }
            }
            bodyJointsToVisit.RemoveAt(0);
        }
        if (baseOfNeck == null)
        {
            baseOfNeck = head;
        }

        for (int i = 0; i < feet.Count; i++)
        {
            BoneJoint currentBonejoint = feet[i];
            float     dist             = 0;
            while (currentBonejoint.previousJoint != null && currentBonejoint.isPartOfLeg())
            {
                currentBonejoint.attachedFoot     = feet[i];
                currentBonejoint.distanceFromFoot = dist;
                currentBonejoint = currentBonejoint.previousJoint;
                dist            += currentBonejoint.distanceFromLastBone;
            }
            if (currentBonejoint != null && currentBonejoint.isPartOfBody())
            {
                currentBonejoint.type = BoneJoint.BoneJointType.Hip;
            }
        }
    }
Пример #12
0
 public Foot(BoneJoint footJoint)
 {
     joint = footJoint;
 }
Пример #13
0
    void FeedForward(Joint previous, Joint currentJoint)
    {
        if (previous.m_boneJoint == null || currentJoint.m_boneJoint == null)
        {
            return;
        }
        Vector2 previousJointPos = previous.transform.position;
        Vector2 currentJointPos  = currentJoint.transform.position;

        Vector2 targetPos = GetPosLocked(previousJointPos, currentJointPos, currentJoint.m_boneJoint.distanceFromLastBone, false);

        if (currentJoint.m_boneJoint.isPartOfLeg()) //is either a legjoint
        {
            if (currentJoint.m_boneJoint.nextJoints != null)
            {
                Vector3 footPos = currentJoint.m_boneJoint.attachedFoot.transform.position;

                float   maxDistFromFoot    = currentJoint.m_boneJoint.distanceFromFoot;
                float   maxDist            = currentJoint.m_boneJoint.maxDistanceFromBodyJoint + maxDistFromFoot;
                float   rotationToAddCurve = m_legCurve.Evaluate(maxDistFromFoot / maxDist);
                float   footToBodyAngle    = Vector2.Angle(Vector2.right, (Vector2)(currentJoint.m_boneJoint.closestBodyJoint.transform.position - footPos));
                Vector2 toAdd  = new Vector2(0, maxDistFromFoot / maxDist);
                Vector2 curved = (Quaternion.Euler(0, 0, footToBodyAngle * rotationToAddCurve) * toAdd) * m_legCurveStrength;
                curved += currentJointPos;

                Vector3 lockedPos = GetPosLocked(previousJointPos, curved, currentJoint.m_boneJoint.distanceFromLastBone, false);
                targetPos = GetPosLocked(footPos, lockedPos, currentJoint.m_boneJoint.distanceFromFoot, true);
            }
            else //if is a foot
            {
                targetPos = currentJointPos;
            }
        }
        else
        {
            if (currentJoint.m_boneJoint.type == BoneJoint.BoneJointType.Hip)
            {
                for (int i = 0; i < currentJoint.m_boneJoint.nextJoints.Count; i++)
                {
                    BoneJoint nextJoint = currentJoint.m_boneJoint.nextJoints[i];
                    if (nextJoint.isPartOfLeg())
                    {
                        Vector2 lockedTo    = nextJoint.attachedFoot.transform.position;
                        Vector2 jointMaxPos = GetPosLocked(lockedTo, nextJoint.transform.position, nextJoint.distanceFromFoot, true);
                        jointMaxPos = GetPosLocked(jointMaxPos, currentJointPos, nextJoint.distanceFromLastBone, false); //where the joint should be

                        targetPos = GetPosLocked(previousJointPos, jointMaxPos, currentJoint.m_boneJoint.distanceFromLastBone, false);
                        targetPos = GetPosLocked(lockedTo, targetPos, nextJoint.distanceFromFoot + nextJoint.distanceFromLastBone, true);
                        break;
                    }
                }
            }
            else
            {
                BoneJoint nextHip     = currentJoint.m_boneJoint;
                float     distFromHip = 0;
                int       i           = 0;
                while (nextHip.type != BoneJoint.BoneJointType.Hip && nextHip.nextJoints.Count > 0)
                {
                    nextHip      = nextHip.nextJoints[0];
                    distFromHip += nextHip.distanceFromLastBone;
                }
                Vector2 jointMaxPos = GetPosLocked(nextHip.transform.position, currentJointPos, distFromHip, true);
                targetPos = GetPosLocked(previousJointPos, jointMaxPos, currentJoint.m_boneJoint.distanceFromLastBone, false);
            }
        }
        currentJoint.transform.position = targetPos;//Vector2.MoveTowards(currentJoint.transform.position, targetPos, m_boneJointsLerpSpeed * Time.deltaTime);
        UpdatePosToNeighbours(currentJoint, previous);
    }