Topic: Is there a way to spawn a permanent hitbox with the stage?

I've looked in the forums and I understand platforms aren't possible without reworks but what about hitboxes? I've tried just adding them to the stage prefab but UFE Doesn't recognize it in the spawn pool and it isn't included in the UFEFixedUpdate calls. Does anyone know how to spawn a Projectile Move Script without using a move file?

Otherwise I would just change the intro animation to a move file and spawn it that way but that seems fairly jank and easy to mess up where it would need to be.

Share

Thumbs up Thumbs down

2 (edited by benmade1 2024-03-06 18:55:40)

Re: Is there a way to spawn a permanent hitbox with the stage?

Figured it out but want to share for anyone in the future.

So first of all I added a public array of MoveInfo to StageOptions.cs
Then went to GlobalEditorWindow.cs and added the following code to the end of the stageOptions group (Looks ugly but I was having trouble using panels).

stageHitBoxesToggle = EditorGUILayout.Foldout(stageHitBoxesToggle, "Stage Hitboxes (" + globalInfo.stages[i].hitBoxes.Length + ")", foldStyle);
    if (stageHitBoxesToggle)
    {
        for (int h = 0; h < globalInfo.stages[i].hitBoxes.Length; h++)
        {
            globalInfo.stages[i].hitBoxes[h] = (MoveInfo)EditorGUILayout.ObjectField(globalInfo.stages[i].hitBoxes[h], typeof(MoveInfo));
            if (SmallButton("Delete Hitbox"))
                globalInfo.stages[i].hitBoxes = RemoveElement<MoveInfo>(globalInfo.stages[i].hitBoxes, globalInfo.stages[i].hitBoxes[h]);
        }

        if (StyledButton("New Hitbox"))
    globalInfo.stages[i].hitBoxes = AddElement<MoveInfo>(globalInfo.stages[i].hitBoxes, null);
    }

Next I went to Projectile.cs and added a public variable called neutral
Then added this line to MoveEditorWindow.cs to be able to toggle it

moveInfo.projectiles[i].neutral = EditorGUILayout.Toggle("Effects Both Players", moveInfo.projectiles[i].neutral);

The penultimate step was spawning said hitboxes in MatchManager.cs by stealing the code from ControlScript.cs and spawning them in the Start and NewRound functions

        void SpawnHitBoxes()
        {
            int projCount = 0;
            foreach (MoveInfo hitbox in UFE.config.selectedStage.hitBoxes)
                foreach (Projectile projectile in hitbox.projectiles)
                {
                    projCount++;

                    projectile.casted = true;

                    FPVector newPos = FPVector.zero;
                    newPos += UFE.config.selectedStage.position;

                    string uniqueId;
                    GameObject pTemp;
                    if (projectile.fixedZAxis) newPos.z = 0;

                    if (projectile._duration > 0)
                    {
                        long durationFrames = (int)FPMath.Round(projectile._duration * UFE.config.fps);

                        uniqueId = projectile.projectilePrefab.name + UFE.currentFrame + projCount;
                        pTemp = UFE.SpawnGameObject(projectile.projectilePrefab, newPos.ToVector(), Quaternion.identity, durationFrames, true, uniqueId);
                    }
                    else
                    {
                        uniqueId = projectile.projectilePrefab.name + UFE.currentFrame + projCount;
                        pTemp = UFE.SpawnGameObject(projectile.projectilePrefab, newPos.ToVector(), Quaternion.identity, null, true, uniqueId);
                    }

                    Vector3 newRotation = projectile.projectilePrefab.transform.rotation.eulerAngles;
                    newRotation.z = projectile.directionAngle;
                    pTemp.transform.rotation = Quaternion.Euler(newRotation);

                    ProjectileMoveScript projectileMoveScript = (ProjectileMoveScript)pTemp.GetComponent(typeof(ProjectileMoveScript));
                    if (projectileMoveScript == null)
                    {
                        projectileMoveScript = pTemp.AddComponent<ProjectileMoveScript>();
                        projectileMoveScript.fpTransform = pTemp.AddComponent<FPTransform>();
                    }

                    projectileMoveScript.fpTransform.position = newPos + new FPVector(projectile._castingOffSet.x, projectile._castingOffSet.y, projectile._castingOffSet.z);
                    projectileMoveScript.data = projectile;
                    projectileMoveScript.data.uniqueId = hitbox.id;
                    projectileMoveScript.myControlsScript = UFE.GetControlsScript(1);
                    projectileMoveScript.transform.position = newPos.ToVector();

                    foreach (ControlsScript controls in UFE.GetAllControlsScripts())
                        controls.projectiles.Add(projectileMoveScript);
                    projectileMoveScript.UFEStart();
                }
        }

Finally in the fixed update function of ProjectileMoveScript.cs I simply copy and pasted the collision check so that if the projectile is neutral it also checks myControlscript for projectiles

            if (data.neutral)
            {
                blockableAreaIntersect = myControlsScript.CheckBlockableAreaContact(blockableArea, mirror > 0);
                if (data.projectileCollision) IsCollidingProjectile(myControlsScript);
                IsCollidingCharacter(myControlsScript);
                foreach (ControlsScript opAssist in myControlsScript.assists)
                {
                    if (data.projectileCollision) IsCollidingProjectile(opAssist);
                    IsCollidingCharacter(opAssist);
                }
            }

Edit: double checked my steps forgot to mention that in the UFEStart function of ProjectileMoveScript.cs I changed the call so that neutral projectiles weren't added to myControlScript.projectiles since I already added it in the MatchManager.

            if (!data.neutral && !myControlsScript.projectiles.Contains(this))
                myControlsScript.projectiles.Add(this);

Also wanted to say I did not optimize this so there is likely better ways of doing this so feel free to make improvements

Share

Thumbs up +1 Thumbs down

Re: Is there a way to spawn a permanent hitbox with the stage?

Very interesting. There is a more complex implementation of this on UFE 3 (available for Patreon Tier 4 members). It has many features like that, including the ability to create platforms and a variety of stage interactables.
I'm currently focused on improving UFE 2 (working on version 2.7), but I plan to continue working on UFE 3 and hopefully release it to the general public sometime in the near future.

Like UFE? Please rate and review us on the Asset Store!
Questions about the Forum? Check out our Karma FAQ.
Don't forget to check our discord channel.