/// <summary>
    /// Actives the collider associated with the given shape type.
    /// Should only be used internally and by the save/load system.
    /// </summary>
    /// <param name="colliderType">Shape type to change the collider to.</param>
    public void ChangeColliderType(ShapeData.ShapeType colliderType)
    {
        activeColliderType = colliderType;
        switch (colliderType)
        {
        // BoxCollider2D
        case ShapeData.ShapeType.BOX:
            EnableOneColliderType(boxColliders);
            break;

        // CircleCollider2D
        case ShapeData.ShapeType.CIRCLE:
            EnableOneColliderType(circleColliders);
            break;

        // Triangle needs to be a specific kind of polygon collider
        case ShapeData.ShapeType.TRIANGLE:
            MorphPolygonToShape(ShapeData.TRIANGLE_POINTS);
            EnableOneColliderType(polygonColliders);
            break;

        default:
            Debug.LogError("Unhandled ColliderType of '" + colliderType + "' in PlayerColliderController.cs");
            break;
        }
    }
    /// <summary>Coroutine to smoothly change the shape of the mesh</summary>
    /// <param name="onFinishMeshChange">Function to call once the mesh has finished changing</param>
    private IEnumerator ChangeMeshCoroutine(ShapeData.ShapeType shapeType, FinishChange onFinishMeshChange)
    {
        changeMeshCoroutFin = false;

        // Get the initial values for each of the blend shapes
        float[] startBlendShapes = new float[BLEND_SHAPE_AMOUNT];
        for (int i = 0; i < BLEND_SHAPE_AMOUNT; ++i)
        {
            startBlendShapes[i] = targetRenderers[0].GetBlendShapeWeight(i);
        }
        // Get index of the target blend shape
        int targetBlendIndex = GetBlendIndexFromShape(shapeType);

        // The amount of lerps that will be done
        float t = 0;

        while (t < 1)
        {
            // Lerp it
            LerpRenderers(targetBlendIndex, startBlendShapes, t);
            // Step
            t += changeSpeed * Time.deltaTime;

            yield return(null);
        }
        // Set the variables without lerping now that we are done
        LerpRenderers(targetBlendIndex, startBlendShapes, 1);

        changeMeshCoroutFin = true;
        // Call the specified functionality after changing meshes
        onFinishMeshChange?.Invoke();

        yield return(null);
    }
    /// <summary>Called when an avaible spot is found in change form controller.
    /// Updates the state and plays the sound.
    /// Starts chaning the mesh</summary>
    private void OnAvailableSpotFound()
    {
        ShapeData prevData = GetCurrentState();
        ShapeData data     = SkillData.GetData(curAttemptedStateIndex);

        // If the direction affects how the shape scales or we are swapping to a new state
        if (data.DirectionAffectsScale || !IsCurrentState(curAttemptedStateIndex))
        {
            // Update the state
            UpdateCurrentState(curAttemptedStateIndex);

            // Start changing shape if we need to
            if (data.TypeOfShape != curShape)
            {
                // Start updating the mesh
                meshTransitioner.StartChangeShape(data.TypeOfShape);

                // Check if we need to invoke the shape change behaviors
                if (prevData.HasShapeChangeBehavior)
                {
                    // Call change from on the old data
                    prevData.ShapeChangeBehave.ChangeFrom();
                }
                if (data.HasShapeChangeBehavior)
                {
                    // Call change to on the new data
                    data.ShapeChangeBehave.ChangeTo();
                }
            }
            // Set the current shape to the new one
            curShape = data.TypeOfShape;
        }
    }
    /// <summary>
    /// Creates and returns PlayerCollidersSaveData holding the data for the
    /// player's collider controller.
    /// </summary>
    /// <returns></returns>
    public override object Save()
    {
        // Get the current active collider type
        ShapeData.ShapeType colliderType = colliderCont.GetActiveColliderType();

        // Return the new data
        return(new PlayerCollidersSaveData(colliderType));
    }
    /// <summary>Shows the visual for the player not fitting somewhere.</summary>
    /// <param name="shapeType">Type of shape the player tried to change to.</param>
    /// <param name="size">Size the player tried to change to.</param>
    /// <param name="rotation">Rotation of the shape to display.</param>
    private void ShowCannotFitHere(ShapeData.ShapeType shapeType, Vector2 pos, Vector2Int size, float rotation)
    {
        // Activate the cannot fit controller to show itself
        Vector3 posV3  = new Vector3(pos.x, pos.y, cannotFitCont.transform.position.z);
        Vector3 sizeV3 = new Vector3(size.x, size.y);

        cannotFitCont.Activate(posV3, sizeV3, rotation, shapeType);
    }
    /// <summary>Sets the active state to the given state without using the skill.
    /// Should only be used for loading save data.
    /// Also sets the attempted state and current shape type to the
    /// state information associated with the specified state.</summary>
    public override void FakeUse(int stateIndex)
    {
        base.FakeUse(stateIndex);
        ShapeData data = SkillData.GetData(stateIndex);

        curAttemptedStateIndex = stateIndex;
        curShape = data.TypeOfShape;
        changeFormCont.CurShapeData = data;
    }
 /// <summary>
 /// Creates save data for the rotating visuals.
 /// </summary>
 /// <param name="type">Type of shape the player is.</param>
 /// <param name="col">Color the player is.</param>
 public PlayerScaleVisualsSaveData(ShapeData.ShapeType type, Color col)
 {
     // Cast the enum to an int
     shapeType = (int)type;
     // Save the color in an array of floats
     color[0] = col.r;
     color[1] = col.g;
     color[2] = col.b;
 }
Exemple #8
0
    /// <summary>
    /// Creates and returns PlayerRotVisualsSaveData holding the current shape/color renderer's data.
    /// </summary>
    /// <returns></returns>
    public override object Save()
    {
        // Type of shape the player is right now
        ShapeData.ShapeType shapeType = blendTransitioner.CurrentShapeType;
        // Color the player is right now
        Color color = meshRenderer.material.color;

        // Return the data
        return(new PlayerScaleVisualsSaveData(shapeType, color));
    }
    /// <summary>Turns on the colliders for the given shape's type.
    /// Returns an AvailableSpot to hold if the player was able to fit in the current location and what location the spot was found.
    /// If a spot was found, the colliders were updated.
    /// If a spot was not found, they cannot fit in their current location and their colliders were not changed.</summary>
    /// <param name="colliderType">Type of collider to activate</param>
    /// <param name="size">The actual size of the collider to test</param>
    /// /// <param name="rotation">Rotation of the shape.</param>
    public AvailableSpot ActivateCollider(ShapeData.ShapeType colliderType, Vector2Int size, float rotation)
    {
        AvailableSpot availSpot = TestColliderChange(colliderType, size, rotation);

        if (availSpot.Available)
        {
            ChangeColliderType(colliderType);
        }
        return(availSpot);
    }
    /// <summary>Starts smoothly changing the shape given</summary>
    /// <param name="onFinishMeshChange">Function to call once the mesh has finished changing</param>
    public void StartChangeShape(ShapeData.ShapeType shapeType, FinishChange onFinishMeshChange = null)
    {
        currentShapeType = shapeType;

        // If there is an ongoing coroutine, stop it
        if (!changeMeshCoroutFin)
        {
            StopCoroutine(changeMeshCorout);
        }
        // Start a new coroutine
        changeMeshCorout = StartCoroutine(ChangeMeshCoroutine(shapeType, onFinishMeshChange));
    }
Exemple #11
0
    /// <summary>
    /// Load the skill data from the serialized object and
    /// reapply the loaded data to the active player's renderer.
    /// </summary>
    /// <param name="serializedObj">object with the player's visual's saved data</param>
    public override void Load(object serializedObj)
    {
        // Cast the data
        PlayerScaleVisualsSaveData data = serializedObj as PlayerScaleVisualsSaveData;

        // Change the shape of the player
        ShapeData.ShapeType shapeType = data.GetShapeType();
        blendTransitioner.ChangeShapeInstant(shapeType);
        // Change the color of the player
        Color color = data.GetColor();

        meshRenderer.material       = new Material(meshRenderer.material);
        meshRenderer.material.color = color;
    }
    /// <summary>Shows the cannot fit visual at the given position as the given size and shape.</summary>
    /// <param name="pos">Position to move the cannot fit visual to.</param>
    /// <param name="size">Shape size to set.</param>
    /// <param name="rotation">Rotation of the shape.</param>
    /// <param name="shapeType">ShapeType to set the cannot fit visual to.</param>
    public void Activate(Vector3 pos, Vector3 size, float rotation, ShapeData.ShapeType shapeType)
    {
        // Move to the player's position.
        transform.position = pos;
        // Rotate the shape
        Vector3 angles = transform.eulerAngles;

        angles.z = rotation;
        transform.eulerAngles = angles;
        // Make it fit the size and shape the player attempted to change to.
        scaleCont.ShapeScale = size;
        blendTrans.ChangeShapeInstant(shapeType);

        StartFadeOutCoroutine();
    }
    /// <summary>Instantly changes the shape to the specified shape type.</summary>
    /// <param name="shapeType">Shape to change to.</param>
    public void ChangeShapeInstant(ShapeData.ShapeType shapeType)
    {
        currentShapeType = shapeType;

        // Get the initial values for each of the blend shapes
        float[] startBlendShapes = new float[BLEND_SHAPE_AMOUNT];
        for (int i = 0; i < BLEND_SHAPE_AMOUNT; ++i)
        {
            startBlendShapes[i] = targetRenderers[0].GetBlendShapeWeight(i);
        }
        // Get index of the target blend shape
        int targetBlendIndex = GetBlendIndexFromShape(shapeType);

        // Lerp with a value of 1.
        LerpRenderers(targetBlendIndex, startBlendShapes, 1);
    }
Exemple #14
0
    private bool ShapeCast(ShapeData.ShapeType shape, Vector2 pos, Vector2 size, float rotation, LayerMask layerMask,
                           bool isTest = false)
    {
        // Turn on the test collider of the given type see if there is a collision with a wall
        switch (shape)
        {
        // BoxCollider2D
        case ShapeData.ShapeType.BOX:
            if (isTest)
            {
                return(PhysicsDebugging.OverlapBox(pos, size, rotation, layerMask));
            }
            return(Physics2D.OverlapBox(pos, size, rotation, layerMask));

        // CircleCollider2D
        case ShapeData.ShapeType.CIRCLE:
            if (isTest)
            {
                return(PhysicsDebugging.OverlapCircle(pos, size.x * 0.5f, layerMask));
            }
            return(Physics2D.OverlapCircle(pos, size.x * 0.5f, layerMask));

        // Triangle needs to be a specific kind of polygon collider
        case ShapeData.ShapeType.TRIANGLE:
            RaycastHit2D[] polyhits;
            if (isTest)
            {
                polyhits = PhysicsDebugging.OverlapPolygon(pos, size, rotation, ShapeData.TRIANGLE_POINTS, layerMask);
            }
            else
            {
                polyhits = OverlapPolygon(pos, size, rotation, ShapeData.TRIANGLE_POINTS, layerMask);
            }
            foreach (RaycastHit2D pHit in polyhits)
            {
                if (pHit)
                {
                    return(true);
                }
            }
            return(false);

        default:
            Debug.LogError($"Unhandled ColliderType of '{shape}' in PlayerColliderController.cs");
            return(true);
        }
    }
    /// <summary>Returns blend index corresponding to the given shape.
    /// Returns -2 if ShapeType is unrecognized. Returns -1 if shape is base shape.</summary>
    private int GetBlendIndexFromShape(ShapeData.ShapeType shape)
    {
        switch (shape)
        {
        case ShapeData.ShapeType.BOX:
            return(0);

        case ShapeData.ShapeType.CIRCLE:
            return(-1);

        case ShapeData.ShapeType.TRIANGLE:
            return(1);

        default:
            Debug.LogError("Unhandled Shape Type " + shape);
            break;
        }
        return(-2);
    }
Exemple #16
0
    /// <summary>Checks if the type of type of collider given will hit any unpassable walls if changed to.
    /// Returns an available spot which holds if a spot was found (True) or not (False) and
    /// the location the available spot was found</summary>
    /// <param name="colliderType">Shape of collider to turn into</param>
    /// <param name="size">The actual size of the collider</param>
    /// <param name="rotation">Rotation of the shape.</param>
    public AvailableSpot CheckIfColliderWillHitWall(ShapeData.ShapeType colliderType, Vector2 size, float rotation)
    {
        // Colored wall layer mask
        LayerMask colorWallLayerMask = GetCurrentColoredWallLayerMask();

        Vector2 gridPos = ActiveGrid.Instance.CastToGridPosition(transform.position, new Vector2(size.x, size.y), rotation);

        // Physics casts don't play well with negatives sizes, so fix that
        size = new Vector2(Mathf.Abs(size.x) - COLLIDER_OFFSET_AMOUNT, Mathf.Abs(size.y) - COLLIDER_OFFSET_AMOUNT);

        // Try in multiple spots around the player
        // x and y for offset
        // i | x | y
        // ---------
        // 0 | 0 | 0
        // 1 | 0 | 1
        // 2 | 1 | 0
        // 3 | 1 | 1
        for (int i = 0; i < 4; ++i)
        {
            float   tileSize = ActiveGrid.Instance.GetTileSize();
            int     x        = i >= 2 ? 1 : 0;
            int     y        = i % 2;
            Vector2 offset   = new Vector2(x, y) * tileSize;
            Vector2 curPos;
            // Add or subtract based on where the rounded position is
            int xSign = transform.position.x < gridPos.x ? -1 : 1;
            int ySign = transform.position.y < gridPos.y ? -1 : 1;
            curPos.x = gridPos.x + offset.x * xSign;
            curPos.y = gridPos.y + offset.y * ySign;

            // If there was no hit, we found a place the player can be
            if (!ShapeCast(colliderType, curPos, size, rotation, colorWallLayerMask))
            {
                return(new AvailableSpot(true, curPos));
            }
        }

        // If there was a hit, we cannot change
        return(new AvailableSpot(false, gridPos));
    }
 /// <summary>
 /// Creates save data for the player's collider controller.
 /// </summary>
 /// <param name="shapeType">Type of collider that is currently active.</param>
 public PlayerCollidersSaveData(ShapeData.ShapeType shapeType)
 {
     colliderType = shapeType;
 }
 /// <summary>Tests if the given type of shape will fit in the player's current position.
 /// Returns an AvailableSpot to hold if a spot was found (player can fit) and
 /// where that spot is.</summary>
 /// <param name="colliderType">Shape of the collider to test.s</param>
 /// <param name="size">The actual size of the collider to test.</param>
 /// <param name="rotation">Rotation of the shape.</param>
 public AvailableSpot TestColliderChange(ShapeData.ShapeType colliderType, Vector2Int size, float rotation)
 {
     return(testColliderRef.CheckIfColliderWillHitWall(colliderType, size, rotation));
 }