Search Unity

[RELEASED] Rex Engine: A Unity 2D Platformer Engine

Discussion in 'Assets and Asset Store' started by BeeZee, Jun 20, 2017.

  1. BlackGamma

    BlackGamma

    Joined:
    Dec 2, 2019
    Posts:
    25
    Okay... nothin' back from the person I hit up on fiverr, I messaged back and forth a little bit but I figured I'd tinker around in the movingstate script, and on line 284 it reads:
    if (controller.axis.x != 0.0f)
    and I just changed the axis to 'y' to see if it would play vertical movement animations, but not horizontal animations, but now it plays movement animations for movement on both axes?? Seems to work just fine, but I was sure it would just flip the axis, but whatever it works! I have no idea how one would go about setting up separate animations for up & down like in a lot of top-down games, but I'm just trying to go for side views of the player at all times-- but I'm stoked about this!
     
    jeremyfryc likes this.
  2. BlackGamma

    BlackGamma

    Joined:
    Dec 2, 2019
    Posts:
    25
    Also- I for those of you who are trying to set up shop systems, I realized that going with energy rather than score for currency is the right move! In the energy.cs script, at line 34 there are the three "on revive" enums... I literally just typed 'none' in the list, saved it and selected 'none' on my 'gold' energy object in my player and that caused that type of energy to stay at the same value when you respawn. I know the score reverts to what it was when you last reached a checkpoint, and I might try to copy some of the stuff from the score script to get that working, but this is at least good enough for what I'm going for. It seems like it'd be relatively easy to set it up so it subtracts a set amount every time you respawn also. Then ya just give your player an attack that uses that energy. I have an attack set with a couple different 'action' attacks like, fishing, buy, sell, heal, etc. And this might sound kinda dumb (I don't really have a clue what I'm doing) but my 'buy' 'attack' is a projectile attack that damages players (1 damage), and ignores terrain, slotted slightly above the player. It always shoots directly 'up' and requires 50 gold to shoot. I'm going to set up my shops so that behind a thick wall, there is a target that will be hit by the projectile if you shoot while you're standing next to an item for sale (placeholder sprite). I'll have a specific AI for each item which'll be the target's 'death AI routine' and will determine how many times the target must be 'shot' with gold before playing a sequence where it enables the real item and disables the placeholder sprite. I have spell attacks that can shoot through walls so I tag the target as a player so you can't use spells as money, it also needs to be far enough behind a wall that you can't melee attack through the wall and use melee attacks as money. I don't want the player to have to pay coin by coin, so the cost of all items in my game will be multiples of 50. Having the 'buy' action slotted in an attack set will also minimize the possibility of accidentally throwing money away when you don't mean to by hitting the button on accident. But this could totally work for gate/bridge tolls and stuff like that too. I just finished my first top down game (as soon as I figured out the movement animation) but had already started working on this one. In my first one, I really wanted to have shops, so all of my good factions are communists and all commerce and exchange works on a basis of suggested donation. (So you could 'buy' or take a medkit, but it would have a -15 ammo powerup on top of it, so if you had at least 15 you'd pay for it, but you could still take it if not.) sorry for the rambling posts y'al
     
    realitywhoneedsit likes this.
  3. BlackGamma

    BlackGamma

    Joined:
    Dec 2, 2019
    Posts:
    25
    One more thing-- if you aren't already using an attack set you could easily just set up a bunch of 'pay' attacks in there like 'pay 1', 'pay 5', 'pay 10', 'pay 50', 'pay 100', and just use it as a payment menu kinda? I hope some of y'all are able to put this to use!
     
  4. BlackGamma

    BlackGamma

    Joined:
    Dec 2, 2019
    Posts:
    25
    Okay, another update on shop systems using my dumb approach! It's really easy to add additional tags to select in a contact damage component, so you don't need to use a thick wall like I was describing before. (I found this out while trying to make it so you can't cut down trees with arrows...)
    Open ContactDamage.cs and RexActor.cs
    In contact damage, just add whatever tags you want. (I've added 'Trees', and I'm going to add 'Gold' for buying items, 'SellWood' for selling wood, 'SellFood' for selling food, 'SellOre' for selling ore, and 'Ore' to make it so you can't mine with arrows either.
    In RexActor, on line 1139, the collision checks for damage begin, and you just have to copy either the 'player' or 'enemy' chunk of the script, copy & paste it below 'enemy', and then fill in the name of the new tag(s) you're adding.
     
  5. BlackGamma

    BlackGamma

    Joined:
    Dec 2, 2019
    Posts:
    25
    ***sorry, you should copy the chunk of the script for the enemy tag because it starts with "else if" and you don't want to put an 'if' in there without 'else' i think
     
  6. BlackGamma

    BlackGamma

    Joined:
    Dec 2, 2019
    Posts:
    25
    ^^^ this also works for setting up metroid style doors and stuff like that, I'm going to experiment with having different amounts for different tags as well. Sorry for spamming the forum
     
  7. rafaelquintanaz

    rafaelquintanaz

    Joined:
    Oct 3, 2018
    Posts:
    5
    Hello everyone, I would like to know if someone can help me so that "Rex" has the ability to move bidirectional ladder. Please help. Thank you very much to all.

     
    Last edited: Jan 1, 2021
  8. BlackGamma

    BlackGamma

    Joined:
    Dec 2, 2019
    Posts:
    25
    There's a post from september 2019 in this forum stating that the code for 8 way movement between multiple ladders has been posted in the forum somewhere, but it doesn't seem to come up in searches. It'd probably be worth digging around the older forum posts to see if it has actually been posted in here.
     
    rafaelquintanaz likes this.
  9. realitywhoneedsit

    realitywhoneedsit

    Joined:
    Sep 2, 2019
    Posts:
    10
    I love these 'dumb' inventive solutions, this is exactly the stuff I like to come to this board and see; using the built in systems to get results they weren't necessarily designed for, just by expanding on their logic. off the top of my head it kind of reminds me of how you buy something in Alundra - whereas another game might have you click through some menus, Alundra uses the game mechanic of picking up objects to have you pick up what you want to buy and actually throw it on the counter.

    Also you level generation scheme is a testament to how rad the AI system is. I haven't touched Rex in 2 months and this is making me want to get back into it. Most of the things I've enjoyed doing with AI have been graphical. I've made a very slick looking ferris wheel that uses layers of objects with AIs to trigger its light up animations, with special cases to make sure conflicting animations don't overlap, rare animations, and animations that trigger other game objects to do special their own special animations. Like for example I have one screen with fireflies that will all light up in sync when another animation plays, and the fireflies themselves have routines to simulate a kind of organic lighting up when they get close to each other.

    I've also used the AI to make very dynamic skies that have random weather. Basically I made an invisible object that flies around the screen, occasionally playing one of four lightning strike animations. When the lightning strikes, the big skybox object in the background plays its own subtle flash animation.

    I'll have to go back through my notes to see what other AI ideas I've had and what I've done, not all of them are graphical but animation triggering + AI is just so easy to do.

    edit: I can't remember if implemented this but a basic solution i came up with to keys/doors/destructable stuff was to have objects that would only destroy at a very specific health percentage, otherwise their AI routine would refill their health if you undershoot or overshoot it. Then you have an 'attack' that does the specific damage required so it is only capable of destroying specific objects. i think the general concept can be applied to lots of situations.

    also, for those who were asking, that 8-way climbing mod was here https://forum.unity.com/threads/rel...platformer-engine.477647/page-18#post-4203091
    i messed around with it and i know its not perfect but it's good to have. i've edited the ladder script several times and things like getting on and off a ladder, treating the middle of a ladder as ground when it's in between two solids so you can walk straight through, these have been tough. there's a lot of nuance to it and every game seems to have totally different rules on how ladders work and how they change depending on the circumstances.
     
    Last edited: Dec 30, 2020
    rafaelquintanaz likes this.
  10. rafaelquintanaz

    rafaelquintanaz

    Joined:
    Oct 3, 2018
    Posts:
    5
  11. BlackGamma

    BlackGamma

    Joined:
    Dec 2, 2019
    Posts:
    25
    I hope you're able to get that workin! And thanks for the kind words, @realitywhoneedsit!
    I think some folks may be interested in this, but I combined the script that BeeZee posted a while ago for a 'Max HP Increase' powerup, with the '100 points = 1up' script that @HCrowley and @jeremyfryc wrote, to create a simple sort of xp/level up system. Just pasted in after line 24 of ScorePowerup.cs:
    Code (CSharp):
    1. if (ScoreManager.Instance.score % 100 == 0)
    2.                 {
    3.                     GameManager.Instance.player.hp.max += (10);
    4.                     GameManager.Instance.player.RestoreHP(10000);
    5.                     ScoreManager.Instance.SetScore(0);
    6.                     ScoreManager.Instance.SetScoreAtCheckpoint(0);
    7.                 }
    I've removed the extra life aspect, but the value listed in the first line (100) is the score/"xp" required to "level up". In the second line the value (10) represents how much your player's max hp will increase by. In the third line, I have 10000 set as the restore value just so the player's hp will always completely refill, I'm not sure if there's a better way to do that. The fourth line resets the score, and the fifth line resets the score at your player's last checkpoint. (to prevent someone from exploiting the system by racking up 99xp, hitting a checkpoint, leveling up, dying, respawning with 99xp, and leveling up for ever.)
     
    Last edited: Dec 31, 2020
    realitywhoneedsit likes this.
  12. rafaelquintanaz

    rafaelquintanaz

    Joined:
    Oct 3, 2018
    Posts:
    5
  13. rafaelquintanaz

    rafaelquintanaz

    Joined:
    Oct 3, 2018
    Posts:
    5
    Hi, I'm not very expert in C# programming.
    I would like to implement an energy bar for the player, so that this energy bar runs out when the player for example: runs or climbs. And when this energy bar is depleted, the player cannot continue running or climbing, until this bar is refilled. Anyone know of a way to do it with the REX engine. Thank you.
     
  14. rafaelquintanaz

    rafaelquintanaz

    Joined:
    Oct 3, 2018
    Posts:
    5
    Hi @hodgepodge2017, I would like to know if it is possible for you to upload an update of the "RexExtensions 2_16" for the Rex engine version 1.59.0. Since I am interested in implementing "8-way ladder climb". I have downloaded the file that is in this forum and it gives me many errors that cannot be solved because I do not know much C#. I would like to please if it is possible for you to upload the file that only enables "8-way ladder climb". Thank you very much
     
  15. thenadamgoes

    thenadamgoes

    Joined:
    Apr 26, 2019
    Posts:
    29
    Has anyone had any success using the Universal Render Pipeline with Rex? For some reason when I try to play the entire screen is gray. I can't seem to figure out what setting is wrong either. I noticed other people had this issue on the board, but never saw any resolution.
     
  16. thenadamgoes

    thenadamgoes

    Joined:
    Apr 26, 2019
    Posts:
    29
    So unless I am mistaken, the 2D Renderer in URP doesn't support multiple cameras. Luckily I'm not super far into my game so I can switch to a single perspective camera and it all seems work fine.

    If anyone has any other solutions, I'd like to know.
     
  17. tirkaroKujo

    tirkaroKujo

    Joined:
    Jul 10, 2017
    Posts:
    10
    The "Swap Player" component just doesn't work; not with ProCamera 2D anyway.
    Every time I use it, best I can hope for is the swapped player being technically functional on scene load, but the camera wont focus on them at all; even manually changing the camera focus via code or timeline doesn't seem to work.
    I guess it mostly comes down to the fact that the swapped player is a Cloned element? but im not sure.
     
  18. BlackGamma

    BlackGamma

    Joined:
    Dec 2, 2019
    Posts:
    25
    I've had trouble getting 'Swap Player' to work, in my previous game I got it set up so when the game starts, the player can choose a character, but at no point after that will the player ever change, due to some issues with energy bars never despawning (if i could figure this out, i could make a rex-rogue). If this is in the scope of what you're aiming for @tirkaroKujo, I might be able to help you out. @thenadamgoes, sorry I haven't tried using URP at all.
     
  19. BlackGamma

    BlackGamma

    Joined:
    Dec 2, 2019
    Posts:
    25
    If anyone is interested in a powerup that affects contact damage for melee attacks that the player already has enabled, rather than disabling/enabling attacks, here is a script for that:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. namespace RexEngine
    6. {
    7.     public class AttackPowerup : Powerup
    8.     {
    9.         public int damageIncrease = 1;
    10.         public bool fishingPowerup = false;
    11.         void Awake()
    12.         {
    13.             idString = "AttackPowerup";
    14.         }
    15.         protected override void TriggerEffect(RexActor actor)
    16.         {
    17.             if (actor == null)
    18.             {
    19.                 return;
    20.             }
    21.  
    22.             if(fishingPowerup == false)
    23.             {
    24.                 foreach (Attack attack in actor.GetComponentsInChildren<Attack>())
    25.                 {
    26.                     if (attack.name != "Fish" && attack.name != "Pay" && attack.name != "SellWood" && attack.name != "SellOre" && attack.name != "SellFood")
    27.                     {
    28.                         foreach (ContactDamage damage in attack.GetComponents<ContactDamage>())
    29.                         {
    30.                             damage.amount += damageIncrease;
    31.                         }
    32.                     }
    33.  
    34.                 }
    35.             }
    36.  
    37.             if (fishingPowerup == true)
    38.             {
    39.                 foreach (Attack attack in actor.GetComponentsInChildren<Attack>())
    40.                 {
    41.                     if (attack.name == "Fish")
    42.                     {
    43.                         foreach (ContactDamage damage in attack.GetComponents<ContactDamage>())
    44.                         {
    45.                             damage.amount += damageIncrease;
    46.                         }
    47.                     }
    48.  
    49.                 }
    50.             }
    51.  
    52.         }
    53.     }
    54. }
    In my current game, I have several "melee attacks" (which act as bartering actions), which I don't want upgraded with any attack upgrades, and then a "fishing" attack, which I only want upgraded with certain powerups. The rest of my player's melee attacks are with a sword, so unless the bool "fishingPowerup" is set to true, it will only affect those. If "fishingPowerup" is true, it will only affect that one "attack". Hopefully some folks could put this to use, and if anyone wants the script stripped down without the fishing/bartering stuff, I'll post that. It'd also be pretty easy to set it up by typing the name of the attack you want to upgrade into a string on the powerup, like the normal attack upgrade powerup that comes with rex engine, so i could post it like that too.
     
    Lars-Steenhoff likes this.
  20. BlackGamma

    BlackGamma

    Joined:
    Dec 2, 2019
    Posts:
    25
    Here is a script for a powerup that affects the player's movement speed!
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. namespace RexEngine
    6. {
    7.     public class SpeedPowerup : Powerup
    8.     {
    9.         public int amount = 1;
    10.         void Awake()
    11.         {
    12.             idString = "SpeedPowerup";
    13.         }
    14.         protected override void TriggerEffect(RexActor actor)
    15.         {
    16.             if (actor == null)
    17.             {
    18.                 return;
    19.             }
    20.  
    21.             MovingState movement = actor.slots.controller.GetComponent<MovingState>();
    22.             {
    23.                 movement.movementProperties.speed += amount;
    24.  
    25.             }
    26.  
    27.  
    28.          
    29.         }
    30.     }
    31. }
    it is set to increase your speed by "amount", but if you change the line "movement.movementProperties.speed += amount;" to "movement.movementProperties.speed == amount;" then it will set to a specific value
     
    tirkaroKujo and Lars-Steenhoff like this.
  21. BlackGamma

    BlackGamma

    Joined:
    Dec 2, 2019
    Posts:
    25
    if anyone wants the scripts to make it so shields add damage resistance, rather than making the player invincible (by subtracting a value from incoming damage) I can post that, it takes changing RexActor, Shield, and ShieldPowerup, but adds more variety to the shields. I'm working on incorporating part of the speed powerup i made so that shields (which are suits of armor in my game) affect the acceleration of the player, if that is something that anyone would be interested in at all too!
     
    Lars-Steenhoff likes this.
  22. Lars-Steenhoff

    Lars-Steenhoff

    Joined:
    Aug 7, 2007
    Posts:
    3,526
    Yes I would like to use those scripts!
     
  23. BlackGamma

    BlackGamma

    Joined:
    Dec 2, 2019
    Posts:
    25
    I've got it set up so each type of shield/armor adjusts the player's speed and acceleration, and has an hp value (like the default shields) which will destroy the shield if at 0 hp, and then the damage resistance value. I tried to find out some way to get an hp bar to spawn in for the shield but I gave up, and made a dumb little thing that holds a "good" sprite, a "worn" sprite, and a "damaged" sprite, and it will display those sprites (by changing the sort order because i don't really know what i'm doing) based on the values you assign to each shield's "worn" and "damaged" values. I think this adds a good level of dynamics with the shield, being able to kind of tell how much hp it has left, but my code for that is a little funky, so lemme know if you want it stripped down to just the damage resistance & speed adjusting properties!

    step 1: in RexActor.cs, in the invincibility properties section, plop this public int in. I put it in line 113 below the "isShieldInvincibilityActive" bool, but I don't think the placement matters as long as it's in the invincibility class.

    Code (CSharp):
    1. public int damageResistance = 0;
    step 2: around line 493 in RexActor, you should find this:

    Code (CSharp):
    1. if(invincibility.isShieldInvincibilityActive)
    2.             {
    3.                 amount = 0;
    4.  
    5.                 if(invincibility.preventKnockbackIfShielded)
    6.                 {
    7.                     willCauseKnockback = false;
    8.                 }
    9.             }
    replace with this:

    Code (CSharp):
    1. if(invincibility.isShieldInvincibilityActive && invincibility.damageResistance >= 0 && unadjustedAmount >= invincibility.damageResistance)
    2.             {
    3.                 amount -= invincibility.damageResistance;
    4.  
    5.                 if(invincibility.preventKnockbackIfShielded)
    6.                 {
    7.                     willCauseKnockback = false;
    8.                 }
    9.             }
    10.  
    11.             if(invincibility.isShieldInvincibilityActive && invincibility.damageResistance >= 0 && unadjustedAmount <= invincibility.damageResistance || invincibility.isShieldInvincibilityActive && invincibility.damageResistance >= 0 && amount == invincibility.damageResistance)
    12.             {
    13.                 amount = 1;
    14.  
    15.                 if (invincibility.preventKnockbackIfShielded)
    16.                 {
    17.                     willCauseKnockback = false;
    18.                 }
    19.             }
    (the second part of this makes it so you'll always take at least 1 damage with shield invincibility, even if your damage resistance is higher than the amount of incoming damage. I can repost it without this if you want shields to be able to prevent any incoming damage.)

    step 3: just replace ShieldPowerup.cs with this:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. namespace RexEngine
    6. {
    7.     public class ShieldPowerup:Powerup
    8.     {
    9.         public RexPool spawnPool;
    10.  
    11.         void Awake()
    12.         {
    13.             idString = "Shield";
    14.         }
    15.         protected override void TriggerEffect(RexActor actor)
    16.         {
    17.             MovingState movement = actor.slots.controller.GetComponent<MovingState>();
    18.  
    19.             if (actor == null)
    20.             {
    21.                 return;
    22.             }
    23.  
    24.             if(!actor.invincibility.isShieldInvincibilityActive && spawnPool)
    25.             {
    26.                 Shield shield = spawnPool.Spawn().GetComponent<Shield>();
    27.                 if(shield)
    28.                 {
    29.                     shield.transform.parent = actor.transform;
    30.                     shield.transform.localPosition = Vector2.zero;
    31.                     DontDestroyOnLoad(shield.gameObject);
    32.                     shield.parentActor = actor;
    33.                     actor.invincibility.damageResistance = shield.resistance;
    34.                     movement.movementProperties.speed -= shield.speedPenalty;
    35.                     movement.movementProperties.acceleration = shield.acceleration;
    36.                     actor.OnDamageTaken += shield.OnParentDamaged;
    37.                 }
    38.             }
    39.  
    40.             if (actor.invincibility.isShieldInvincibilityActive && spawnPool)
    41.             {
    42.                 Shield currentShield = actor.GetComponentInChildren<Shield>();
    43.                 Shield shield = spawnPool.Spawn().GetComponent<Shield>();
    44.                 {
    45.                     currentShield.hp = shield.hp;
    46.                     currentShield.wornHp = shield.wornHp;
    47.                     currentShield.damagedHp = shield.damagedHp;
    48.                     actor.invincibility.damageResistance = shield.resistance;
    49.                     movement.movementProperties.speed += currentShield.speedPenalty;
    50.                     currentShield.speedPenalty = shield.speedPenalty;
    51.                     movement.movementProperties.speed -= shield.speedPenalty;
    52.                     movement.movementProperties.acceleration = shield.acceleration;
    53.                     foreach (SpriteRenderer icon in currentShield.GetComponentsInChildren<SpriteRenderer>())
    54.                     {
    55.                         if (icon.name == "Good")
    56.                         {
    57.                             icon.sortingOrder = 20;
    58.                         }
    59.                         if (icon.name == "Worn")
    60.                         {
    61.                             icon.sortingOrder = -100;
    62.                         }
    63.                         if (icon.name == "Damaged")
    64.                         {
    65.                             icon.sortingOrder = -100;
    66.                         }
    67.                     }
    68.                 }
    69.              
    70.             }
    71.  
    72.             actor.invincibility.isShieldInvincibilityActive = true;
    73.         }
    74.     }
    75. }
    76.  
    step 4: and replace Shield.cs with this:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. namespace RexEngine
    6. {
    7.     public class Shield:MonoBehaviour
    8.     {
    9.         [Tooltip("If True, no amount of damage will break the shield, and it will not be removed unless manually destroyed via a script.")]
    10.         public bool hasUnlimitedHP = false;
    11.  
    12.         [Tooltip("The amount of damage the shield can sustain before being destroyed.")]
    13.         public int hp = 1;
    14.         public int wornHp = 1;
    15.         public int damagedHp = 1;
    16.         public int resistance = 1;
    17.         public float speedPenalty = 1.0f;
    18.         public float acceleration = 0.5f;
    19.         [HideInInspector]
    20.         public RexActor parentActor;
    21.  
    22.         public virtual void OnParentDamaged(int amount, int unadjustedAmount, int currentHP, int totalHP)
    23.         {
    24.  
    25.             if (!hasUnlimitedHP)
    26.             {
    27.                 hp -= unadjustedAmount;
    28.                 if (hp <= 0)
    29.                 {
    30.                     Destroy(gameObject);
    31.                 }
    32.  
    33.                 if (hp <= wornHp)
    34.                 {
    35.                     foreach (SpriteRenderer icon in gameObject.GetComponentsInChildren<SpriteRenderer>())
    36.                     {
    37.                         if (icon.name == "Good")
    38.                         {
    39.                             icon.sortingOrder = -100;
    40.                         }
    41.                         if (icon.name == "Worn")
    42.                         {
    43.                             icon.sortingOrder = 20;
    44.                         }
    45.                     }
    46.                 }
    47.                 if (hp <= damagedHp)
    48.                 {
    49.                     foreach (SpriteRenderer icon in gameObject.GetComponentsInChildren<SpriteRenderer>())
    50.                     {
    51.                         if (icon.name == "Good")
    52.                         {
    53.                             icon.sortingOrder = -100;
    54.                         }
    55.                         if (icon.name == "Worn")
    56.                         {
    57.                             icon.sortingOrder = -100;
    58.                         }
    59.                         if (icon.name == "Damaged")
    60.                         {
    61.                             icon.sortingOrder = 20;
    62.                         }
    63.                     }
    64.                 }
    65.  
    66.             }
    67.             if (parentActor.hp.current == 0)
    68.             {
    69.                 Destroy(gameObject);
    70.             }
    71.            
    72.         }
    73.  
    74.         void OnDestroy()
    75.         {
    76.            
    77.             if (parentActor)
    78.             {
    79.                 MovingState movement = parentActor.slots.controller.GetComponent<MovingState>();
    80.                 parentActor.OnDamageTaken -= this.OnParentDamaged;
    81.                 parentActor.invincibility.isShieldInvincibilityActive = false;
    82.                 parentActor.invincibility.damageResistance = 0;
    83.                 movement.movementProperties.speed += speedPenalty;
    84.                 movement.movementProperties.acceleration = 0.25f;
    85.             }
    86.         }
    87.     }
    88. }
    89.  
    (the last line in that one resets the player's acceleration to 0.25, because all of my players have this as their default accel value, so you should set this to whatever your player's acceleration value is.)

    for this to work as is, each of your shield objects will need to have three child objects with sprite renderer components, named "Good", "Worn", and "Damaged".

    the shield powerup subtracts the speed penalty from your player's speed, and then sets it to the value listed for acceleration. When the shield is destroyed, it adds the speed penalty to your player's speed, and sets the acceleration to 0.25.

    also, i set it up so if you collect another shield while already shielded, it will kinda absorb the new shield's values, so you pretty much get a new shield, but it is still the original object. (this could cause an issue if you have different sprites for each shield's "good, worn & damaged" icons, because those would not be replaced with the new shield's sprites)

    I think that's everything, I hope it works for ya!
     
    Lars-Steenhoff likes this.
  24. BlackGamma

    BlackGamma

    Joined:
    Dec 2, 2019
    Posts:
    25
    I think that you could combine part of the attack.cs script with the climbing & moving state scripts, 'cause I think part of the attack script prevents the attack from being performed if its slotted mp is empty, I can try to look in to this soon, but I think it would just take some copying & pasting. It might be tough with running though cause its part of the normal move state, and I've been pretty lost trying to edit that script specifically.
     
    Lars-Steenhoff likes this.
  25. BlackGamma

    BlackGamma

    Joined:
    Dec 2, 2019
    Posts:
    25
    but it might be easier to try to add something to those states that checks the mp based on the player's rexActor script, rather than adding mp slots to the rex states, and just prevents the ability from being performed if mp =/<= 0. then you'd need to slot your 'stamina' energy into the player's mp slot in rexActor, and if you already had ammo or mana or something slotted in there that might get funky
     
    Lars-Steenhoff likes this.
  26. BlackGamma

    BlackGamma

    Joined:
    Dec 2, 2019
    Posts:
    25
    it became quickly apparent to me that having a leveling up system where the player gains the same amount of hp at the same amount of xp each time is dumb and kind of impossible to balance a game around, so i made a level system that just fits into scorePowerup and scoreManager. the level scale is just based on the fibonacci sequence, which i use in my tabletop rpg, and I think it's a very easy-to-balance scale but the values could be edited in the score powerup script if you want to change the scale. I've chunked up the levels so the bonuses you get from leveling up change at level 6. this will still reset your 'xp'/score to 0 every time you level up, but the value needed will change based on the level. your player will gain hp, and damage for every melee attack, except for those listed, every time they level up, and at levels 3 & 6, the energy/mp for each attack listed will be increased by 25. This is set up for levels 1-10, and at level 11 it stops working. how this works will vary greatly from game to game. I'm not totally sure where I want my levels to cap yet, so i've left it unfinished for the time being, but if someone wants me to post it with an edit where you never pass level 10 and stop gaining xp or something I can do that (at level 11, your xp will keep going up, but you'll never reach level 12). I'm also tempted to try having the player kinda 'reset' at level 10, have their hp and damage reset but max mp stay the same or something to have some rogue-ish type of progression so I might end up posting that too

    in ScorePowerup.cs, add this at line 13 for a level up sound
    Code (CSharp):
    1. [System.Serializable]
    2.         public class Sounds2
    3.         {
    4.             public AudioClip levelUpSound;
    5.         }
    6.         public Sounds2 sounds2;
    and replace this:
    Code (CSharp):
    1. if(equation == Equation.Increment)
    2.             {
    3.                 //Debug.Log("Add " + amount + " to score");
    4.                 ScoreManager.Instance.IncrementScore(amount);
    5.             }
    6.             else
    7.             {
    8.                 //Debug.Log("Remove " + amount + " from score");
    9.                 ScoreManager.Instance.DecrementScore(amount);
    10.             }
    with this:
    Code (CSharp):
    1. if(equation == Equation.Increment)
    2.             {
    3.                 //Debug.Log("Add " + amount + " to score");
    4.                 ScoreManager.Instance.IncrementScore(amount);
    5.  
    6.                 if (ScoreManager.Instance.playerLevel == 1 && ScoreManager.Instance.score >= 100 || ScoreManager.Instance.playerLevel == 2 && ScoreManager.Instance.score >= 100 || ScoreManager.Instance.playerLevel == 3 && ScoreManager.Instance.score >= 200 || ScoreManager.Instance.playerLevel == 4 && ScoreManager.Instance.score >= 300 || ScoreManager.Instance.playerLevel == 5 && ScoreManager.Instance.score >= 500)
    7.                 {
    8.                     GameManager.Instance.player.hp.max += (5);
    9.                     GameManager.Instance.player.RestoreHP(10000);
    10.                     ScoreManager.Instance.playerLevel += 1;
    11.                     ScoreManager.Instance.SetScore(0);
    12.                     ScoreManager.Instance.SetScoreAtCheckpoint(0);
    13.                     PlaySoundIfOnCamera(sounds2.levelUpSound);
    14.                     foreach (Attack attack in player.GetComponentsInChildren<Attack>())
    15.                     {
    16.                         if (attack.name != "Fish" && attack.name != "Pay" && attack.name != "SellWood" && attack.name != "SellOre" && attack.name != "SellFood")
    17.                         {
    18.                             foreach (ContactDamage damage in attack.GetComponents<ContactDamage>())
    19.                             {
    20.                                 damage.amount += 1;
    21.                             }
    22.                         }
    23.  
    24.                         if (ScoreManager.Instance.playerLevel == 3 && (attack.name == "SellFood" || attack.name == "SellWood" || attack.name == "SellOre"))
    25.                         {
    26.                                 if (attack.name == "SellFood")
    27.                                 {
    28.                                     attack.slots.mp.max += 25;
    29.                                 }
    30.                                 if (attack.name == "SellWood")
    31.                                 {
    32.                                     attack.slots.mp.max += 25;
    33.                                 }
    34.                                 if (attack.name == "SellOre")
    35.                                 {
    36.                                     attack.slots.mp.max += 25;
    37.                                 }
    38.                         }
    39.  
    40.                     }
    41.                 }
    42.                 else if (ScoreManager.Instance.playerLevel == 6 && ScoreManager.Instance.score >= 800 || ScoreManager.Instance.playerLevel == 7 && ScoreManager.Instance.score >= 1300 || ScoreManager.Instance.playerLevel == 8 && ScoreManager.Instance.score >= 2100 || ScoreManager.Instance.playerLevel == 9 && ScoreManager.Instance.score >= 3400 || ScoreManager.Instance.playerLevel == 10 && ScoreManager.Instance.score >= 5500)
    43.                 {
    44.                     GameManager.Instance.player.hp.max += (10);
    45.                     GameManager.Instance.player.RestoreHP(10000);
    46.                     ScoreManager.Instance.playerLevel += 1;
    47.                     ScoreManager.Instance.SetScore(0);
    48.                     ScoreManager.Instance.SetScoreAtCheckpoint(0);
    49.                     PlaySoundIfOnCamera(sounds2.levelUpSound);
    50.                     foreach (Attack attack in player.GetComponentsInChildren<Attack>())
    51.                     {
    52.                         if (attack.name != "Fish" && attack.name != "Pay" && attack.name != "SellWood" && attack.name != "SellOre" && attack.name != "SellFood")
    53.                         {
    54.                             foreach (ContactDamage damage in attack.GetComponents<ContactDamage>())
    55.                             {
    56.                                 damage.amount += 3;
    57.                             }
    58.  
    59.                             if (ScoreManager.Instance.playerLevel == 6 && (attack.name == "SellFood" || attack.name == "SellWood" || attack.name == "SellOre"))
    60.                             {
    61.                                 if (attack.name == "SellFood")
    62.                                 {
    63.                                     attack.slots.mp.max += 25;
    64.                                 }
    65.                                 if (attack.name == "SellWood")
    66.                                 {
    67.                                     attack.slots.mp.max += 25;
    68.                                 }
    69.                                 if (attack.name == "SellOre")
    70.                                 {
    71.                                     attack.slots.mp.max += 25;
    72.                                 }
    73.                             }
    74.  
    75.                         }
    76.  
    77.                     }
    78.                 }
    79.  
    80.             }
    81.             else
    82.             {
    83.                 //Debug.Log("Remove " + amount + " from score");
    84.                 ScoreManager.Instance.DecrementScore(amount);
    85.                 if (ScoreManager.Instance.score <= 0)
    86.                 {
    87.                     ScoreManager.Instance.SetScoreAtCheckpoint(0);
    88.                 }
    89.  
    90.             }
    in ScoreManager.cs, add this at line 14:
    Code (CSharp):
    1. public TextMesh text;
    2.         public int totalDigitsLevel = 1;
    and then replace this
    Code (CSharp):
    1. protected void UpdateDisplay()
    2.         {
    3.             text.text = score.ToString().PadLeft(totalDigits, '0');
    4.         }
    with this
    Code (CSharp):
    1. protected void UpdateDisplay()
    2.         {
    3.             text.text = score.ToString().PadLeft(totalDigits, '0');
    4.             levelText.text = playerLevel.ToString().PadLeft(totalDigitsLevel, '0');
    5.         }
    this will also give you a slot to put a text display to show your player's level in the scoreManager object in the Singletons prefab
     
    tirkaroKujo likes this.
  27. evolgenius81

    evolgenius81

    Joined:
    Apr 18, 2019
    Posts:
    1
    its gone! :( I can't see how to get it on the website, and it's not in asset store. I want to cry now. T_T
     
  28. PhantomFox128

    PhantomFox128

    Joined:
    May 22, 2019
    Posts:
    157
    So, this probably isn't related to Rex, but in case it is, is there a way set a particle effect to play at a specific time during an attack?
     
  29. BlackGamma

    BlackGamma

    Joined:
    Dec 2, 2019
    Posts:
    25
    I'm sorry, i'm definitely lost when it comes to particles, but if you're using sprite animation, it'd be pretty easy to slot a particle-like animation in the attack's animator (not for the player or projectile but for the attack itself)
     
    PhantomFox128 likes this.
  30. BlackGamma

    BlackGamma

    Joined:
    Dec 2, 2019
    Posts:
    25
    if anybody is interested in making projectiles launched via 8-way aiming rotate based on the attack direction (sort of like how projectiles launched at a target or angle via AI does it) just replace this chunk of projectile.cs at line 226
    Code (CSharp):
    1. slots.spriteRenderer.transform.localEulerAngles = new Vector3(0.0f, 0.0f, 0.0f);
    2.  
    3.             slots.physicsObject.SetVelocityX(startingXSpeed * (int)direction.horizontal);
    4.             slots.physicsObject.SetAccelerationCapX(movementSpeed.x * (int)direction.horizontal);
    5.  
    6.             slots.physicsObject.SetVelocityY(startingYSpeed * (int)direction.vertical);
    7.             slots.physicsObject.SetAccelerationCapY(movementSpeed.y * (int)direction.vertical);
    with this!
    Code (CSharp):
    1. float angle = 0.0f;
    2.             if(spawningActor.slots.input.verticalAxis == 0.0f)
    3.             {
    4.                 angle = 0.0f;
    5.             }
    6.             else if (spawningActor.slots.input.verticalAxis <= 0.0f)
    7.             {
    8.                 if (spawningActor.slots.input.horizontalAxis == 0.0f)
    9.                 {
    10.                     angle = 90.0f;
    11.                 }
    12.                 else if (spawningActor.slots.input.horizontalAxis <= 0.0f)
    13.                 {
    14.                     angle = 45.0f;
    15.                 }
    16.                 else if (spawningActor.slots.input.horizontalAxis >= 0.0f)
    17.                 {
    18.                     angle = 45.0f;
    19.                 }
    20.             }
    21.             else
    22.             {
    23.                 if (spawningActor.slots.input.horizontalAxis == 0.0f)
    24.                 {
    25.                     angle = 90.0f;
    26.                 }
    27.                 else if (spawningActor.slots.input.horizontalAxis <= 0.0f)
    28.                 {
    29.                     angle = 45.0f;
    30.                 }
    31.                 else if (spawningActor.slots.input.horizontalAxis >= 0.0f)
    32.                 {
    33.                     angle = 45.0f;
    34.                 }
    35.             }
    36.  
    37.             slots.physicsObject.SetVelocityX(startingXSpeed * (int)direction.horizontal);
    38.             slots.physicsObject.SetAccelerationCapX(movementSpeed.x * (int)direction.horizontal);
    39.  
    40.             slots.physicsObject.SetVelocityY(startingYSpeed * (int)direction.vertical);
    41.             slots.physicsObject.SetAccelerationCapY(movementSpeed.y * (int)direction.vertical);
    42.  
    43.             slots.spriteRenderer.transform.localEulerAngles = new Vector3(0.0f, 0.0f, angle);
     
  31. BlackGamma

    BlackGamma

    Joined:
    Dec 2, 2019
    Posts:
    25
    ** actually, i guess this is only working for projectiles that aren't animated for some reason... i'm working on fixing that
     
  32. PhantomFox128

    PhantomFox128

    Joined:
    May 22, 2019
    Posts:
    157
    Has anyone found a way to implement a variable jump height that changes how high the player can go depending on how long the jump button is pressed? The options currently there don't seem to do much in that regard (tapping and holding the jump button has barely any difference) and from what I can gather, it wouldn't be easy to implement that in the JumpState script.
     
  33. jeremyfryc

    jeremyfryc

    Joined:
    Mar 11, 2014
    Posts:
    95
    Hey, long time no see... Still here plugging away with RexEngine. To answer your question -- this is controlled already with RexEngine. On the JumpState, the "Min Frames" and "Max Frames" amounts are essentially equal to how long the jump button is pressed. If even states that in the notes, if you hover over "Min Frames" or "Max Frames". Hope this helps!
     
    PhantomFox128 likes this.
  34. PhantomFox128

    PhantomFox128

    Joined:
    May 22, 2019
    Posts:
    157
    I've tried adjusting those before, but unfortunately it doesn't give the result I'm looking for. The values I currently have with it are fine when it comes to game feel and function (max jump height, speed and gravity are fine and it plays nicely with the animations that are set), I just can't get the player to essentially be able to "short hop." Again, tapping the jump button or holding it down yields almost no difference. Currently, my Min Frames is 1, Max Frames is 8, and Speed is 25.
    jumpstate.png

    I've tried increasing the Max Frames/Speed, but I either get a jump that goes way too high and/or it messes up the animations a bit on top of feeling too floaty, if that makes sense.

    EDIT: So I tried doubling the Min Frames and Max Frames to 2 and 16 respectively while also setting the Gravity to 2 (originally it was set to 1). This is actually mostly doing what I'm looking for, but gravity does feel a bit too strong and the Cresting Jump animation no longer plays. I don't know what that's about.
     
    Last edited: Mar 6, 2021
  35. jeremyfryc

    jeremyfryc

    Joined:
    Mar 11, 2014
    Posts:
    95
    Yeah, I hear you. You're just going to have to do iteration upon iteration. You'll find the what you want. But at the same time, indie development is sometimes about compromise. You may have to compromise exactly what you want for what you are able to do. Also, once people start play testing your game, they may want you to iterate further on the jump mechanic. This happened with me and my game. I thought it was perfect... I sent it out to some people, and they wanted the player more responsive. So, I had to change it. Keep at it. You'll find what you are looking for.
     
    PhantomFox128 likes this.
  36. PhantomFox128

    PhantomFox128

    Joined:
    May 22, 2019
    Posts:
    157
    So after some tweaking, it seems like I managed to get it working! As for the animation, the problem was I set some frames from the jump animation to the beginning of the cresting jump animation so that it would sync up with the previous settings. Removing some of those frames seems to have fixed it. Still gonna take a bit of tweaking, but I finally got it where it needs to be! Thanks for the help! I appreciate it.
     
    jeremyfryc likes this.
  37. PhantomFox128

    PhantomFox128

    Joined:
    May 22, 2019
    Posts:
    157
    So, I just realized that Unity 2020 is now in LTS and was wondering if there are any Rex users that can verify that Rex works with it?
     
  38. andreiagmu

    andreiagmu

    Joined:
    Feb 20, 2014
    Posts:
    175
    Hi! Has anyone implemented "one-way camera/level scrolling" with Rex Engine? Like in the original Super Mario Bros. (NES), where you can scroll the camera to the right as you walk, but not back to the left.
    Or like in Sonic Jump, where you can scroll up in the level, but not downwards.

    I haven't tested with 2020 LTS, but I can definitely say that Rex Engine is working perfectly in Unity 2021.1 beta. So, I guess it also works with 2020 LTS.
     
    PhantomFox128 likes this.
  39. PhantomFox128

    PhantomFox128

    Joined:
    May 22, 2019
    Posts:
    157
    Just upgraded to 2020, and the entire camera is messed up and I can't figure out how to get it back to normal. During gameplay, the whole thing looks zoomed in and it seems like no amount of tweaking will zoom it out. Did anyone else go through something similar?
    I'm also using the URP and ProCamera2D.
     
  40. andreiagmu

    andreiagmu

    Joined:
    Feb 20, 2014
    Posts:
    175
    @Azerkit I'm using 2021.1 with URP, I did have some camera issues, but I don't remember if it was your same issue.
    I had to comment out some things on the RexCamera script (the cullingMask initializations on Awake, for instance), because I changed my camera logic from Rex's default multi-camera setup, to a single camera setup. (because the multi-camera setup was running slow on mobile)

    Maybe that would help you, to try using a single camera setup.
    Or maybe this is something ProCamera2D related, but I don't use that plugin, so I don't know how it works.
     
  41. jeremyfryc

    jeremyfryc

    Joined:
    Mar 11, 2014
    Posts:
    95
    Hey guys, I just wanted to chime in and mention that I've been using Unity 2020 since it's release and I have no issues with it and RexEngine. Of course, I'm not using any lighting systems in my game, so no URP or anything like that. Just good 'ol pixel art.

    There's one finicky thing, and that's the RexEngine GUI. If it's unlocked, which it typically is, parts of the GUI will flicker across the Unity GUI. It doesn't affect any of the actual sprite rendering in game, in the editor or in a build. I've even made builds in Unity 2020 on Mac and PC with no issues. It's just over the actual Unity GUI. I dunno what it is. I just lock the RexEngine GUI when I'm not adjusting level sizes and stuff and the flicker goes away. BTW, I'm using Unity 2020.2.4f1.

    Hope that helps!
     
    PhantomFox128 and andreiagmu like this.
  42. PhantomFox128

    PhantomFox128

    Joined:
    May 22, 2019
    Posts:
    157
    Okay, so I don't know if it was because I messed around with the camera for a bit or because I essentially re-imported most of my assets after upgrading, but the problem I had was caused by a camera component that showed up on my player prefab somehow. Disabling it fixed the issue, so I straight up removed the component. Doing this also removed a script attached to the player called Universal Additional Camera Data which, looking at a backup I have, was also there, but it doesn't seem to be affecting anything, so I'm assuming it's fine.

    A more problematic issue I've had since upgrading though is the landing animation now gets stuck on loop if the player stays still after hitting the ground. It also gives this error:

    NullReferenceException: Object reference not set to an instance of an object
    RexEngine.LandingState.SpawnLandingParticle () (at Assets/RexEngine/Scripts/RexEngine/_States/LandingState.cs:120)
    RexEngine.LandingState+<LandingCoroutine>d__12.MoveNext () (at Assets/RexEngine/Scripts/RexEngine/_States/LandingState.cs:101)
    UnityEngine.SetupCoroutine.InvokeMoveNext (System.Collections.IEnumerator enumerator, System.IntPtr returnValueAddress) (at <10564ed154d647e194bef4aef8878649>:0)
    UnityEngine.MonoBehaviour:StartCoroutine(String)
    RexEngine.LandingState:OnBegin() (at Assets/RexEngine/Scripts/RexEngine/_States/LandingState.cs:57)
    RexEngine.RexController:SetState(RexState, Boolean) (at Assets/RexEngine/Scripts/RexEngine/_Abstracts/RexController.cs:280)
    RexEngine.RexState:Begin(Boolean) (at Assets/RexEngine/Scripts/RexEngine/_States/RexState.cs:70)
    RexEngine.RexController:ApplyPhysicsObjectFlags() (at Assets/RexEngine/Scripts/RexEngine/_Abstracts/RexController.cs:666)
    RexEngine.RexController:FixedUpdate() (at Assets/RexEngine/Scripts/RexEngine/_Abstracts/RexController.cs:211)

    Again, the camera is the only thing I've touched since upgrading, so I don't know what's causing this.
     
  43. thenadamgoes

    thenadamgoes

    Joined:
    Apr 26, 2019
    Posts:
    29
    I'm also having some camera and other issues. I upgraded to Procamera and switched to a perspective camera because I was using the URP and experimental 2D lighting. It most works and looks fantastic...

    However, it's sorta messed up the boundaries to each area. my character gets stuck before getting to the edge of the room and just can't move.

    What's even weird though...my partner who is working on the same game and we use Unity collaborate to sync our builds...isn't having this issue at all.

    I honestly can't figure out what it is. I'm this close to deleting the entire project and resyncing from an older build. It's driving me nuts.
     
  44. thenadamgoes

    thenadamgoes

    Joined:
    Apr 26, 2019
    Posts:
    29
    So I figured out what was causing this, but I'm no closer to understanding why. In the game window if I manually set the resolution to 4K, it all works perfectly. But if I use any of the preselected aspect ratios (even 16:9) I get this problem where I get stuck in the boundary. I'm not gonna worry about it now since it's working, but it's weird.
     
  45. jhasselbach22

    jhasselbach22

    Joined:
    Sep 15, 2018
    Posts:
    3
    Would anyone know if it is possible to use Call Function on the World Action Sequence Set to enable/disable a sub bool of an ability state by chance? I am trying to make it so I pickup an item and it turns on the canRun bool of the Moving State only.
     

    Attached Files:

  46. andreiagmu

    andreiagmu

    Joined:
    Feb 20, 2014
    Posts:
    175
    You could write a new method, that only sets canRun = true, and call this new method on that Method Name field.
     
  47. jhasselbach22

    jhasselbach22

    Joined:
    Sep 15, 2018
    Posts:
    3
    Thank you for the reply @andreiagmu but I am one of those typical cannot code and typically use playmaker for things like this. With no playmaker integration I will just have to work on continuing to learn to code properly. I have looked at a couple of examples and think I might be able to figure it out so thank you. I would like to integrate something with the World Action Sequence Set to make it easier to set things like Health, number of jumps, and so forth upon picking up an item but will have to dig in deep.

    Thank you once again for your time.
     
    geraldp48 and andreiagmu like this.
  48. ShirohelmDev

    ShirohelmDev

    Joined:
    Jun 26, 2019
    Posts:
    32
    i have figured out how to implement metroidstyle maps but i have to still actually implement it...
    ive also figured out how to do enemies and objects that can only be damaged certain ways

    heres the things i need to implement;
    8 way aiming but where the actual character can be individually animated for every animation direction
    teleporting enemies
    saving i think should be easy enough
     
  49. ShirohelmDev

    ShirohelmDev

    Joined:
    Jun 26, 2019
    Posts:
    32
  50. ShirohelmDev

    ShirohelmDev

    Joined:
    Jun 26, 2019
    Posts:
    32
    i can confirm that with this package it is possible to do 8 way aiming... and for the player to actually be animated differently depending on where they point... true 8 way aiming....
     

    Attached Files:

    Lars-Steenhoff likes this.