Advertisement

Unlock abilities in a Metroidvania game

Started by December 19, 2021 01:28 PM
5 comments, last by Thaumaturge 2 years, 11 months ago

I am developing a metroidvania style game, I have programmed the basic movements of the main character (adjustable jump, left and right movement and melee attack) and in the same script I have also programmed the walljump and wall slide, all this works well, but I need that the player unlocks this ability advancing in the game, when collecting an item, but I don't know how to modify my code so that it is initially desactivated and then when collecting an item it became activated.

Here I attach the code, if someone could help me I would appreciate it.

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

public class Base_1 : MonoBehaviour

{

public float Speed;

public float JumpHeight;

public float JumpPower;

public float Gravity;

public int Fase1;

public int Fase2;

public bool Jumping;

public float Fallen;

public Animator ani;

private float YPos;

private int sky_;

///////////////////GroundDetector///////////////////////

private RaycastHit2D hit;

public Vector3 v3;

public float distance;

public LayerMask layer;

///////////////////WallJump///////////////////////

// Start is called before the first frame update

private RaycastHit2D hit2;

private RaycastHit2D hit3;

public Vector3 ray_pose;

public float distance2;

public bool slide;

public bool Jumping2;

public float delay;

void Start()

{

ani = GetComponent<Animator>();

}

void OnDrawGizmos()

{

Gizmos.DrawRay(transform.position + v3, Vector3.up * -1 * distance);

Gizmos.DrawRay(transform.position + ray_pose, transform.right * distance2);

}

public bool CheckCollision

{

get

{

hit = Physics2D.Raycast(transform.position + v3, transform.up * -1, distance, layer);

return hit.collider != null;

}

}

public bool CheckCollision_Wall

{

get

{

hit2 = Physics2D.Raycast(transform.position + ray_pose, transform.right, distance2, layer);

return hit2.collider != null;

}

}

public bool CheckCollision_Wall_Jump

{

get

{

hit3 = Physics2D.Raycast(transform.position + ray_pose, transform.right, distance2 * 2, layer);

return hit3.collider != null;

}

}

public void Wall_Jump()

{

if (CheckCollision_Wall && !CheckCollision)

{

if (transform.position.y < YPos)

{

if (!Jumping)

{

Gravity = -2.5f;

slide = true;

ani.SetBool("slide", true);

}

}

}

else

{

slide = false;

ani.SetBool("slide", false);

}

if (delay > 0)

{

delay -= 4 * Time.deltaTime;

}

}

public void Platform_Detector()

{

if (CheckCollision || slide)///////******

{

ani.SetBool("sky", false);

sky_ = 0;

if (!Jumping)

{

if (!slide)

{

Gravity = 0;

}

Fase1 = 0;

Fase2 = 0;

}

}

else

{

ani.SetBool("sky", true);

if (!Jumping)

{

switch (Fase2)

{

case 0:

if (!slide)

{

Gravity = 0;

}

Fase2 = 1;

break;

case 1:

if (Gravity > -10)

{

Gravity -= JumpHeight / Fallen * Time.deltaTime;

}

break;

}

}

}

if (!slide)

{

if (transform.position.y > YPos)

{

ani.SetFloat("gravity", 1);

}

if (transform.position.y < YPos)

{

ani.SetFloat("gravity", 0);

switch (sky_)

{

case 0:

ani.Play("Base Layer.Sky", 0, 0);

sky_++;

break;

}

}

}

YPos = transform.position.y;

}

public void Jump()

{

if (Input.GetKey(KeyCode.Space))

{

switch (Fase1)

{

case 0:

if (CheckCollision)

{

Gravity = JumpHeight;

Fase1 = 1;

Jumping = true;

}

if (slide && delay <= 0)

{

Gravity = JumpHeight;

Fase1 = 1;

Jumping = true;

Jumping2 = true;

delay = 1;

}

break;

case 1:

if (Gravity > 0)

{

Gravity -= JumpPower * Time.deltaTime;

}

else

{

Fase1 = 2;

}

Jumping = true;

if (slide)

{

Jumping2 = true;

}

break;

case 2:

Jumping = false;

break;

}

}

else

{

Jumping = false;

Jumping2 = false;

}

}

public void Move()

{

if (Input.GetKey(KeyCode.RightArrow))

{

transform.Translate(Vector3.right * Speed * Time.deltaTime);

transform.rotation = Quaternion.Euler(0, 0, 0);

if (!slide)

{

ani.SetBool("run", true);

}

else

{

ani.SetBool("run", false);

}

distance2 = 0.18f;

}

else

{

ani.SetBool("run", false);

distance2 = 0;

}

if (Input.GetKey(KeyCode.LeftArrow))

{

transform.Translate(Vector3.right * Speed * Time.deltaTime);

transform.rotation = Quaternion.Euler(0, 180, 0);

if (!slide)

{

ani.SetBool("run", true);

}

else

{

ani.SetBool("run", false);

}

distance2 = 0.18f;

}

}

// Update is called once per frame

void FixedUpdate()

{

Move();

Jump();

if (Jumping2 && CheckCollision_Wall_Jump)

{

transform.Translate(Vector3.left * Gravedad * 1.2f * Time.deltaTime);

transform.Translate(Vector3.up * Gravedad * Time.deltaTime);

}

else

{

transform.Translate(Vector3.up * Gravedad * Time.deltaTime);

}

}

void Update()

{

Wall_Jump();

Platform_Detector();

}

}

There are more-complex, more-elegant, and more-extensible approaches, but a simple means of doing this might be to just have your character-class include some boolean variables that determine whether the code for the related abilities should be run.

So, for example, you might have a variable named “hasWallJumpAbility”, which is initially set to “false”. This variable would then be checked before the wall-jump code is run. And when the player acquires the item that should grant the ability, doing so would set this variable to “true”--thus allowing the wall-jump code to run, and the ability to be “gained”.

MWAHAHAHAHAHAHA!!!

My Twitter Account: @EbornIan

Advertisement

But how can I implement that in my code?

I don't know where to put the boolean variable to execute the code of the skill that I want to unlock.

I would suggest that the booleans be declared at the start of the player-class--I suppose in the same sort of place that you define your character's speed, etc.

The actual use of the booleans would be wherever the logic for the ability lies.

I'll confess that I'm finding it a little hard to parse your code without any formatting--it would be easier, I imagine, if it were formatted via the forum's “code block” system. (If you want to do so in future, the “code block” option should be found in the top menu-bar of the “new post” entry.)

That said, I see near the end that you have a call to a “Wall_Jump” method. If that method handles all of the logic for wall-jumping, then you could wrap that in an if-statement that checks the relevant boolean, perhaps. This should allow you to only run the wall-jumping logic when the boolean is set to “true” (i.e. when the player has the ability enabled).

MWAHAHAHAHAHAHA!!!

My Twitter Account: @EbornIan

@Thaumaturge Oh thank you very much I solved it, it was so much easiest than I think, I´m going to follow you on twitter ?.

For the next time I will do what you told me to use the code block, I am new to this forum and I did not know very well how it worked, thanks!!!

I'm glad that you figured it out! And I'm glad if I've been of service! ^_^

And thank you if you do so follow me on Twitter. (But no pressure if you don't want to, of course.) ^_^

As to the code-block, fair enough! Each forum has its own particular tools or markup, after all. ^_^

MWAHAHAHAHAHAHA!!!

My Twitter Account: @EbornIan

This topic is closed to new replies.

Advertisement