Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using UnityEngine;
- /// <summary>
- /// Fakes 2D jumping using a body that jumps and a shadow of where it will be.
- /// The 'shadow' only has to be a Transform and doesn't require any image.
- /// </summary>
- public class PsuedoBody2D : MonoBehaviour
- {
- #region Public Fields
- [Header("Control Objects")]
- [Tooltip("The body of the object that jumps up and down.")]
- public Transform BodyPoint;
- [Tooltip("The collider for the body.")]
- public Collider2D BodyCollider2D;
- [Tooltip("The position of the shadow on the ground.")]
- public Transform GroundPoint;
- [Header("Physics")]
- [Tooltip("The height the object is currently at.")]
- public float Height = 0;
- [Tooltip("Whether gravity will be applied or not.")]
- public bool EnableGravity = true;
- [Tooltip("The gravity that will pull the object to the ground.")]
- public float Gravity = -0.5f;
- [Tooltip("The current up and down movement of the object.")]
- public float Velocity = 0;
- [Tooltip("If set, the ground point will follow the body when grounded, " +
- "otherwise, the body will follow the ground point when grounded. " +
- "The body always follows the ground point in the air.")]
- public bool MatchGroundPointToBodyPointWhenGrounded = false;
- [Serializable]
- public class Shadow
- {
- [Tooltip("The scaler for the shadow.")]
- public Scaler ShadowScaler;
- [Tooltip("The SpriteRenderer that represents the shadow's renderer.")]
- public SpriteRenderer ShadowRenderer;
- [Tooltip("If set, the shadow will be enabled when the object is grounded.")]
- public bool DisplayShadowWhenGrounded = false;
- [Tooltip("If set, the shadow will be enabled when the object is in the air.")]
- public bool DisplayShadowWhenInAir = true;
- [Tooltip("The settings for scaling shadows based off height.")]
- public ShadowScaling ScalingSettings = new ShadowScaling();
- [Tooltip("The settings for setting shadows opacity based off height.")]
- public ShadowOpacity OpacitySettings = new ShadowOpacity();
- }
- [Header("Display Settings (Optional)")]
- [Tooltip("The settings that control shadow related features.")]
- public Shadow ShadowSettings = new Shadow();
- [Serializable]
- public class ShadowScaling
- {
- [Tooltip("Whether shadow scaling occurs or not.")]
- public bool EnableShadowScaling = true;
- [Tooltip("Inverts height scaling so that height for min is the max.")]
- public bool Invert = false;
- [Tooltip("The maximum scaling that the shadow will reach.")]
- public Vector3 MaxScale = new Vector3(0.05f, 0.05f, 0.05f);
- [Tooltip("At this height, the maximum scaling will be reached for shadow scaling.")]
- public float HeightForMaxScale = 8f;
- }
- [Serializable]
- public class ShadowOpacity
- {
- [Tooltip("Whether shadow opacity scaling occurs or not.")]
- public bool EnableShadowOpacityScaling = true;
- [Tooltip("Inverts height scaling so that height for min is the max.")]
- public bool Invert = false;
- [Tooltip("The minimum opacity that the shadow will reach." +
- "This is a percentage of the initial opacity setting.")]
- [Range(0f, 1f)]
- public float MinOpacityScale = 0.5f;
- [Tooltip("At this height, the minimum scale will be reached for shadow opacity.")]
- public float HeightForMinScale = 8f;
- }
- [Serializable]
- public class BodyScaling
- {
- [Tooltip("The scaler that represents the bodies scaling.")]
- public Scaler BodyScaler;
- [Tooltip("Whether shadow opacity scaling occurs or not.")]
- public bool EnableBodyScaling = true;
- [Tooltip("Inverts height scaling so that height for max is the min.")]
- public bool Invert = false;
- [Tooltip("The maxiumum scale that the body will reach." +
- "This is a percentage of the initial scale setting.")]
- public Vector3 MaxScaling = new Vector3(1.2f, 1.2f, 1.2f);
- [Tooltip("At this height, the minimum scale will be reached for shadow opacity.")]
- public float HeightForMaxScale = 8f;
- }
- [Tooltip("The settings for scaling the body based off height.")]
- public BodyScaling BodyScalingSettings = new BodyScaling();
- [Header("Events")]
- public GameEventController OnLanding;
- public GameEventController OnTakeOff;
- [Header("_TESTING_")]
- public bool TEST_Jump = false;
- public float TEST_Velocity = 0.3f;
- #endregion
- #region Public/Private Properties, Private Fields
- /// <summary>
- /// Whether the Jumper2D is grounded or not.
- /// </summary>
- public bool IsGrounded
- {
- get
- {
- return Height <= 0;
- }
- }
- /// <summary>
- /// The offset of the shadow towards the body's position at start.
- /// This is the initial offset when the script starts and cannot be modified.
- /// To change the offset value, use the PositionOffsetModifier and PositionOffsetScale variables.
- /// </summary>
- public Vector3 PositionOffset { get; private set; }
- /// <summary>
- /// Modifies the PositionOffset by this value.
- /// Modifying this will allow you to change the position of the body and shadow from eachother by a given value.
- /// </summary>
- public Vector3 PositionOffsetModifier { get; set; }
- /// <summary>
- /// Scales the PositionOffset by these value.
- /// Modifying this will allow you to change the position of the body and shadow from eachother by scaling the original offset,
- /// plus any modifications made through the modifier value.
- /// </summary>
- public Vector3 PositionOffsetScale { get; set; }
- /// <summary>
- /// The body was grounded during the last update.
- /// </summary>
- private bool _previouslyGrounded;
- /// <summary>
- /// The psuedo 2D height of the body in the last update.
- /// </summary>
- private float _previouslyHeight;
- /// <summary>
- /// The initial setting for the opacity of the shadow when starting.
- /// </summary>
- private float _shadowInitialOpacity = 1;
- #endregion
- #region Initialization
- void Awake()
- {
- PositionOffset = BodyPoint.position - GroundPoint.position;
- PositionOffsetModifier = Vector3.zero; // No modification by default
- PositionOffsetScale = Vector3.one; // No scaling by default
- _previouslyHeight = Height;
- _previouslyGrounded = Height > 0;
- }
- void Start()
- {
- if (BodyCollider2D)
- {
- BodyCollider2D = BodyPoint.GetComponent<Collider2D>();
- }
- if (ShadowSettings.ShadowRenderer != null)
- {
- _shadowInitialOpacity = ShadowSettings.ShadowRenderer.color.a;
- }
- }
- #endregion
- void Update()
- {
- if (TEST_Jump)
- {
- TEST_Jump = false;
- Velocity += TEST_Velocity;
- }
- HandleOnGroundingChange();
- HandleVisual();
- HandleVelocity();
- SetHeightAndPosition();
- _previouslyHeight = Height;
- _previouslyGrounded = IsGrounded;
- }
- /// <summary>
- /// Sets the position of the body in relation to the ground point, as well as the elevation.
- /// </summary>
- void SetHeightAndPosition()
- {
- Height += Velocity;
- Height = Mathf.Max(0, Height);
- // Calculate the actual offset from the base and the modifications.
- Vector3 offset = new Vector3(
- (PositionOffset.x + PositionOffsetModifier.x) * PositionOffsetScale.x,
- (PositionOffset.y + PositionOffsetModifier.y) * PositionOffsetScale.y,
- (PositionOffset.z + PositionOffsetModifier.z) * PositionOffsetScale.z
- );
- if (Height > 0)
- {
- BodyPoint.position = new Vector3(
- GroundPoint.position.x,
- GroundPoint.position.y + Height,
- GroundPoint.position.z
- ) + offset;
- }
- else
- {
- if (MatchGroundPointToBodyPointWhenGrounded)
- {
- GroundPoint.position = BodyPoint.position - offset;
- }
- else
- {
- BodyPoint.position = GroundPoint.position + offset;
- }
- }
- }
- /// <summary>
- /// Handles the velocity for an update.
- /// </summary>
- void HandleVelocity()
- {
- if (IsGrounded)
- {
- // Only 0 or positive velocity on the ground.
- Velocity = Mathf.Max(0, Velocity);
- }
- else if (EnableGravity)
- {
- Velocity += Gravity * Time.deltaTime;
- }
- }
- /// <summary>
- /// Handles all events that happen when the grounding changes.
- /// This sets the colliders and executes game events.
- /// </summary>
- void HandleOnGroundingChange()
- {
- if (_previouslyGrounded != IsGrounded)
- {
- return;
- }
- if (BodyCollider2D != null)
- {
- BodyCollider2D.enabled = IsGrounded;
- }
- GameEventController.Execute(IsGrounded ? OnLanding : OnTakeOff);
- }
- #region Visual Settings
- /// <summary>
- /// Handles dealing with visual related things.
- /// </summary>
- void HandleVisual()
- {
- SetShadowActivity();
- SetShadowScaling();
- SetShadowOpacity();
- SetBodyScaling();
- }
- void SetShadowActivity()
- {
- if (ShadowSettings.ShadowRenderer == null)
- {
- return;
- }
- ShadowSettings.ShadowRenderer.enabled = Height > 0 ? ShadowSettings.DisplayShadowWhenInAir : ShadowSettings.DisplayShadowWhenGrounded;
- }
- /// <summary>
- /// Sets the shadow scaling based off settings and height.
- /// </summary>
- void SetShadowScaling()
- {
- if (ShadowSettings.ShadowScaler == null)
- {
- return;
- }
- else if (!ShadowSettings.ScalingSettings.EnableShadowScaling)
- {
- ShadowSettings.ShadowScaler.Set(this, Vector3.one);
- return;
- }
- float t = ShadowSettings.ScalingSettings.HeightForMaxScale > 0 ?
- Mathf.Clamp01(Height / ShadowSettings.ScalingSettings.HeightForMaxScale) :
- 1;
- if (ShadowSettings.ScalingSettings.Invert)
- {
- t = 1 - t;
- }
- Vector3 scale = Vector3.Lerp(Vector3.one, ShadowSettings.ScalingSettings.MaxScale, t);
- ShadowSettings.ShadowScaler.Set(this, scale);
- }
- /// <summary>
- /// Sets the shadow opacity value based off settings and height.
- /// </summary>
- void SetShadowOpacity()
- {
- if (ShadowSettings.ShadowRenderer == null)
- {
- return;
- }
- else if(!ShadowSettings.OpacitySettings.EnableShadowOpacityScaling)
- {
- ShadowSettings.ShadowRenderer.color = new Color(ShadowSettings.ShadowRenderer.color.r,
- ShadowSettings.ShadowRenderer.color.g,
- ShadowSettings.ShadowRenderer.color.b,
- _shadowInitialOpacity
- );
- return;
- }
- float t = ShadowSettings.OpacitySettings.HeightForMinScale > 0 ?
- Mathf.Clamp01(Height / ShadowSettings.OpacitySettings.HeightForMinScale) :
- 1;
- if (ShadowSettings.OpacitySettings.Invert)
- {
- t = 1 - t;
- }
- float scale = Mathf.Lerp(1, ShadowSettings.OpacitySettings.MinOpacityScale, t);
- ShadowSettings.ShadowRenderer.color = new Color(ShadowSettings.ShadowRenderer.color.r,
- ShadowSettings.ShadowRenderer.color.g,
- ShadowSettings.ShadowRenderer.color.b,
- _shadowInitialOpacity * scale
- );
- }
- /// <summary>
- /// Scales the body based off height.
- /// </summary>
- void SetBodyScaling()
- {
- if (!BodyScalingSettings.EnableBodyScaling || BodyScalingSettings.BodyScaler == null)
- {
- return;
- }
- float t = BodyScalingSettings.HeightForMaxScale > 0 ?
- Mathf.Clamp01(Height / BodyScalingSettings.HeightForMaxScale) :
- 1;
- if (BodyScalingSettings.Invert)
- {
- t = 1 - t;
- }
- Vector3 scale = Vector3.Lerp(Vector3.one, BodyScalingSettings.MaxScaling, t);
- BodyScalingSettings.BodyScaler.Set(this, scale);
- }
- #endregion
- }
Add Comment
Please, Sign In to add comment