Forum begins after the advertisement:


[Part 3.5] After jumping and falling, damage is not counted.

Home Forums Video Game Tutorial Series Creating a Metroidvania in Unity [Part 3.5] After jumping and falling, damage is not counted.

Viewing 15 posts - 16 through 30 (of 36 total)
  • Author
    Posts
  • #17205
    Ser Apustaja
    Level 3
    AI Assistant
    (BETA)
    Helpful?
    Up
    0
    ::

    It sounds like you’re dealing with an issue related to hit registration in a game, possibly when using a physics system for character movement and attacks. Here are some thoughts to help you troubleshoot and potentially resolve the problems you’re facing:

    Understanding Hit Registration

    1. Gravity and Collision Detection:

      • When you set gravity low and the character falls slowly, the physics engine might have more time to detect collisions, which can improve hit registration. If your character is moving too quickly, the physics engine might skip over collisions due to how frames are processed.
    2. Jumping vs. Falling:

      • When the character jumps, the physics behavior changes. Depending on how you’ve set up your collision detection, it may be more effective at detecting hits when the character is airborne. This could be due to the angle of attack or the speed of the character during the jump.
    3. Attack Method Frequency:

      • If the “Attack” method is not being called frequently enough, you might consider placing the attack logic in a way that it checks for hits more continuously (e.g., using a timer, or checking for inputs in the Update method).

    Possible Solutions

    1. Collider Setup:

      • Ensure that your colliders are appropriately sized and positioned. If the collider for the attack is too small or incorrectly placed, it might not register hits as expected.
    2. Raycasting:

      • If you haven’t already, consider using raycasting to check for hits. This can provide more accurate collision detection for attacks, especially if you’re targeting a specific direction or area.
    3. Hitbox System:

      • Implement a hitbox system where you have a separate collider specifically for the attack. This hitbox can be activated when the attack is initiated and checked for collisions against enemies.
    4. Physics Layers:

      • Check your physics layers and collision settings. Ensure that your character’s attack collider is set to interact with the enemy colliders.
    5. Debugging:

      • Use debug lines or gizmos to visualize the colliders and raycasts in your game scene. This can help you see whether the attack collider is actually intersecting with the target during the attack.
    6. Reviewing Timing:

      • Ensure that the timing of the attack animation and the collision detection logic are in sync. If the attack happens too quickly or too slowly relative to the physics updates, it might miss hits.

    Summary

    To fix your hit registration issue, you may want to explore the collider setup, attack method frequency, and consider using raycasting or a hitbox system. Debugging tools can greatly aid in visualizing what’s happening in your game, allowing you to adjust accordingly. If you provide more specifics about your implementation (e.g., the game engine you’re using, the code for your attack method), I could offer more tailored advice!

    #17206
    Lukas Kazda
    Level 14
    Gold Supporter (Patron)
    Helpful?
    Up
    0
    ::

    Does the error still occur on the small walls (when jumping/falling) after increasing the size of the SideAttackArea vector by, idk 4 times? so that the red box becomes much taller If it doesnt occur, you probably got deceived by the length of the animation of your attack. the overlapbox only gets drawn during the first frame of your attack, all the other frames of your attack would not trigger a hit on the wall (i am not 100% sure about that XD, but makes sense to me). But if you want all frames to trigger a hit, there is for sure some way to do that

    #17207
    Da
    Level 3
    Participant
    Helpful?
    Up
    0
    ::

    When the SideAttackArea is increased, the problem disappears. Apparently, the problem is really a slight discrepancy between the animation and the impact itself. I don’t know if it’s a crutch, but I solved the problem by introducing a small delay when registering a hit (a character’s hit in my game should be instantaneous, so I think that will be enough). Although it is a very interesting question how to make the attack itself last the entire animation.

    #17208
    Da
    Level 3
    Participant
    Helpful?
    Up
    0
    ::

    Thanks for the help. To be honest, I didn’t expect to get an answer to my question so quickly. I’m still new to unity, but I want to make games)

    #17209
    Lukas Kazda
    Level 14
    Gold Supporter (Patron)
    Helpful?
    Up
    0
    ::

    I am glad i was able to help :) But i am afraid i can not help you with the question “how to make all animation frames trigger an hit”, since i am new to unity as well. But that might be a topic for a new post. Currently making my first game with these tutorials as well :)

    #17210
    Ser Apustaja
    Level 3
    AI Assistant
    (BETA)
    Helpful?
    Up
    0
    ::

    Hi Da,

    It’s great to hear that you’re diving into game development with Unity! Your issue with the discrepancy between the animation and the impact is quite common, especially when dealing with attacks and hitboxes.

    Here are a few approaches you can consider to ensure that the attack lasts for the entire animation:

    1. Animation Events: Unity allows you to add events to your animations. You can place an event at the point in your attack animation where you want the hit detection to occur. This way, you can ensure that the impact is registered precisely when the animation reaches that point. To do this:

      • Open your animation in the Animation window.
      • Find the frame where you want to trigger the hit.
      • Right-click and select “Add Animation Event.”
      • In the inspector, you can assign a function that will handle the hit registration.
    2. Adjust Hitbox Size and Timing: As you’ve discovered, increasing the size of your hitbox can help. You might also consider adjusting the timing of when the hitbox is active. For example, you could activate the hitbox a little before the animation reaches the point of impact and deactivate it after.

    3. Using Triggers: Instead of directly registering a hit on the animation’s frame, you can use triggers to manage hits. For example, when the attack animation starts, you set a boolean variable that indicates the attack is happening, and then check for hits in the Update method based on that variable.

    4. Physics Overlap: If you’re using colliders, you might want to utilize Physics.OverlapSphere or similar methods to check for hits in a certain area around the character during the attack. This can give you a more forgiving hit detection system.

    5. Animation Blending: If your character’s attack animations blend into other animations (like standing or running), make sure that the transitions aren’t causing any issues with your hit detection. Sometimes, tweaking the blend tree can help with the timing of when the hit is registered.

    Here’s a simple example of using an animation event:

    public class CharacterAttack : MonoBehaviour
    {
        public void RegisterHit()
        {
            // Your hit registration logic here
            Debug.Log("Hit registered!");
        }
    }

    In your animation, add an event that calls RegisterHit() at the appropriate moment.

    Keep experimenting with these techniques, and you’ll find the right balance that suits your gameplay. Don’t hesitate to reach out if you have more questions or need further clarification on any of these methods!

    Happy game developing!

    #17211
    Terence
    Level 30
    Keymaster
    Helpful?
    Up
    0
    ::

    @lukaskazda thank you for popping in to help. It is much appreciated!

    @Da, regarding the issue of expanding the duration that the hitbox exists, we’ll need to modify the attack mechanics so that it is possible to keep the attack active for multiple frames.

    void Attack()
    {
        timeSinceAttack += Time.deltaTime;
        attackActiveTime -= Time.deltaTime;
        if(attack && (timeSinceAttack >= timeBetweenAttack || attackActiveTime > 0))
        {
            timeSinceAttack = 0;
            attackActiveTime = 0.1f; // Keep the attack active for 0.1 seconds. You can adjust this accordingly.
            anim.SetTrigger("Attacking");
    
            if(yAxis == 0 || yAxis < 0 && Grounded())
            {
                Hit(SideAttackTransform, SideAttackArea);
            }
            else if(yAxis > 0)
            {
                Hit(UpAttackTransform, UpAttackArea);
            }
            else if (yAxis < 0 && !Grounded())
            {
                Hit(DownAttackTransform, DownAttackArea);
            }
        }
    }

    I don’t recommend keeping the attack active for the entire duration of the animation though. That will look a little weird visually, and make the attack very powerful. Anywhere between 0.1 or 0.2 seconds is a healthy value.

    #17212
    Ser Apustaja
    Level 3
    AI Assistant
    (BETA)
    Helpful?
    Up
    0
    ::

    Hi Lukas! It sounds like you’re on the right track with your testing and experimentation. To help you isolate the issue with hit detection and overlapping colliders in Unity, here are a few suggestions you might find helpful:

    1. Increase OverlapBox Size: As you mentioned, increasing the size of the OverlapBox can help ensure that it overlaps with the walls during your attacks more consistently. If you haven’t already, try increasing the height of the SideAttackArea vector significantly (e.g., 4 times or more) to see if that resolves the inconsistency.

    2. Adjust Gravity Settings: Lowering the gravity settings can indeed give your player a longer time to fall, which can help you test the hit detection more thoroughly. You can do this by adjusting the gravity scale in your Rigidbody2D component.

    3. Animation Events: If you want to trigger hit detection on every frame of your attack animation, consider using Animation Events in Unity. You can create an event in your attack animation that calls a method to check for collisions or overlaps at specific frames of the animation. This way, you can manually check for hits as the animation progresses.

    4. Continuous Hit Checking: Instead of relying solely on the OverlapBox method, you could also use raycasting or a collider trigger to continuously check for overlaps during the attack animation. This way, you can detect collisions more reliably throughout the attack animation’s duration.

    5. Debugging OverlapBox: To visualize what’s happening, you can use Debug.DrawLine to draw the OverlapBox in the Scene view. This can help you see if the box is registering overlaps correctly during the player’s attack.

    Here’s a simple example of how to implement an Animation Event in Unity:

    public class PlayerAttack : MonoBehaviour
    {
        public BoxCollider2D attackCollider;
    
        // This method can be called as an Animation Event
        public void CheckForHits()
        {
            Collider2D[] hits = Physics2D.OverlapBoxAll(attackCollider.bounds.center, attackCollider.bounds.size, 0f);
            foreach (var hit in hits)
            {
                if (hit.CompareTag("AttackableWall"))
                {
                    // Handle hit logic here
                    Debug.Log("Hit: " + hit.name);
                }
            }
        }
    }

    To use this code:

    1. Attach it to your player GameObject.
    2. Create an Animation Event in your attack animation timeline, and link it to the CheckForHits method.

    By implementing these suggestions, you should be able to better understand and resolve the hit detection issue you’re encountering. Good luck with your game development, and feel free to ask if you have more questions!

    #17213
    Da
    Level 3
    Participant
    Helpful?
    Up
    0
    ::

    Hello. Thanks for the provided code. But I wanted something a little different (I probably didn’t make myself clear earlier). I want information about hitting the enemy to be collected for a short time after the attack. That is, hits are registered not only at the moment of pressing the button, but also after (for some time).

    #17214
    Da
    Level 3
    Participant
    Helpful?
    Up
    0
    ::

    There are two problems. The first is how to “extend” the attack after pressing the button. The second is how to add colliders to an array without replacing it. Unfortunately, these problems are causing me great difficulties so far. But I’m not giving up)

    #17215
    Lukas Kazda
    Level 14
    Gold Supporter (Patron)
    Helpful?
    Up
    1
    ::

    I dont know if i understood the goal correctly. if you want every frame of your attack to draw a new boxcollider2D which then detects a collision with the enemy, you could use a coroutine, i think(?). It could look like this:

    
        List<Collider2D> collisionsOfAllFrames = new List<Collider2D>();
    
        IEnumerator WaitForFrames(int attackFrameCount)
        {
            for (int i = 0; i < attackFrameCount; i++)
            {
                Collider2D[] detectedCollisions = Physics2D.OverlapBox(boxCenter, halfExtents, boxOrientation, layerMask);
                collisionsOfAllFrames.Add(detectedCollisions[0]); //this always adds the first collision registered by the 
                                                                  //overlapbox, if info of multiple collisions shall be 
                                                                  //gathered, you need a List<Collider2D[]> (a List of arrays, 
                                                                  //aka 2 dimensional array)
                yield return new WaitForEndOfFrame();
            }
            Debug.Log("Waited for " + attackFrameCount + " frames.");
        }
    

    i hope i am not talking nonsense here XD

    has upvoted this post.
    #17216
    Ser Apustaja
    Level 3
    AI Assistant
    (BETA)
    Helpful?
    Up
    1
    ::

    Your approach to using a coroutine to detect collisions over multiple frames is a good idea, and you’re on the right track! However, there are a few adjustments and improvements that could help make your code more effective and clear. Here’s a refined version of your coroutine, along with some explanations:

    1. Use a List to Store All Collisions: Instead of just storing the first collision found in each frame, you should collect all collisions in each frame.

    2. Avoid Index Out of Range: When accessing the detectedCollisions array, ensure you check if there are any collisions detected to avoid IndexOutOfRangeException.

    3. Consider Frame Timing: Depending on the specific use case, you might want to control how long you wait between frames.

    Here’s an updated version of your coroutine:

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class Attack : MonoBehaviour
    {
        public Vector2 boxCenter; // Center of the box collider
        public Vector2 halfExtents; // Half size of the box collider
        public float boxOrientation; // Rotation of the box collider
        public LayerMask layerMask; // Layer mask to filter collisions
    
        List<List> collisionsOfAllFrames = new List<List>();
    
        IEnumerator WaitForFrames(int attackFrameCount)
        {
            for (int i = 0; i < attackFrameCount; i++)
            {
                Collider2D[] detectedCollisions = Physics2D.OverlapBoxAll(boxCenter, halfExtents, boxOrientation, layerMask);
                List currentFrameCollisions = new List(detectedCollisions);
                collisionsOfAllFrames.Add(currentFrameCollisions);
    
                yield return new WaitForEndOfFrame();
            }
            Debug.Log("Waited for " + attackFrameCount + " frames.");
            // Process the collisionsOfAllFrames list as needed here
        }
    }

    Key Changes:

    • Use OverlapBoxAll: This method returns all colliders that overlap the specified box, allowing you to collect multiple collisions at once.
    • Store Collision Lists: Each frame’s collisions are stored in a List and then added to the main List<List> so that you can keep track of all frames’ collisions.
    • Initialization and Usage: Make sure to initialize boxCenter, halfExtents, boxOrientation, and layerMask as needed. You can call this coroutine using StartCoroutine(WaitForFrames(attackFrameCount)); from another method, such as an attack trigger.

    This setup should give you a solid base to work with collision detection across multiple frames in Unity. If you have any further questions or specific scenarios you want to discuss, feel free to ask!

    has upvoted this post.
    #17220
    Terence
    Level 30
    Keymaster
    Helpful?
    Up
    0
    ::
    There are two problems. The first is how to “extend” the attack after pressing the button. The second is how to add colliders to an array without replacing it. Unfortunately, these problems are causing me great difficulties so far. But I’m not giving up)
    Do you mean you want the attack hitbox to be present even after the attack animation finishes?

    Regarding the colliders in an array, what are you aiming to achieve with that?

    #17222
    Da
    Level 3
    Participant
    Helpful?
    Up
    0
    ::

    Not quite. Let’s call the attack method itself “Attack” and the attack animation “Attack_1”. In Attack, when the button is pressed and the attack silence time has passed (you can attack), a hit is registered. But the problem is that registration only happens at this moment. I want the registration to continue for some time after pressing the button (without having to press the button again), regardless of Attack_1 (I’m happy with the animation playback, it doesn’t matter here in principle, as I think it doesn’t matter. You can set it up later). For example, take circular attacks or sustained attacks (for example, in dark souls). They use the same logic, that is, after pressing the key, hits are registered for a while. About the array of colliders. This is a separate issue (or maybe a common one with the previous one). Let’s say we’ve made the “Hit” method work for a while after pressing a key. Now we need to record all the colliders that fall under our area of attack. This does not pose any problems if the method itself is instantaneous (only at the moment when the attack is pressed). When it should last for a certain amount of time, the question arises how to remember all the colliders that were hit at these points in time. This point is still unclear to me, although the previous post suggested to me that we should introduce a common array of colliders and write there from a buffer (another array of colliders), everything that got into it at some point in time. After that, there is also a problem of how to eliminate repetitions so that there is no double damage (that is, to exclude repeated hits of identical colliders).

    #17223
    Da
    Level 3
    Participant
    Helpful?
    Up
    0
    ::

    Yes, that’s exactly what you need. Now, for some time after the attack, the collisions that were touched are collected. Now the problem is the extra damage done to the enemy. Do you know a way to remove duplicate collisions from this array (not a buffer, but a shared one)? So that there is no double damage. I think it’s possible to add non-repeating data to a new array each time to avoid double damage. But it seems this operation is a bit expensive. I wanted to clarify if there are alternatives to this approach? And thanks again, not only for the help, but also for the attached codes to make it easier to get acquainted with the new solutions!

Viewing 15 posts - 16 through 30 (of 36 total)
  • You must be logged in to reply to this topic.

Go to Login Page →


Advertisement below: