Search Unity

Shadow detector to PlayerPrefs

Discussion in 'Scripting' started by G_Trex, Sep 20, 2017.

  1. G_Trex

    G_Trex

    Joined:
    Apr 20, 2013
    Posts:
    98
    Hi Everyone

    I have a shadow detector script I really like, but that wasn't written by me (can't even remember where I got it). The main problem is that it's written in C#, and I only really know JavaScript. It's also a bit more complex than what I normally use.

    It currently displays the 'how well the player is lit' value to a gui text. How would I change the code so that it writes the value to playerprefs instead?

    Thank you.

    Here's the code :
    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System;
    4. using System.Collections;
    5. using System.Collections.Generic;
    6.  
    7. public class ShadowDetector : MonoBehaviour {
    8.  
    9.     public bool autoGetCollider = true;
    10.     public CapsuleCollider playerCollider;
    11.     public LayerMask lightLayers = -1;
    12.     public LayerMask obstaclesLayers = -1;
    13.     public float maxShadowBright = 0.5f;
    14.     public float sensorDelay = 1f;
    15.     public bool debugMode = true;
    16.    
    17.     private static List<Light> v_directionalLightList = new List<Light>();
    18.     private static List<Light> v_pointLightList = new List<Light>();
    19.     private static List<Light> v_spotLightList = new List<Light>();
    20.     private float v_bright;
    21.     private bool v_shaded = false;
    22.     private bool v_croutineReady = true;
    23.  
    24.     Transform t_player;
    25.     Vector3 v_capsCenter;
    26.     float v_capsRadius;
    27.     float v_capsHalfHeight;
    28.     Vector3 v_upDirection;
    29.  
    30.     public bool isShaded {
    31.         get { return v_shaded; }
    32.     }
    33.  
    34.     public float shadowBright
    35.     {
    36.         get { return v_bright; }
    37.     }
    38.  
    39.     void Start () {
    40.         if(autoGetCollider)
    41.         {
    42.             playerCollider = GetComponent<CapsuleCollider>();
    43.         }
    44.         else
    45.         {
    46.             if (playerCollider == null) playerCollider = gameObject.AddComponent<CapsuleCollider>();
    47.         }
    48.         t_player = transform;
    49.     }
    50.    
    51.     void Update () {
    52.  
    53.         if (v_croutineReady)
    54.         {
    55.             v_bright = 0f;
    56.             v_croutineReady = false;
    57.             v_capsCenter = t_player.TransformPoint(playerCollider.center);
    58.             v_capsRadius = playerCollider.radius;
    59.             v_capsHalfHeight = playerCollider.height * 0.5f;
    60.             v_upDirection = t_player.up;
    61.             StartCoroutine(GetAllCloseLights(v_capsCenter, () => {
    62.                 StartCoroutine(GetDirectionalLightsBright(() => {
    63.                     StartCoroutine(GetPointLightsBright(() => {
    64.                         StartCoroutine(GetSpotLightsBright(() => {
    65.                             v_shaded = v_bright <= maxShadowBright;
    66.                             StartCoroutine(WaitReadyCroutine(sensorDelay));
    67.                         }));
    68.                     }));
    69.                 }));
    70.             }));
    71.         }
    72.  
    73.     }
    74.  
    75.     private IEnumerator WaitReadyCroutine(float t)
    76.     {
    77.         yield return new WaitForSeconds(t);
    78.         v_croutineReady = true;
    79.     }
    80.  
    81.     private IEnumerator GetAllCloseLights(Vector3 point, Action callback)
    82.     {
    83.  
    84.         v_directionalLightList.Clear();
    85.         v_pointLightList.Clear();
    86.         v_spotLightList.Clear();
    87.  
    88.         Light[] lights = FindObjectsOfType<Light>();
    89.  
    90.         foreach (Light currLight in lights)
    91.         {
    92.             switch (currLight.type)
    93.             {
    94.                 case LightType.Directional:
    95.                     if (currLight.enabled && IsInLayerMask(currLight.gameObject)) v_directionalLightList.Add(currLight);
    96.                     break;
    97.                 case LightType.Point:
    98.                     float currPointLightDist = (currLight.transform.position - point).sqrMagnitude;
    99.                     if (currLight.enabled && IsInLayerMask(currLight.gameObject)
    100.                         && currPointLightDist < currLight.range * currLight.range)
    101.                         v_pointLightList.Add(currLight);
    102.                     break;
    103.                 case LightType.Spot:
    104.                     float currSpotLightDist = (currLight.transform.position - point).sqrMagnitude;
    105.                     if (currLight.enabled && IsInLayerMask(currLight.gameObject)
    106.                         && currSpotLightDist < currLight.range * currLight.range)
    107.                         v_spotLightList.Add(currLight);
    108.                     break;
    109.             }
    110.         }
    111.  
    112.         callback();
    113.         yield return null;
    114.  
    115.     }
    116.  
    117.     private void LightCollision(Transform from, Action<Vector3> callback)
    118.     {
    119.         Vector3 lightPos = from.position;
    120.         Vector3 heading = v_capsCenter - lightPos;
    121.         Vector3 leftDirection = Vector3.Cross(heading.normalized, v_upDirection).normalized;
    122.         RaycastHit hit;
    123.         // center
    124.         if (Physics.Linecast(lightPos, v_capsCenter, out hit, obstaclesLayers))
    125.         {
    126.             //left
    127.             if (t_player != hit.transform &&
    128.                 Physics.Linecast(lightPos, v_capsCenter + leftDirection * v_capsRadius, out hit, obstaclesLayers))
    129.             {
    130.                 // right
    131.                 if (t_player != hit.transform &&
    132.                     Physics.Linecast(lightPos, v_capsCenter + -leftDirection * v_capsRadius, out hit, obstaclesLayers))
    133.                 {
    134.                     // up
    135.                     if (t_player != hit.transform &&
    136.                         Physics.Linecast(lightPos, v_capsCenter + v_upDirection * v_capsHalfHeight, out hit, obstaclesLayers))
    137.                     {
    138.                         // down
    139.                         if (t_player != hit.transform &&
    140.                             Physics.Linecast(lightPos, v_capsCenter + -v_upDirection * v_capsHalfHeight, out hit, obstaclesLayers))
    141.                         {
    142.                             if (t_player != hit.transform) return;
    143.                         }
    144.                     }
    145.                 }
    146.             }
    147.         }
    148.         if (debugMode) Debug.DrawLine(lightPos, hit.point, Color.green);
    149.         callback(heading);
    150.     }
    151.  
    152.     private bool SpotAngleTest(Light light)
    153.     {
    154.         Vector3 heading = v_capsCenter - light.transform.position;
    155.         float toPosAngle = Vector3.Angle(v_capsCenter - light.transform.position, light.transform.forward);
    156.         return !(heading.magnitude > light.range || toPosAngle > light.spotAngle / 2f);
    157.     }
    158.  
    159.     private IEnumerator GetDirectionalLightsBright(Action callback)
    160.     {
    161.         foreach (Light light in v_directionalLightList)
    162.         {
    163.             Vector3 heading = v_capsCenter - light.transform.position;
    164.             float distance = heading.magnitude;
    165.             Vector3 direction = light.transform.rotation * Vector3.forward;
    166.             direction = Vector3.Reflect(direction, -direction);
    167.             RaycastHit hit;
    168.             if (Physics.Raycast(v_capsCenter, direction, out hit, distance, obstaclesLayers)) continue;
    169.             v_bright += light.intensity;
    170.         }
    171.         callback();
    172.         yield return null;
    173.     }
    174.  
    175.     private IEnumerator GetPointLightsBright(Action callback)
    176.     {
    177.         foreach (Light light in v_pointLightList)
    178.         {
    179.             LightCollision(light.transform, (heading) => {
    180.                 v_bright += light.intensity - (heading.magnitude / light.range * light.intensity);
    181.             });
    182.         }
    183.         callback();
    184.         yield return null;
    185.     }
    186.  
    187.     private IEnumerator GetSpotLightsBright(Action callback)
    188.     {
    189.         foreach (Light light in v_spotLightList)
    190.         {
    191.             if (!SpotAngleTest(light)) continue;
    192.             LightCollision(light.transform, (heading) => {
    193.                 v_bright += light.intensity - (heading.magnitude / light.range * light.intensity);
    194.             });
    195.         }
    196.         callback();
    197.         yield return null;
    198.     }
    199.  
    200.     private bool IsInLayerMask(GameObject obj)
    201.     {
    202.         return ((lightLayers.value & (1 << obj.layer)) > 0);
    203.     }
    204.  
    205.     void OnGUI()
    206.     {
    207.         if (!debugMode) return;
    208.         GUILayout.BeginArea(new Rect(10f, 10f, Screen.width, Screen.height));
    209.         GUILayout.Label("Sensor Bright = " + string.Format("{0:0.00}", v_bright));
    210.         GUILayout.EndArea();
    211.     }
    212.  
    213. }
    214.  
     
  2. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,188
    If you just mean the label,

    Code (CSharp):
    1. PlayerPrefs.SetString("lit", string.Format("{0:0.00}", v_bright));
    2. PlayerPrefs.SetFloat("LitValue", v_bright);
    3.  
     
  3. G_Trex

    G_Trex

    Joined:
    Apr 20, 2013
    Posts:
    98
    Thank you!

    That largely works great. :)

    One small alteration though - I was hoping to save it as an integer rather than a string. How would I do that?

    EDIT : Nevermind, I was able to work this part out myself.

    Code (csharp):
    1.  
    2.         PlayerPrefs.SetInt("lit", (int) v_bright);
    3.         PlayerPrefs.SetFloat("LitValue", v_bright);
    4.  
     
    Last edited: Sep 21, 2017
  4. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,188
    Glad you got it figured out! You could also just save the float and convert it to an int when you want to pull it again, or just save the int itself. Just depends on what you need them for.

    Good luck with your game!