Example #1
0
    /// <summary>
    /// Changes the length of the drake by modifying the last bone index
    /// </summary>
    /// <param name='newCount'>
    /// New bone count (superior bones will be disabled)
    /// </param>
    private void ChangeBoneCount(int newCount)
    {
        // Change index of last bone
        currentBoneCount = Mathf.Clamp(newCount, BONE_COUNT_MIN, bones.Length);

        // Update line renderer
        CreateBodyLine();

        // Update scales
        int cnt = 0;

        for (int i = 0; i < scales.Length; ++i)
        {
            DrakeScale s = scales[i];
            if (s.boneRef.index < currentBoneCount && i != 0)
            {
                if (!Helper.IsActive(scales[i].gameObject))
                {
                    Helper.SetActive(scales[i].gameObject, true);
                    if (scales[i].glowRef != null)
                    {
                        Helper.SetActive(scales[i].glowRef, true);
                    }
                    s.Shine();
                    // Note : they will be updated in their Start() method
                    //s.UpdateColorDistanceAutonomy();
                }
                else
                {
                    s.UpdateColorDistanceAutonomy();
                }
                ++cnt;
            }
            else
            {
                Helper.SetActive(scales[i].gameObject, false);
                if (scales[i].glowRef != null)
                {
                    Helper.SetActive(scales[i].glowRef, false);
                }
            }
        }

        currentScaleCount = cnt;

        // Update tail position
        DrakeBone lastBone = bones [currentBoneCount - 1];

        tail.transform.position = lastBone.pos;
    }
Example #2
0
    void Start()
    {
        #region "Check parameters"

        targetSpeed      = speedLimit.min;
        speed            = targetSpeed;
        wavingPhaseSpeed = wavingPhaseSpeedMax;
        // Default parameters
        if (currentBoneCount <= BONE_COUNT_MIN)
        {
            currentBoneCount = BONE_COUNT_MIN;
        }

        #endregion
        #region "Create bones"

        // Pre-allocate the maximum number of bones
        bones     = new DrakeBone[BONE_COUNT_MAX];
        bones [0] = new DrakeBone(transform.position, 0);
        for (int i = 1; i < bones.Length; i++)
        {
            DrakeBone prev = bones [i - 1];

            // Align as a straight line
            DrakeBone bone = new DrakeBone(
                prev.pos.x - BONE_SPACING, prev.pos.y, prev.pos.z, i);
            bone.angleRad = 0;

            // Linking
            bone.drakeRef = this;
            bone.parent   = prev;
            prev.child    = bone;

            bones [i] = bone;
        }

        #endregion
        #region "Create body line"

        CreateBodyLine();

        #endregion
        #region "Create scales"

        // Pre-allocate the maximum number of scales
        // (only a subset of them will be active)
        scales = new DrakeScale[SCALE_COUNT_MAX];
        float t_step = 1.0f / (float)scales.Length;

        for (int i = 0; i < scales.Length; ++i)
        {
            float t = t_step * i;

            // Get the bone where we will attach the scale
            DrakeBone bone = GetBoneFromParametric(t);

            // Compute a random scale ID
            int prefabIndex = UnityEngine.Random.Range(0, scalePrefabs.Length - 1);

            // Create scale
            GameObject scaleObject = Instantiate(
                scalePrefabs [prefabIndex],
                new Vector3(bone.pos.x, bone.pos.y, bone.pos.z),
                Quaternion.identity
                ) as GameObject;

            // Set its color
            //Material scaleMaterial = new Material (Shader.Find ("Diffuse"));
            //scaleMaterial.color = Color.black;
            MeshRenderer meshRenderer = scaleObject.GetComponent <MeshRenderer> ();
            meshRenderer.material = scaleMaterial;

            // Add scripts
            scaleObject.AddComponent("DrakeScale");
            scaleObject.AddComponent("PainterBehavior");

            // Add glow
            GameObject glowObj = null;
            if (i != 0)              // because the first scale is... well, not used (See below).
            {
                glowObj = Instantiate(glowPrefab) as GameObject;
            }

            // Get scale script and init some of its variables
            DrakeScale scaleScript = scaleObject.GetComponent <DrakeScale> ();
            scaleScript.boneRef            = bone;
            scaleScript.drakeRef           = this;
            scaleScript.glowRef            = glowObj;
            scaleScript.parametricPosition = t;
            scaleScript.indexedPosition    = i;
            //scaleScript.materialRef = scaleMaterial;
            scales[i] = scaleScript;

            // Fix scale size
            const float scaleFix = 1.15f;
            scaleObject.transform.localScale = new Vector3(scaleFix, scaleFix, scaleFix);

            // Set scale as child of the drake : not useful for now
        }

        // Disable first scale because it overlaps on the head
        // TODO dirty code, try to do this more cleanly
        Helper.SetActive(scales[0].gameObject, false);

        #endregion
        #region "Create tail"

        DrakeBone lastBone = bones [currentBoneCount - 1];
        tail = Instantiate(
            tailPrefab,
            new Vector3(lastBone.pos.x, lastBone.pos.y, lastBone.pos.z),
            Quaternion.identity
            ) as GameObject;

        // Set tail mesh color
        Material tailMaterial = new Material(Shader.Find("Diffuse"));
        tailMaterial.color = Color.black;
        tail.GetComponent <MeshRenderer>().material = tailMaterial;

        #endregion

        ChangeBoneCount(currentBoneCount);
        startBoneCount = currentBoneCount;
        //startScaleCount = currentScaleCount;

        if (Settings.trailerMode)
        {
            ChangeBoneCount(BONE_COUNT_MAX);
        }
    }
Example #3
0
    void Update()
    {
        if (!Settings.onTablet)
        {
            // This is just for debug. It enlarges the dragon (for free)
            if (Input.GetKeyDown(KeyCode.Space))
            {
                ChangeBoneCount(BONE_COUNT_MAX);
            }
        }

        #region "Head update"

        #region "Head speed"

        // Gravity :
        // The drake has more difficulty to go up,
        // and is helped by gravity when going down

        /*float gravityModifier = Vector3.Dot(Vector3.down, transform.right);
         * if(gravityModifier > 0)
         * {
         *      targetSpeed += gravityModifier * drakeGravity * Time.deltaTime;
         * }*/

        // Speed addition with drake ondulations
        float wavingSpeedAddition =
            wavingToSpeedAcceleration * Mathf.Cos(wavingPhase) * speedLimit.Mid * Time.deltaTime;
        if (wavingSpeedAddition > 0)
        {
            targetSpeed += wavingSpeedAddition;
        }

        // Speed reduction by air friction
        targetSpeed -= linearSpeedReduction * Time.deltaTime;
        targetSpeed -= quadraticSpeedReduction * targetSpeed * targetSpeed * Time.deltaTime;
        bool diving = false;
        // Effects of the sea
        if (Level.Get.IsWater(transform.position.x, transform.position.y))
        {
            // Speed is slowing
            // TODO maybe put this in friction code?
            //

            if (!lastFrameUnderwater)
            {
                if (transform.right.y < 0)
                {
                    OnSeaDive();
                    diving = true;
                }
                lastFrameUnderwater = true;
            }
        }
        else
        {
            if (lastFrameUnderwater)
            {
                if (transform.right.y > 0)
                {
                    OnSeaSurface();
                }
                lastFrameUnderwater = false;
            }
        }

        #endregion
        #region "Head rotation and waving"

        // Update phase
        if (wavingPhaseSpeed < wavingPhaseSpeedMax)
        {
            wavingPhaseSpeed += 2f * Time.deltaTime;
        }
        wavingPhase += wavingPhaseSpeed * Time.deltaTime;

        // Sine waving
        if (periodicSineDeviation != 0)
        {
            headRotationDeg += periodicSineDeviation * Mathf.Sin(wavingPhase);
        }

        // Noise waving
        if (randomDeviation != 0)
        {
            if (grabbedByHornets)
            {
                headRotationDeg += UnityEngine.Random.Range(-GRAB_ROTATION_RANDOM, GRAB_ROTATION_RANDOM);
            }
            else
            {
                headRotationDeg += randomDeviation * (Mathf.PerlinNoise(wavingPhase, 0) - 0.5f);
            }
        }

        #endregion
        #region "Head final application"

        // Make sure we don't go out of authorized speed
        targetSpeed = speedLimit.Clamp(targetSpeed);

        // Compute instant speed
        //speed = (targetSpeed - speed) * acceleration * Time.deltaTime;

        speed = Mathf.Lerp(speed, targetSpeed, acceleration * Time.deltaTime);
        if (diving)
        {
            speed      *= seaCoef;
            targetSpeed = 0f;
        }
        speed = speedLimit.Clamp(speed);

        // Update head rotation from target angle
        lastFrameHeadRotationDeg = headRotationDeg; // memorize last rotation
        headRotationDeg          = Mathf.LerpAngle(
            headRotationDeg,                        // Current
            targetHeadRotationDegNorm,              // Target
            // The faster it flies, the faster it turns
            rotationAbility.Lerp(speedLimit.GetT(speed)) * Time.deltaTime
            );

        // Rotate and move forward
        transform.rotation  = Quaternion.Euler(0f, 0f, headRotationDeg);
        transform.position += speed * transform.right * Time.deltaTime;

        #endregion
        #region "Paint splash"

        // Note from gamers point-of-view:
        // doing zig-zags shouldn't work because the angular speed
        // slightly crosses 0, and then resets splashTriggerTime.
        // The only way is to keep a constant angular speed, so make circles.

        if (Mathf.Abs(AngularSpeed) >= SPLASH_TRIGGER_ANGSPEED_DEG)
        {
            if (Time.time - splashTriggerTime >= SPLASH_TRIGGER_DELAY_S &&
                !HasMoonPaint &&
                !Level.Get.IsWater(transform.position.x, transform.position.y))
            {
                DoPaintSplash();
                splashTriggerTime = Time.time;
                if (!Settings.trailerMode)
                {
                    CommonSounds.Instance.playSplash();                     //michele
                }
            }
        }
        else
        {
            splashTriggerTime = Time.time;
        }

        #endregion

        #endregion
        #region "Body update"

        // The body must follow the head.
        bones [0].pos = transform.position;

        // Slightly offset body start (Kandinsky's head is transluscent)
        bones [0].pos.x -= transform.right.x;
        bones [0].pos.y -= transform.right.y;

        // Update core line
        for (uint i = 1; i < bones.Length; ++i)
        {
            bones [i].Update();
        }

        // Send positions to the line renderer
        for (int i = 0; i < currentBoneCount; ++i)
        {
            lineRenderer.SetPosition(i, bones[i].pos);
        }

        #endregion
        #region "Tail update"

        DrakeBone lastBone = bones [currentBoneCount - 1];

        tail.transform.position = lastBone.pos;
        tail.transform.rotation = Quaternion.Euler(90f, 0f, 0f);
        tail.transform.RotateAround(Vector3.forward, lastBone.angleRad + Mathf.PI);

        #endregion

        // Debug
        // Displays the barycenter of the dragon

        /*if(Settings.debugMode)
         * {
         *      Vector3 b = GetBarycenter();
         *      TmpDebug.Instance.transform.position = b;
         * //			Debug.DrawLine(
         * //				new Vector3(b.x-3, b.y-3, transform.position.z),
         * //				new Vector3(b.x-3, b.y-3, transform.position.z), Color.red, 0.5f);
         * }*/
    }