Guest User

PsuedoBody2D

a guest
Jun 12th, 2016
129
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 12.65 KB | None | 0 0
  1. using System;
  2. using UnityEngine;
  3.  
  4. /// <summary>
  5. /// Fakes 2D jumping using a body that jumps and a shadow of where it will be.
  6. /// The 'shadow' only has to be a Transform and doesn't require any image.
  7. /// </summary>
  8. public class PsuedoBody2D : MonoBehaviour
  9. {
  10.     #region Public Fields
  11.  
  12.     [Header("Control Objects")]
  13.     [Tooltip("The body of the object that jumps up and down.")]
  14.     public Transform BodyPoint;
  15.  
  16.     [Tooltip("The collider for the body.")]
  17.     public Collider2D BodyCollider2D;
  18.  
  19.     [Tooltip("The position of the shadow on the ground.")]
  20.     public Transform GroundPoint;
  21.  
  22.     [Header("Physics")]
  23.     [Tooltip("The height the object is currently at.")]
  24.     public float Height = 0;
  25.  
  26.     [Tooltip("Whether gravity will be applied or not.")]
  27.     public bool EnableGravity = true;
  28.  
  29.     [Tooltip("The gravity that will pull the object to the ground.")]
  30.     public float Gravity = -0.5f;
  31.  
  32.     [Tooltip("The current up and down movement of the object.")]
  33.     public float Velocity = 0;
  34.  
  35.     [Tooltip("If set, the ground point will follow the body when grounded, " +
  36.              "otherwise, the body will follow the ground point when grounded. " +
  37.              "The body always follows the ground point in the air.")]
  38.     public bool MatchGroundPointToBodyPointWhenGrounded = false;
  39.  
  40.     [Serializable]
  41.     public class Shadow
  42.     {
  43.         [Tooltip("The scaler for the shadow.")]
  44.         public Scaler ShadowScaler;
  45.  
  46.         [Tooltip("The SpriteRenderer that represents the shadow's renderer.")]
  47.         public SpriteRenderer ShadowRenderer;
  48.  
  49.         [Tooltip("If set, the shadow will be enabled when the object is grounded.")]
  50.         public bool DisplayShadowWhenGrounded = false;
  51.  
  52.         [Tooltip("If set, the shadow will be enabled when the object is in the air.")]
  53.         public bool DisplayShadowWhenInAir = true;
  54.  
  55.         [Tooltip("The settings for scaling shadows based off height.")]
  56.         public ShadowScaling ScalingSettings = new ShadowScaling();
  57.  
  58.         [Tooltip("The settings for setting shadows opacity based off height.")]
  59.         public ShadowOpacity OpacitySettings = new ShadowOpacity();
  60.     }
  61.     [Header("Display Settings (Optional)")]
  62.     [Tooltip("The settings that control shadow related features.")]
  63.     public Shadow ShadowSettings = new Shadow();
  64.  
  65.     [Serializable]
  66.     public class ShadowScaling
  67.     {
  68.         [Tooltip("Whether shadow scaling occurs or not.")]
  69.         public bool EnableShadowScaling = true;
  70.  
  71.         [Tooltip("Inverts height scaling so that height for min is the max.")]
  72.         public bool Invert = false;
  73.  
  74.         [Tooltip("The maximum scaling that the shadow will reach.")]
  75.         public Vector3 MaxScale = new Vector3(0.05f, 0.05f, 0.05f);
  76.  
  77.         [Tooltip("At this height, the maximum scaling will be reached for shadow scaling.")]
  78.         public float HeightForMaxScale = 8f;
  79.     }
  80.  
  81.     [Serializable]
  82.     public class ShadowOpacity
  83.     {
  84.         [Tooltip("Whether shadow opacity scaling occurs or not.")]
  85.         public bool EnableShadowOpacityScaling = true;
  86.  
  87.         [Tooltip("Inverts height scaling so that height for min is the max.")]
  88.         public bool Invert = false;
  89.  
  90.         [Tooltip("The minimum opacity that the shadow will reach." +
  91.                  "This is a percentage of the initial opacity setting.")]
  92.         [Range(0f, 1f)]
  93.         public float MinOpacityScale = 0.5f;
  94.  
  95.         [Tooltip("At this height, the minimum scale will be reached for shadow opacity.")]
  96.         public float HeightForMinScale = 8f;
  97.     }
  98.  
  99.     [Serializable]
  100.     public class BodyScaling
  101.     {
  102.         [Tooltip("The scaler that represents the bodies scaling.")]
  103.         public Scaler BodyScaler;
  104.  
  105.         [Tooltip("Whether shadow opacity scaling occurs or not.")]
  106.         public bool EnableBodyScaling = true;
  107.  
  108.         [Tooltip("Inverts height scaling so that height for max is the min.")]
  109.         public bool Invert = false;
  110.  
  111.         [Tooltip("The maxiumum scale that the body will reach." +
  112.                  "This is a percentage of the initial scale setting.")]
  113.         public Vector3 MaxScaling = new Vector3(1.2f, 1.2f, 1.2f);
  114.  
  115.         [Tooltip("At this height, the minimum scale will be reached for shadow opacity.")]
  116.         public float HeightForMaxScale = 8f;
  117.     }
  118.     [Tooltip("The settings for scaling the body based off height.")]
  119.     public BodyScaling BodyScalingSettings = new BodyScaling();
  120.  
  121.     [Header("Events")]
  122.     public GameEventController OnLanding;
  123.     public GameEventController OnTakeOff;
  124.  
  125.     [Header("_TESTING_")]
  126.     public bool TEST_Jump = false;
  127.     public float TEST_Velocity = 0.3f;
  128.  
  129.     #endregion
  130.  
  131.     #region Public/Private Properties, Private Fields
  132.  
  133.     /// <summary>
  134.     /// Whether the Jumper2D is grounded or not.
  135.     /// </summary>
  136.     public bool IsGrounded
  137.     {
  138.         get
  139.         {
  140.             return Height <= 0;
  141.         }
  142.     }
  143.  
  144.     /// <summary>
  145.     /// The offset of the shadow towards the body's position at start.
  146.     /// This is the initial offset when the script starts and cannot be modified.
  147.     /// To change the offset value, use the PositionOffsetModifier and PositionOffsetScale variables.
  148.     /// </summary>
  149.     public Vector3 PositionOffset { get; private set; }
  150.  
  151.     /// <summary>
  152.     /// Modifies the PositionOffset by this value.
  153.     /// Modifying this will allow you to change the position of the body and shadow from eachother by a given value.
  154.     /// </summary>
  155.     public Vector3 PositionOffsetModifier { get; set; }
  156.  
  157.     /// <summary>
  158.     /// Scales the PositionOffset by these value.
  159.     /// Modifying this will allow you to change the position of the body and shadow from eachother by scaling the original offset,
  160.     /// plus any modifications made through the modifier value.
  161.     /// </summary>
  162.     public Vector3 PositionOffsetScale { get; set; }
  163.  
  164.     /// <summary>
  165.     /// The body was grounded during the last update.
  166.     /// </summary>
  167.     private bool _previouslyGrounded;
  168.  
  169.     /// <summary>
  170.     /// The psuedo 2D height of the body in the last update.
  171.     /// </summary>
  172.     private float _previouslyHeight;
  173.  
  174.     /// <summary>
  175.     /// The initial setting for the opacity of the shadow when starting.
  176.     /// </summary>
  177.     private float _shadowInitialOpacity = 1;
  178.  
  179.     #endregion
  180.  
  181.     #region Initialization
  182.  
  183.     void Awake()
  184.     {
  185.         PositionOffset = BodyPoint.position - GroundPoint.position;
  186.         PositionOffsetModifier = Vector3.zero; // No modification by default
  187.         PositionOffsetScale = Vector3.one; // No scaling by default
  188.  
  189.         _previouslyHeight = Height;
  190.         _previouslyGrounded = Height > 0;
  191.     }
  192.    
  193.     void Start()
  194.     {
  195.         if (BodyCollider2D)
  196.         {
  197.             BodyCollider2D = BodyPoint.GetComponent<Collider2D>();
  198.         }
  199.  
  200.         if (ShadowSettings.ShadowRenderer != null)
  201.         {
  202.             _shadowInitialOpacity = ShadowSettings.ShadowRenderer.color.a;
  203.         }
  204.     }
  205.  
  206.     #endregion
  207.  
  208.     void Update()
  209.     {
  210.         if (TEST_Jump)
  211.         {
  212.             TEST_Jump = false;
  213.             Velocity += TEST_Velocity;
  214.         }
  215.        
  216.         HandleOnGroundingChange();
  217.         HandleVisual();
  218.         HandleVelocity();
  219.  
  220.         SetHeightAndPosition();
  221.  
  222.         _previouslyHeight = Height;
  223.         _previouslyGrounded = IsGrounded;
  224.     }
  225.  
  226.     /// <summary>
  227.     /// Sets the position of the body in relation to the ground point, as well as the elevation.
  228.     /// </summary>
  229.     void SetHeightAndPosition()
  230.     {
  231.         Height += Velocity;
  232.         Height = Mathf.Max(0, Height);
  233.  
  234.         // Calculate the actual offset from the base and the modifications.
  235.         Vector3 offset = new Vector3(
  236.             (PositionOffset.x + PositionOffsetModifier.x) * PositionOffsetScale.x,
  237.             (PositionOffset.y + PositionOffsetModifier.y) * PositionOffsetScale.y,
  238.             (PositionOffset.z + PositionOffsetModifier.z) * PositionOffsetScale.z
  239.         );
  240.  
  241.         if (Height > 0)
  242.         {
  243.             BodyPoint.position = new Vector3(
  244.                 GroundPoint.position.x,
  245.                 GroundPoint.position.y + Height,
  246.                 GroundPoint.position.z
  247.                 ) + offset;
  248.         }
  249.         else
  250.         {
  251.             if (MatchGroundPointToBodyPointWhenGrounded)
  252.             {
  253.                 GroundPoint.position = BodyPoint.position - offset;
  254.             }
  255.             else
  256.             {
  257.                 BodyPoint.position = GroundPoint.position + offset;
  258.             }
  259.         }
  260.     }
  261.  
  262.     /// <summary>
  263.     /// Handles the velocity for an update.
  264.     /// </summary>
  265.     void HandleVelocity()
  266.     {
  267.         if (IsGrounded)
  268.         {
  269.             // Only 0 or positive velocity on the ground.
  270.             Velocity = Mathf.Max(0, Velocity);
  271.         }
  272.         else if (EnableGravity)
  273.         {
  274.             Velocity += Gravity * Time.deltaTime;
  275.         }
  276.     }
  277.  
  278.     /// <summary>
  279.     /// Handles all events that happen when the grounding changes.
  280.     /// This sets the colliders and executes game events.
  281.     /// </summary>
  282.     void HandleOnGroundingChange()
  283.     {
  284.         if (_previouslyGrounded != IsGrounded)
  285.         {
  286.             return;
  287.         }
  288.  
  289.         if (BodyCollider2D != null)
  290.         {
  291.             BodyCollider2D.enabled = IsGrounded;
  292.         }
  293.  
  294.         GameEventController.Execute(IsGrounded ? OnLanding : OnTakeOff);
  295.     }
  296.  
  297.     #region Visual Settings
  298.  
  299.     /// <summary>
  300.     /// Handles dealing with visual related things.
  301.     /// </summary>
  302.     void HandleVisual()
  303.     {
  304.         SetShadowActivity();
  305.         SetShadowScaling();
  306.         SetShadowOpacity();
  307.         SetBodyScaling();
  308.     }
  309.  
  310.     void SetShadowActivity()
  311.     {
  312.         if (ShadowSettings.ShadowRenderer == null)
  313.         {
  314.             return;
  315.         }
  316.  
  317.         ShadowSettings.ShadowRenderer.enabled = Height > 0 ? ShadowSettings.DisplayShadowWhenInAir : ShadowSettings.DisplayShadowWhenGrounded;
  318.     }
  319.  
  320.     /// <summary>
  321.     /// Sets the shadow scaling based off settings and height.
  322.     /// </summary>
  323.     void SetShadowScaling()
  324.     {
  325.         if (ShadowSettings.ShadowScaler == null)
  326.         {
  327.             return;
  328.         }
  329.         else if (!ShadowSettings.ScalingSettings.EnableShadowScaling)
  330.         {
  331.             ShadowSettings.ShadowScaler.Set(this, Vector3.one);
  332.             return;
  333.         }
  334.  
  335.         float t = ShadowSettings.ScalingSettings.HeightForMaxScale > 0 ?
  336.                 Mathf.Clamp01(Height / ShadowSettings.ScalingSettings.HeightForMaxScale) :
  337.                 1;
  338.  
  339.         if (ShadowSettings.ScalingSettings.Invert)
  340.         {
  341.             t = 1 - t;
  342.         }
  343.  
  344.         Vector3 scale = Vector3.Lerp(Vector3.one, ShadowSettings.ScalingSettings.MaxScale, t);
  345.        
  346.         ShadowSettings.ShadowScaler.Set(this, scale);
  347.     }
  348.  
  349.     /// <summary>
  350.     /// Sets the shadow opacity value based off settings and height.
  351.     /// </summary>
  352.     void SetShadowOpacity()
  353.     {
  354.         if (ShadowSettings.ShadowRenderer == null)
  355.         {
  356.             return;
  357.         }
  358.         else if(!ShadowSettings.OpacitySettings.EnableShadowOpacityScaling)
  359.         {
  360.             ShadowSettings.ShadowRenderer.color = new Color(ShadowSettings.ShadowRenderer.color.r,
  361.                ShadowSettings.ShadowRenderer.color.g,
  362.                ShadowSettings.ShadowRenderer.color.b,
  363.                _shadowInitialOpacity
  364.            );
  365.             return;
  366.         }
  367.  
  368.         float t = ShadowSettings.OpacitySettings.HeightForMinScale > 0 ?
  369.                 Mathf.Clamp01(Height / ShadowSettings.OpacitySettings.HeightForMinScale) :
  370.                 1;
  371.  
  372.         if (ShadowSettings.OpacitySettings.Invert)
  373.         {
  374.             t = 1 - t;
  375.         }
  376.  
  377.         float scale = Mathf.Lerp(1, ShadowSettings.OpacitySettings.MinOpacityScale, t);
  378.        
  379.         ShadowSettings.ShadowRenderer.color = new Color(ShadowSettings.ShadowRenderer.color.r,
  380.             ShadowSettings.ShadowRenderer.color.g,
  381.             ShadowSettings.ShadowRenderer.color.b,
  382.             _shadowInitialOpacity * scale
  383.         );
  384.     }
  385.  
  386.     /// <summary>
  387.     /// Scales the body based off height.
  388.     /// </summary>
  389.     void SetBodyScaling()
  390.     {
  391.         if (!BodyScalingSettings.EnableBodyScaling || BodyScalingSettings.BodyScaler == null)
  392.         {
  393.             return;
  394.         }
  395.  
  396.         float t = BodyScalingSettings.HeightForMaxScale > 0 ?
  397.                 Mathf.Clamp01(Height / BodyScalingSettings.HeightForMaxScale) :
  398.                 1;
  399.  
  400.         if (BodyScalingSettings.Invert)
  401.         {
  402.             t = 1 - t;
  403.         }
  404.  
  405.         Vector3 scale = Vector3.Lerp(Vector3.one, BodyScalingSettings.MaxScaling, t);
  406.  
  407.         BodyScalingSettings.BodyScaler.Set(this, scale);
  408.     }
  409.  
  410.     #endregion
  411. }
Add Comment
Please, Sign In to add comment