Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.

using Mathf.PerlinNoise for camera shake?

Discussion in 'Scripting' started by Nigey, Nov 2, 2013.

  1. Nigey

    Nigey

    Joined:
    Sep 29, 2013
    Posts:
    1,129
    Hi Guys,

    I wanted to make a little camera shake. Pretty simple really. The camera moves to one position and then never moves again. I don't understand the perlinnoise function enough to know what's going wrong.

    Code (csharp):
    1.  
    2. public class CameraEffects : MonoBehaviour {
    3.    
    4.     public GameObject object;
    5.     Vector3 setPosition;
    6.     float minPerlin = -1.0f, maxPerlin = 1.0f;
    7.    
    8.     // Use this for initialization
    9.     void Start ()
    10.     {
    11.         setPosition = transform.position;
    12.     }
    13.    
    14.     // Update is called once per frame
    15.     void Update ()
    16.     {
    17.        
    18.         Vector3 newPos;
    19.        
    20.         newPos = setPosition;
    21.        
    22.         newPos.x =  Mathf.PerlinNoise( newPos.x * minPerlin, newPos.x * maxPerlin);
    23.         newPos.y =  Mathf.PerlinNoise( newPos.y * minPerlin, newPos.y * maxPerlin);
    24.        
    25.         transform.position = newPos;
    26.     }
    27. }
    28.  
    Can anyone give any insight please?
     
  2. fenderrio

    fenderrio

    Joined:
    Mar 2, 2013
    Posts:
    147
  3. CreativeMatter

    CreativeMatter

    Joined:
    Dec 13, 2013
    Posts:
    2
    I wrote a method that returns a Vector2 in the range of -1 to 1 for each axis using the default Unity Perlin noise. .You can modify persistance and lacunarity values for more than one octave to achieve a more natural and unpredictable behaviour. I've also added a bursting behaviour that will make values peak randomly controlled by sampling an extra Perlin noise.
    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public static class NoiseGen
    4. {
    5.     public static Vector2 Shake2D(float amplitude, float frequency, int octaves, float persistance, float lacunarity, float burstFrequency, int burstContrast, float time)
    6.     {
    7.         float valX = 0;
    8.         float valY = 0;
    9.  
    10.         float iAmplitude = 1;
    11.         float iFrequency = frequency;
    12.         float maxAmplitude = 0;
    13.  
    14.         // Burst frequency
    15.         float burstCoord  = time / (1 - burstFrequency);
    16.  
    17.         // Sample diagonally trough perlin noise
    18.         float burstMultiplier = Mathf.PerlinNoise(burstCoord, burstCoord);
    19.  
    20.         //Apply contrast to the burst multiplier using power, it will make values stay close to zero and less often peak closer to 1
    21.         burstMultiplier =  Mathf.Pow(burstMultiplier, burstContrast);
    22.  
    23.         for (int i=0; i < octaves; i++) // Iterate trough octaves
    24.         {
    25.             float noiseFrequency = time / (1 - iFrequency) / 10;
    26.  
    27.             float perlinValueX = Mathf.PerlinNoise(noiseFrequency, 0.5f) ;
    28.             float perlinValueY = Mathf.PerlinNoise(0.5f, noiseFrequency);
    29.  
    30.             // Adding small value To keep the average at 0 and   *2 - 1 to keep values between -1 and 1.
    31.             perlinValueX = (perlinValueX + 0.0352f) * 2 -1;
    32.             perlinValueY = (perlinValueY + 0.0345f) * 2 -1;
    33.                    
    34.             valX += perlinValueX * iAmplitude;
    35.             valY += perlinValueY * iAmplitude;
    36.  
    37.             // Keeping track of maximum amplitude for normalizing later
    38.             maxAmplitude += iAmplitude;
    39.  
    40.             iAmplitude     *= persistance;
    41.             iFrequency     *= lacunarity;
    42.         }
    43.  
    44.         valX *= burstMultiplier;
    45.         valY *= burstMultiplier;
    46.  
    47.         // normalize
    48.         valX /= maxAmplitude;
    49.         valY /= maxAmplitude;
    50.  
    51.         valX *= amplitude;
    52.         valY *= amplitude;
    53.  
    54.         return new Vector2(valX, valY);
    55.     }
    56. }
    Here is the implementation, attach to the GameObject you want to control:

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class Shake : MonoBehaviour
    4. {
    5.     [Range(0,100)]
    6.     public float amplitude = 1;
    7.     [Range(0.00001f, 0.99999f)]
    8.     public float frequency = 0.98f;
    9.  
    10.     [Range(1,4)]
    11.     public int octaves = 2;
    12.  
    13.     [Range(0.00001f,5)]
    14.     public float persistance = 0.2f;
    15.     [Range(0.00001f,100)]
    16.     public float lacunarity = 20;
    17.  
    18.     [Range(0.00001f, 0.99999f)]
    19.     public float burstFrequency = 0.5f;
    20.  
    21.     [Range(0,5)]
    22.     public int  burstContrast = 2;
    23.  
    24.     void Update ()
    25.     {
    26.         transform.position = NoiseGen.Shake2D(amplitude, frequency, octaves, persistance, lacunarity, burstFrequency, burstContrast, Time.time);
    27.     }
    28. }
    Thinking about creating a Vector3 output, any ideas?
     
    bendangelo, adsilcott and petey like this.
unityunity