Club PA 2.0 has arrived! If you'd like to access some extra PA content and help support the forums, check it out at patreon.com/ClubPA
The image size limit has been raised to 1mb! Anything larger than that should be linked to. This is a HARD limit, please do not abuse it.
Our new Indie Games subforum is now open for business in G&T. Go and check it out, you might land a code for a free game. If you're developing an indie game and want to post about it, follow these directions. If you don't, he'll break your legs! Hahaha! Seriously though.
Our rules have been updated and given their own forum. Go and look at them! They are nice, and there may be new ones that you didn't know about! Hooray for rules! Hooray for The System! Hooray for Conforming!

[Game Dev] I don't have a publisher. What I do have are a very particular set of skills.

1464749515256

Posts

  • LilnoobsLilnoobs Alpha Queue Registered User regular
    It's a damn steal. The fantasy creature package itself retails for $350 alone.

  • ZibblsnrtZibblsnrt Registered User regular
    I'm helloworlding around with things again, given I remembered I had the discount on that GMS1.4->2.0 upgrade about six hours before it expired so hell why not.

    Rather enjoying the new setup compared to 1.4.

    Now to actually figure out a project to try in it...

  • rembrandtqeinsteinrembrandtqeinstein Registered User regular
    Zibblsnrt wrote: »
    I'm helloworlding around with things again, given I remembered I had the discount on that GMS1.4->2.0 upgrade about six hours before it expired so hell why not.

    Rather enjoying the new setup compared to 1.4.

    Now to actually figure out a project to try in it...

    The first project is always Asteroids

    DisruptedCapitalist
  • KashaarKashaar Low OrbitRegistered User regular
    Zibblsnrt wrote: »
    I'm helloworlding around with things again, given I remembered I had the discount on that GMS1.4->2.0 upgrade about six hours before it expired so hell why not.

    Rather enjoying the new setup compared to 1.4.

    Now to actually figure out a project to try in it...

    The first project is always Asteroids

    Breakout for me ;)

    kashaar.pngDev Blog | Twitter | Tumblr | Steam
    Unreal Engine 4 Developers Community.

    I'm working on a cute little video game! Here's a link for you.
    KoopahTroopahDac VinrembrandtqeinsteinMadpoet
  • KoopahTroopahKoopahTroopah The koopas, the troopas. Philadelphia, PARegistered User regular
    I converted PA's Thornwatch into a Tabletop Simulator module. It took a good amount of time, but I felt like I had a purpose with a hobby project like that instead of wasting all my free time on Blizzard games. After work yesterday, all I wanted to do was keep adding to the Thornwatch game. I still have piles of games to play, God of War, Spiderman, We Happy Few just came out and I wanted to play that... but I just really felt motivated to work more on the module. Granted I didn't, and I ended up playing SC2 with a friend instead, but still even today I wanna go home and keep working on the Dark of the Wood expansion to release with the base game.

    I've decided I'm going to seriously begin work on my previously thunked about Puzzle Collection game including two modes of similar styles of Puzzle Fighter and Tetris Attack with a cookie baking theme instead of tetrominos starting Sunday. It would be a bit of a ways off, but does anyone here have a good portfolio with Pixel Art? I'd like to do a 60/40 type partnership, I would front the $100 Steam fee to get it on the store and would release it under a company name of my own, but I'd obviously give credit to the artist as well as 40% of the profit from the game. I say 60/40, because I would be doing the programming, sound/music, updates & bug fixes, etc... The only thing I would really like help on is the art.

    ?username=KoopahTroopah&theme=light

    Steam - Battle.net - Koopah089 - PSN/Xbox - 1639-6388-9968/KoopahTroopah - Switch
    ElvenshaeKashaarCornucopiistDisruptedCapitalistIanatordipuc4life
  • HeartlashHeartlash Registered User regular
    Started a design doc on a new project yesterday. I'm excited about it. Thinking a Lovecraftian hero/tower defense hybrid.

    My indie mobile gaming studio: Elder Aeons
    Our first game is now available for free on Google Play: Frontier: Isle of the Seven Gods
    ElvenshaeKoopahTroopahKashaarCornucopiistRoyceSraphim
  • ElaroElaro Bleeding MonumentRegistered User regular
    So for my computer graphics class, the first piece of homework is to make a game. A shmup, specifically. A 3D shmup.

    Not entirely from scratch, mind you, but still.

    Oct1o4x.png
    Derp derp I'm a smurf
    KashaarElvenshaeIanator
  • KashaarKashaar Low OrbitRegistered User regular
    Elaro wrote: »
    So for my computer graphics class, the first piece of homework is to make a game. A shmup, specifically. A 3D shmup.

    Not entirely from scratch, mind you, but still.

    Noice! Use the UE4 twin stick shooter template and code yourself some enemies? ;)

    kashaar.pngDev Blog | Twitter | Tumblr | Steam
    Unreal Engine 4 Developers Community.

    I'm working on a cute little video game! Here's a link for you.
    DisruptedCapitalistRoyceSraphim
  • rembrandtqeinsteinrembrandtqeinstein Registered User regular
    Ive been cracking at my current hover-cart-racer-in-a-tunnel game for while and im stuck on one part. I have gravity working so no matter where you are in the tunnel the gravity force is coming from the relative center. My problem now is how to always keep the top of the car oriented towards the tunnel center while still allowing free turning on the y axis?

    Not knowing much more about quaternions than they exist and are used for this kind of thing isn't helping.

    What I need is something like Transform.LookAt but for the Y axis of the transform rather than the Z axis. I know I can potentially use a parent wrapper but I would really like to avoid that since moving down a twisting tunnel at an arbitrary angle will be complicated enough as it is.

    The basic idea is the tunnel consist of a series of torus sections that are connected at the ends and have the same radius. Gravity coming from the diameter of the torus-defining circle will push the car towards the outer wall of the tunnel. My solution to rotation will keep the car oriented relative to the surface normal of the tunnel regardless of how the player turns or what other things happen while the car is moving, and then force relative to the transform forward will move the car down the tunnel.

    Next level of difficulty, I can't raycast into the tunnel floor to find the normal because the collider isn't convex since we are INSIDE of a donut (section). But that isn't the issue, I can use the gravity direction which won't exactly be a surface normal but close enough for what I want.

    I'm running out of ideas so I'm going to try brute force algorithming where I try every property of transforms, vectors, and quaternions until I can get a least get closer to what I want to do.

  • KashaarKashaar Low OrbitRegistered User regular
    Ive been cracking at my current hover-cart-racer-in-a-tunnel game for while and im stuck on one part. I have gravity working so no matter where you are in the tunnel the gravity force is coming from the relative center. My problem now is how to always keep the top of the car oriented towards the tunnel center while still allowing free turning on the y axis?

    Not knowing much more about quaternions than they exist and are used for this kind of thing isn't helping.

    What I need is something like Transform.LookAt but for the Y axis of the transform rather than the Z axis. I know I can potentially use a parent wrapper but I would really like to avoid that since moving down a twisting tunnel at an arbitrary angle will be complicated enough as it is.

    The basic idea is the tunnel consist of a series of torus sections that are connected at the ends and have the same radius. Gravity coming from the diameter of the torus-defining circle will push the car towards the outer wall of the tunnel. My solution to rotation will keep the car oriented relative to the surface normal of the tunnel regardless of how the player turns or what other things happen while the car is moving, and then force relative to the transform forward will move the car down the tunnel.

    Next level of difficulty, I can't raycast into the tunnel floor to find the normal because the collider isn't convex since we are INSIDE of a donut (section). But that isn't the issue, I can use the gravity direction which won't exactly be a surface normal but close enough for what I want.

    I'm running out of ideas so I'm going to try brute force algorithming where I try every property of transforms, vectors, and quaternions until I can get a least get closer to what I want to do.

    That sounds like it can be solved with some trig though? Is this a wholly custom thing, or are you using an existing engine?

    kashaar.pngDev Blog | Twitter | Tumblr | Steam
    Unreal Engine 4 Developers Community.

    I'm working on a cute little video game! Here's a link for you.
  • rembrandtqeinsteinrembrandtqeinstein Registered User regular
    Kashaar wrote: »
    Ive been cracking at my current hover-cart-racer-in-a-tunnel game for while and im stuck on one part. I have gravity working so no matter where you are in the tunnel the gravity force is coming from the relative center. My problem now is how to always keep the top of the car oriented towards the tunnel center while still allowing free turning on the y axis?

    Not knowing much more about quaternions than they exist and are used for this kind of thing isn't helping.

    What I need is something like Transform.LookAt but for the Y axis of the transform rather than the Z axis. I know I can potentially use a parent wrapper but I would really like to avoid that since moving down a twisting tunnel at an arbitrary angle will be complicated enough as it is.

    The basic idea is the tunnel consist of a series of torus sections that are connected at the ends and have the same radius. Gravity coming from the diameter of the torus-defining circle will push the car towards the outer wall of the tunnel. My solution to rotation will keep the car oriented relative to the surface normal of the tunnel regardless of how the player turns or what other things happen while the car is moving, and then force relative to the transform forward will move the car down the tunnel.

    Next level of difficulty, I can't raycast into the tunnel floor to find the normal because the collider isn't convex since we are INSIDE of a donut (section). But that isn't the issue, I can use the gravity direction which won't exactly be a surface normal but close enough for what I want.

    I'm running out of ideas so I'm going to try brute force algorithming where I try every property of transforms, vectors, and quaternions until I can get a least get closer to what I want to do.

    That sounds like it can be solved with some trig though? Is this a wholly custom thing, or are you using an existing engine?

    I think I'm overthinking it a lot and that post was less a cry for help (not that help wouldnt be appreciated) and more rubber duckie programming where I try to explain the problem to "someone else" as best as I can.

    After writing out that post and looking through the Vector3 methods I found this one: https://docs.unity3d.com/ScriptReference/Vector3.RotateTowards.html I think I take the current transform.up, and apply against negative gravity vector and that will keep the car oriented toward the tunnel section center.

    KashaarCalicaDisruptedCapitalistKoopahTroopah
  • KashaarKashaar Low OrbitRegistered User regular
    Glad to be of rubbery service ;)

    kashaar.pngDev Blog | Twitter | Tumblr | Steam
    Unreal Engine 4 Developers Community.

    I'm working on a cute little video game! Here's a link for you.
    KoopahTroopah
  • GarthorGarthor Registered User regular
    edited September 2018
    You're overthinking this a bit. Vector3.RotateTowards is useful (you'll probably end up using it) but the way you get your car to freely rotate around an arbitrary fixed axis is by using the Quaternion.LookRotation function. Specifically, the second argument, which specifies where the up vector should point, which in your case will always just be -gravity. The reference entry for Vector3.RotateTowards actually provides an example of how you use Quaternion.LookRotation though it's not using the up vector argument.

    For all the other problems that are going to fall out of solving this one, you might want to brush up on your vector math, because you're going to be doing a good bunch of it.

    Garthor on
    rembrandtqeinstein
  • RendRend Registered User regular
    Rend's Periodic Game Dev Updates
    As of mid last week, the actions all my board pieces can take are now fully imported via xml! Now only generic functionality blocks of the various actions you can take in battle are in code, and those are assembled via xml into collections of targets, values, and functions.

    -Values, which are new as of this framework, represent the values used in moves. For instance, the deal damage command needs a minimum and maximum damage value, an attack and defense attribute value, etc. Values can be provided raw or from a prior value, by drawing from an actor's attributes or equipment, or by doing arithmetic on a prior value (for a move which has a damage multiplier, for instance).

    This has proven to be immediately extremely valuable. In the time it took me to implement a single one of my basic actions prior to completing this framework, I was able to implement several advanced actions from my first character class. Obviously the comparison isn't apples to apples- when implementing the basic attack move, I first needed to create the universe, but still. I find that only minor new functionality, if any at all, is necessary for many of the battle actions I have planned.

    This morning I implemented flags which restrict targeting to spaces on the board which are either FURTHER FROM or CLOSER TO a given epicenter than the current location- basically, knockback and pull effects. That was actually pretty fun, I like when I deal with grid coordinates, and the solution felt very tactile to me.
    Let epicenter be the location you are pulling toward or pushing from.
    Let current be your current location.
    Let target be the space you're targeting.

    First, find out whether epicenter is north of current, is south of current, is east of current, and is west of current.
    Note that being north of current and south of current are mutually exclusive, but it does not need to be one or the other. If epicenter is DIRECTLY east, it will be neither north nor south of current.

    Find the same four flags for target: north of current, south of current, etc.

    If limiting to spaces which push away from the epicenter, then return true if:
    -No flag which is true for epicenter is ALSO true for target
    -At least one flag which is true for epicenter is true for target's opposite (EG: epicenter is north of current, target is south of current)

    Respectively, if limiting to spaces which draw toward the epicenter, then return true if:
    -No flag which is true for epicenter is true for target's opposite (EG: epicenter is north of current, target is south of current)
    -At least one flag which is true for epicenter is ALSO true for target

    I had a lot of fun with it this morning.

    In addition, I did some work adding more flavor and UI elements to stuff. I added description fields and implemented a lot of different tooltips over the last couple of weeks as well.
    All in all things continue to go at a good clip!

    Kupidipuc4lifeDisruptedCapitalist
  • templewulftemplewulf The Team Chump USARegistered User regular
    Rend wrote: »
    Rend's Periodic Game Dev Updates
    As of mid last week, the actions all my board pieces can take are now fully imported via xml! Now only generic functionality blocks of the various actions you can take in battle are in code, and those are assembled via xml into collections of targets, values, and functions.

    -Values, which are new as of this framework, represent the values used in moves. For instance, the deal damage command needs a minimum and maximum damage value, an attack and defense attribute value, etc. Values can be provided raw or from a prior value, by drawing from an actor's attributes or equipment, or by doing arithmetic on a prior value (for a move which has a damage multiplier, for instance).

    This has proven to be immediately extremely valuable. In the time it took me to implement a single one of my basic actions prior to completing this framework, I was able to implement several advanced actions from my first character class. Obviously the comparison isn't apples to apples- when implementing the basic attack move, I first needed to create the universe, but still. I find that only minor new functionality, if any at all, is necessary for many of the battle actions I have planned.

    This morning I implemented flags which restrict targeting to spaces on the board which are either FURTHER FROM or CLOSER TO a given epicenter than the current location- basically, knockback and pull effects. That was actually pretty fun, I like when I deal with grid coordinates, and the solution felt very tactile to me.
    Let epicenter be the location you are pulling toward or pushing from.
    Let current be your current location.
    Let target be the space you're targeting.

    First, find out whether epicenter is north of current, is south of current, is east of current, and is west of current.
    Note that being north of current and south of current are mutually exclusive, but it does not need to be one or the other. If epicenter is DIRECTLY east, it will be neither north nor south of current.

    Find the same four flags for target: north of current, south of current, etc.

    If limiting to spaces which push away from the epicenter, then return true if:
    -No flag which is true for epicenter is ALSO true for target
    -At least one flag which is true for epicenter is true for target's opposite (EG: epicenter is north of current, target is south of current)

    Respectively, if limiting to spaces which draw toward the epicenter, then return true if:
    -No flag which is true for epicenter is true for target's opposite (EG: epicenter is north of current, target is south of current)
    -At least one flag which is true for epicenter is ALSO true for target

    I had a lot of fun with it this morning.

    In addition, I did some work adding more flavor and UI elements to stuff. I added description fields and implemented a lot of different tooltips over the last couple of weeks as well.
    All in all things continue to go at a good clip!

    That's awesome! I was considering working on a TRPG way, way down the line.

    Would you be willing to post one of your new XML files here? I'm curious how you've structured everything

    Twitch.tv/FiercePunchStudios | PSN | Steam | Discord | SFV CFN: templewulf
  • RendRend Registered User regular
    Sure! but only if you agree to forgive my abysmal naming conventions and capitalization. One of the next few tasks I've got on the roadmap is a tool to edit the entire collection of battle actions and auto-generate those files (and along with that tool is a bunch of refactor and renaming work to make everything cohesive) So until then it hurts a little to read

  • LD50LD50 Registered User regular
    XML is never human readable.

    bowenSaerisGSMMvrckGlal
  • rembrandtqeinsteinrembrandtqeinstein Registered User regular
    Garthor wrote: »
    You're overthinking this a bit. Vector3.RotateTowards is useful (you'll probably end up using it) but the way you get your car to freely rotate around an arbitrary fixed axis is by using the Quaternion.LookRotation function. Specifically, the second argument, which specifies where the up vector should point, which in your case will always just be -gravity. The reference entry for Vector3.RotateTowards actually provides an example of how you use Quaternion.LookRotation though it's not using the up vector argument.

    For all the other problems that are going to fall out of solving this one, you might want to brush up on your vector math, because you're going to be doing a good bunch of it.

    It looks like rotatetowards isn't going to do it, it seems to always move towards a fixed y rotation when I want the car to turn freely on the y axis but the x and z axis rotation should always move back towards the gravity normal plane

    I think this project might be outside of my skillset since I never learned any 3d math and with RL responsibilities I don't feel like I can dedicate myself to learning it

    Which is sad because just manually moving my car down the tunnel looks pretty cool in scene view. But I don't want to make another "endless runner" style game, I already did one and it is fine but I wanted a full control racing experience.

  • HandkorHandkor Registered User regular
    This is a big milestone for me, I'm putting in a settings menu to change screen resolution and other settings. That's a big sign of getting close to a shipping build.

    KoopahTroopahKashaar
  • KhavallKhavall British ColumbiaRegistered User regular
    edited September 2018
    Garthor wrote: »
    You're overthinking this a bit. Vector3.RotateTowards is useful (you'll probably end up using it) but the way you get your car to freely rotate around an arbitrary fixed axis is by using the Quaternion.LookRotation function. Specifically, the second argument, which specifies where the up vector should point, which in your case will always just be -gravity. The reference entry for Vector3.RotateTowards actually provides an example of how you use Quaternion.LookRotation though it's not using the up vector argument.

    For all the other problems that are going to fall out of solving this one, you might want to brush up on your vector math, because you're going to be doing a good bunch of it.

    It looks like rotatetowards isn't going to do it, it seems to always move towards a fixed y rotation when I want the car to turn freely on the y axis but the x and z axis rotation should always move back towards the gravity normal plane

    I think this project might be outside of my skillset since I never learned any 3d math and with RL responsibilities I don't feel like I can dedicate myself to learning it

    Which is sad because just manually moving my car down the tunnel looks pretty cool in scene view. But I don't want to make another "endless runner" style game, I already did one and it is fine but I wanted a full control racing experience.

    There's an easy bad version to do this.
    void Update() //or whatever you're using to call the rotation
    {
      var allRotate = Vector3.RotateTowards(foo) // where foo is whatever you've been rotating towards
      var oldRotate = transform.eulerAngles(); //This gets the current rotation of the object
      var newRotate = new Vector3(oldRotate.x, oldRotate.y, allRotate.z); //This makes a new Vector3 with the old x and y values and the new z value
      transform.eulerAngles = newRotate; //And this sets the new rotation to this rotation.
    }
    

    That in theory should let the z axis rotate towards the thing, and the x and y axis be free. I think, it's been a few months since I've done anything meaningful about positions in Unity. Also I remember doing too much Euler stuff can sometimes fuck shit up

    Khavall on
    rembrandtqeinstein
  • rembrandtqeinsteinrembrandtqeinstein Registered User regular
    Khavall wrote: »
    Garthor wrote: »
    You're overthinking this a bit. Vector3.RotateTowards is useful (you'll probably end up using it) but the way you get your car to freely rotate around an arbitrary fixed axis is by using the Quaternion.LookRotation function. Specifically, the second argument, which specifies where the up vector should point, which in your case will always just be -gravity. The reference entry for Vector3.RotateTowards actually provides an example of how you use Quaternion.LookRotation though it's not using the up vector argument.

    For all the other problems that are going to fall out of solving this one, you might want to brush up on your vector math, because you're going to be doing a good bunch of it.

    It looks like rotatetowards isn't going to do it, it seems to always move towards a fixed y rotation when I want the car to turn freely on the y axis but the x and z axis rotation should always move back towards the gravity normal plane

    I think this project might be outside of my skillset since I never learned any 3d math and with RL responsibilities I don't feel like I can dedicate myself to learning it

    Which is sad because just manually moving my car down the tunnel looks pretty cool in scene view. But I don't want to make another "endless runner" style game, I already did one and it is fine but I wanted a full control racing experience.

    There's an easy bad version to do this.
    void Update() //or whatever you're using to call the rotation
    {
      var allRotate = Vector3.RotateTowards(foo) // where foo is whatever you've been rotating towards
      var oldRotate = transform.eulerAngles(); //This gets the current rotation of the object
      var newRotate = new Vector3(oldRotate.x, oldRotate.y, allRotate.z); //This makes a new Vector3 with the old x and y values and the new z value
      transform.eulerAngles = newRotate; //And this sets the new rotation to this rotation.
    }
    

    That in theory should let the z axis rotate towards the thing, and the x and y axis be free. I think, it's been a few months since I've done anything meaningful about positions in Unity. Also I remember doing too much Euler stuff can sometimes fuck shit up

    I'll give it a try, one more crack doesnt hurt before giving up and remaking Yar's Revenge....

  • HandkorHandkor Registered User regular
    edited September 2018
    Khavall wrote: »
    Garthor wrote: »
    You're overthinking this a bit. Vector3.RotateTowards is useful (you'll probably end up using it) but the way you get your car to freely rotate around an arbitrary fixed axis is by using the Quaternion.LookRotation function. Specifically, the second argument, which specifies where the up vector should point, which in your case will always just be -gravity. The reference entry for Vector3.RotateTowards actually provides an example of how you use Quaternion.LookRotation though it's not using the up vector argument.

    For all the other problems that are going to fall out of solving this one, you might want to brush up on your vector math, because you're going to be doing a good bunch of it.

    It looks like rotatetowards isn't going to do it, it seems to always move towards a fixed y rotation when I want the car to turn freely on the y axis but the x and z axis rotation should always move back towards the gravity normal plane

    I think this project might be outside of my skillset since I never learned any 3d math and with RL responsibilities I don't feel like I can dedicate myself to learning it

    Which is sad because just manually moving my car down the tunnel looks pretty cool in scene view. But I don't want to make another "endless runner" style game, I already did one and it is fine but I wanted a full control racing experience.

    There's an easy bad version to do this.
    void Update() //or whatever you're using to call the rotation
    {
      var allRotate = Vector3.RotateTowards(foo) // where foo is whatever you've been rotating towards
      var oldRotate = transform.eulerAngles(); //This gets the current rotation of the object
      var newRotate = new Vector3(oldRotate.x, oldRotate.y, allRotate.z); //This makes a new Vector3 with the old x and y values and the new z value
      transform.eulerAngles = newRotate; //And this sets the new rotation to this rotation.
    }
    

    That in theory should let the z axis rotate towards the thing, and the x and y axis be free. I think, it's been a few months since I've done anything meaningful about positions in Unity. Also I remember doing too much Euler stuff can sometimes fuck shit up

    I'll give it a try, one more crack doesnt hurt before giving up and remaking Yar's Revenge....

    Don't give up, I love Yar's Revenge, especially the audio it is very atmospheric and immersive.

    Handkor on
  • rembrandtqeinsteinrembrandtqeinstein Registered User regular
    Handkor wrote: »

    Don't give up, I love Yar's Revenge, especially the audio it is very atmospheric and immersive.

    Yar's is my fallback if tunnelcart doesn't get off the grond

  • GarthorGarthor Registered User regular
    edited September 2018
    Okay, I think this is the simplest way to do what you're looking for, full script, C#:
    using UnityEngine;
    
    [ExecuteInEditMode]
    public class orientCar : MonoBehaviour {
        // Update is called when something in the scene changes
        void Update () {
            // Rotate the car to point its Y axis towards the ray (0,0,1) through (0,0,0)
            // First get the target up vector, which is just the inverse of the position with the Z component zeroed out
            Vector3 newUp = new Vector3(-transform.position.x, -transform.position.y, 0);
    
            // Now, construct a rotation that will take us from our current orientation to our desired one
            Quaternion rot = new Quaternion();
            rot.SetFromToRotation(transform.up, newUp);
    
            // Apply the rotation.  Note that quaternion multiplication is not commutative, it must be done in this order
            transform.rotation = rot * transform.rotation;
        }
    }
    

    This executes in the editor so you can just slap it on something and see it working. It isn't 100% perfect (and it kind of fights the editor for control over the object... don't worry about it) but it should be a passable basis for what you're doing. Also I think you mentioned you wanted the Z axis fixed not the Y axis but I already made my little capsule car so that ship has sailed.

    Garthor on
  • LilnoobsLilnoobs Alpha Queue Registered User regular
    Well, I recently playtested a prototype at an event and the feedback was promising. Here goes revamping the game from the ground up.

    Elvenshae
  • RendRend Registered User regular
    @templewulf
    Here you go! Again please excuse the awfulness of my consistency.
    <?xml version="1.0" encoding="utf-8" ?>
    <BattleActionCollection xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <BattleActions>
            <BattleAction>
                <name>Advancing Strike</name>
                <fighterClass>Soldier</fighterClass>
                <isStandardAction>true</isStandardAction> <!-- True if this should eat the standard action slot, as opposed to the move slot. -->
                <tooltip>Move one space and then attack with your weapon</tooltip>
    
                <TargetRequests>
                    <TargetRequest>
                        <targetLabel>destination</targetLabel>          <!-- Used as a dictionary key -->
                        <canTargetGround>true</canTargetGround>         <!-- True if a blank space is valid target -->
                        <canTargetAllies>false</canTargetAllies>        <!-- True if allies are valid target -->
                        <canTargetEnemies>false</canTargetEnemies>      <!-- True if enemies are valid target -->
                        <canTargetSelf>false</canTargetSelf>            <!-- True if the user is valid target -->
                        <canTargetOrigin>false</canTargetOrigin>        <!-- True if the space this target originates from is valid target -->
    
                        <usaActorWeaponRange>false</usaActorWeaponRange> <!-- True if the range of this target depends on actor weapon -->
                        <useActorStatRange>false</useActorStatRange>    <!-- True if the range of this target depends on actor attribute (move speed, etc) -->
                        <range>1</range>                                <!-- Default range -->
                        <minimumRange>1</minimumRange>                  <!-- Default minimum range -->
                        <isRangeWalkable>true</isRangeWalkable>         <!-- True if this target should use pathfinding for range testing, false for line of sight -->
                        <targetOriginLabel></targetOriginLabel>         <!-- Label of the target request this target originates from -->
                    </TargetRequest>
    
                    <TargetRequest>
                        <targetLabel>target</targetLabel>
                        <canTargetGround>false</canTargetGround>
                        <canTargetAllies>true</canTargetAllies>
                        <canTargetEnemies>true</canTargetEnemies>
                        <canTargetSelf>false</canTargetSelf>
                        <canTargetOrigin>false</canTargetOrigin>
    
                        <useActorWeaponRange>true</useActorWeaponRange>
                        <useActorStatRange>false</useActorStatRange>
                        <range>0</range>
                        <minimumRange>0</minimumRange>
    
                        <targetOriginLabel>destination</targetOriginLabel>
                    </TargetRequest>
                </TargetRequests>
    
                <!-- 2 providers are added to the collection prior to any processing -->
                <!--   -A target provider which returns the actor, ie: the piece using this action -->
                <!--   -A value provider which returns whether or not the actor's current tension is above a given threshold -->
    
                <ValuesBeforeTargeting>                                 <!-- Values which can or should be calculated prior to targeting -->
                    <Value xsi:type="EquipmentValueProvider">
                        <Name>MinDamage</Name>
                        <targetName>actor</targetName>
                        <equipmentType>MainHand</equipmentType>
                        <valueType>MinDamage</valueType>
                    </Value>
                    <Value xsi:type="EquipmentValueProvider">
                        <Name>MaxDamage</Name>
                        <targetName>actor</targetName>
                        <equipmentType>MainHand</equipmentType>
                        <valueType>MaxDamage</valueType>
                    </Value>
    
                    <Value xsi:type="EquipmentValueProvider">
                        <Name>TensionFactor</Name>
                        <targetName>actor</targetName>
                        <equipmentType>MainHand</equipmentType>
                        <valueType>TensionFactor</valueType>
                    </Value>
    
                    <Value xsi:type="ArithmeticValueProvider">
                        <Name>MinDamage</Name>
                        <InitialValue>%MinDamage</InitialValue>                 <!-- % indicates this value should be provided from the dictionary -->
                        <IsInt>true</IsInt>                                     <!-- True if floats should be truncated to ints -->
                        <Conditions>                                            <!-- Checks value dictionary for each key, only processes if all are 'true' -->
                            <Condition>overThreshold</Condition>                <!-- This Arithmetic will only process if the actor's tension is over the threshold -->
                        </Conditions>
                        <Expressions>
                            <Expression>Multiply %TensionFactor</Expression>
                        </Expressions>
                    </Value>
                    <Value xsi:type="ArithmeticValueProvider">
                        <Name>MaxDamage</Name>
                        <InitialValue>%MaxDamage</InitialValue>
                        <IsInt>true</IsInt>
                        <Conditions>
                            <Condition>overThreshold</Condition>
                        </Conditions>
                        <Expressions>
                            <Expression>Multiply %TensionFactor</Expression>
                        </Expressions>
                    </Value>
    
    
                    <Value xsi:type="EquipmentValueProvider">
                        <Name>AttackAttribute</Name>
                        <targetName>actor</targetName>
                        <equipmentType>MainHand</equipmentType>
                        <valueType>AttackAttribute</valueType>          <!-- The attribute the actor will use to deal damage -->
                    </Value>
                    <Value xsi:type="EquipmentValueProvider">
                        <Name>DefenseAttribute</Name>
                        <targetName>actor</targetName>
                        <equipmentType>MainHand</equipmentType>
                        <valueType>DefenseAttribute</valueType>         <!-- The attribute the target will use to mitigate damage -->
                    </Value>
                    <Value xsi:type="EquipmentValueProvider">
                        <Name>WeaponAccuracy</Name>
                        <targetName>actor</targetName>
                        <equipmentType>MainHand</equipmentType>
                        <valueType>Accuracy</valueType>
                    </Value>
                </ValuesBeforeTargeting>
    
                <ValuesAfterTargeting>
                    <Value xsi:type="RollToHitValueProvider">           <!-- Special single purpose value provider which will account for -->
                        <Name>toHit</Name>                              <!--   all accuracy related contingencies. -->
                        <ActorName>actor</ActorName>
                        <TargetName>target</TargetName>
                        <AccuracyModifier>%WeaponAccuracy</AccuracyModifier>
                    </Value>
                </ValuesAfterTargeting>
    
                <CutsceneCommands>
    
                    <CutsceneCommand xsi:type="CenterCameraBetweenCutsceneLoader">      <!-- Centers camera between two targets -->
                        <TargetingMethod>TargetProvider</TargetingMethod>
                        <FirstTargetName>actor</FirstTargetName>
                        <SecondTargetName>destination</SecondTargetName>
                        <Time>0.5</Time>
                    </CutsceneCommand>
    
                    <CutsceneCommand xsi:type="CutsceneWaitLoader">
                        <Time>0.25</Time>
                    </CutsceneCommand>
    
                    <CutsceneCommand xsi:type="MoveBoardPieceCutsceneLoader">           <!-- Moves a piece on the board logically -->
                        <TargetingMethod>TargetProvider</TargetingMethod>
                        <ActorName>actor</ActorName>
                        <DestinationProviderName>destination</DestinationProviderName>
                    </CutsceneCommand>
    
                    <CutsceneCommand xsi:type="MoveAlongPathCutsceneLoader">            <!-- Animates a piece moving in world space -->
                        <TargetingMethod>TargetProvider</TargetingMethod>
                        <ActorName>actor</ActorName>
                        <DestinationProviderName>destination</DestinationProviderName>
                    </CutsceneCommand>
    
                    <CutsceneCommand xsi:type="CenterCameraBetweenCutsceneLoader">
                        <TargetingMethod>TargetProvider</TargetingMethod>
                        <FirstTargetName>actor</FirstTargetName>
                        <SecondTargetName>target</SecondTargetName>
                        <Time>0.5</Time>
                    </CutsceneCommand>
    
                    <CutsceneCommand xsi:type="CutsceneWaitLoader">
                        <Time>0.25</Time>
                    </CutsceneCommand>
    
                    <CutsceneCommand xsi:type="DealDamageCutsceneLoader">               <!-- Actually deals the damage -->
                        <Conditions>
                            <Condition>toHit</Condition>                                <!-- Only process if this move hit -->
                        </Conditions>
                        <TargetingMethod>TargetProvider</TargetingMethod>               <!-- For other cutscenes, such as pre-programmed ones, -->
                        <ActorName>actor</ActorName>                                    <!--  the targeting method might use a unit's name etc. -->
                        <TargetName>target</TargetName>
                        <MinDamage>%MinDamage</MinDamage>
                        <MaxDamage>%MaxDamage</MaxDamage>
                        <AttackAttribute>%AttackAttribute</AttackAttribute>
                        <DefenseAttribute>%DefenseAttribute</DefenseAttribute>
                        <IgnoreArmor>false</IgnoreArmor>                                <!-- True if armor should not mitigate this damage -->
                        <IgnoreStats>false</IgnoreStats>                                <!-- True if attributes should not mitigate this damage -->
                        <ShowFloatingText>true</ShowFloatingText>                       <!-- True if floating text should display the damage dealt -->
                        <WaitForFloatingText>true</WaitForFloatingText>                 <!-- True if the cutscene should wait for the floating text to fade -->
                        <FloatingTextTime>2</FloatingTextTime>
                    </CutsceneCommand>
    
                    <CutsceneCommand xsi:type="CutsceneWaitLoader">
                        <Time>0.25</Time>
                    </CutsceneCommand>
    
                    <CutsceneCommand xsi:type="MoveCameraCutsceneLoader">
                        <TargetingMethod>TargetProvider</TargetingMethod>
                        <TargetName>actor</TargetName>
                        <Time>0.5</Time>
                    </CutsceneCommand>
    
                </CutsceneCommands>
    
            </BattleAction>
    
            <BattleAction>
                <name>Attack Rush</name>
                <fighterClass>Soldier</fighterClass>
                <isStandardAction>true</isStandardAction>
                <tooltip>Damage an opponent and knock them back one space</tooltip>
    
                <TargetRequests>
                    <TargetRequest>
                        <targetLabel>target</targetLabel>
                        <canTargetAllies>true</canTargetAllies>
                        <canTargetEnemies>true</canTargetEnemies>
                        <useActorWeaponRange>true</useActorWeaponRange>
                    </TargetRequest>
                    <TargetRequest>
                        <targetLabel>knockbackDestination</targetLabel>
                        <canTargetGround>true</canTargetGround>
                        <range>1</range>
                        <minimumRange>1</minimumRange>
                        <targetOriginLabel>target</targetOriginLabel>
                        <targetEpicenterLabel>actor</targetEpicenterLabel> <!-- Per my post earlier, epicenter is used for knockback and pull effects -->
                        <mustBeAwayFromEpicenter>true</mustBeAwayFromEpicenter> <!-- Only spaces which are further from actor than the target's current location are valid -->
                    </TargetRequest>
                </TargetRequests>
    
                <ValuesBeforeTargeting>
                    <Value xsi:type="EquipmentValueProvider">
                        <Name>MinDamage</Name>
                        <targetName>actor</targetName>
                        <equipmentType>MainHand</equipmentType>
                        <valueType>MinDamage</valueType>
                    </Value>
                    <Value xsi:type="EquipmentValueProvider">
                        <Name>MaxDamage</Name>
                        <targetName>actor</targetName>
                        <equipmentType>MainHand</equipmentType>
                        <valueType>MaxDamage</valueType>
                    </Value>
    
                    <Value xsi:type="EquipmentValueProvider">
                        <Name>TensionFactor</Name>
                        <targetName>actor</targetName>
                        <equipmentType>MainHand</equipmentType>
                        <valueType>TensionFactor</valueType>
                        <OnlyOverThreshold>true</OnlyOverThreshold>
                    </Value>
    
                    <Value xsi:type="ArithmeticValueProvider">
                        <Name>MinDamage</Name>
                        <InitialValue>%MinDamage</InitialValue>
                        <IsInt>true</IsInt>
                        <Conditions>
                            <Condition>overThreshold</Condition>
                        </Conditions>
                        <Expressions>
                            <Expression>Multiply %TensionFactor</Expression>
                        </Expressions>
                    </Value>
                    <Value xsi:type="ArithmeticValueProvider">
                        <Name>MaxDamage</Name>
                        <InitialValue>%MaxDamage</InitialValue>
                        <IsInt>true</IsInt>
                        <Conditions>
                            <Condition>overThreshold</Condition>
                        </Conditions>
                        <Expressions>
                            <Expression>Multiply %TensionFactor</Expression>
                        </Expressions>
                    </Value>
    
    
                    <Value xsi:type="EquipmentValueProvider">
                        <Name>AttackAttribute</Name>
                        <targetName>actor</targetName>
                        <equipmentType>MainHand</equipmentType>
                        <valueType>AttackAttribute</valueType>
                    </Value>
                    <Value xsi:type="EquipmentValueProvider">
                        <Name>DefenseAttribute</Name>
                        <targetName>actor</targetName>
                        <equipmentType>MainHand</equipmentType>
                        <valueType>DefenseAttribute</valueType>
                    </Value>
                    <Value xsi:type="EquipmentValueProvider">
                        <Name>WeaponAccuracy</Name>
                        <targetName>actor</targetName>
                        <equipmentType>MainHand</equipmentType>
                        <valueType>Accuracy</valueType>
                    </Value>
                </ValuesBeforeTargeting>
    
                <ValuesAfterTargeting>
                    <Value xsi:type="RollToHitValueProvider">
                        <Name>toHit</Name>
                        <ActorName>actor</ActorName>
                        <TargetName>target</TargetName>
                        <AccuracyModifier>%WeaponAccuracy</AccuracyModifier>
                    </Value>
                </ValuesAfterTargeting>
    
    
                <CutsceneCommands>
                    <CutsceneCommand xsi:type="CenterCameraBetweenCutsceneLoader">
                        <TargetingMethod>TargetProvider</TargetingMethod>
                        <FirstTargetName>actor</FirstTargetName>
                        <SecondTargetName>target</SecondTargetName>
                        <Time>0.5</Time>
                    </CutsceneCommand>
                    <CutsceneCommand xsi:type="CutsceneWaitLoader">
                        <Time>0.25</Time>
                    </CutsceneCommand>
                    <CutsceneCommand xsi:type="DealDamageCutsceneLoader">
                        <Conditions>
                            <Condition>toHit</Condition>
                        </Conditions>
                        <TargetingMethod>TargetProvider</TargetingMethod>
                        <ActorName>actor</ActorName>
                        <TargetName>target</TargetName>
                        <MinDamage>%MinDamage</MinDamage>
                        <MaxDamage>%MaxDamage</MaxDamage>
                        <AttackAttribute>%AttackAttribute</AttackAttribute>
                        <DefenseAttribute>%DefenseAttribute</DefenseAttribute>
                        <DealDamageAsTension>false</DealDamageAsTension>
                        <IgnoreArmor>false</IgnoreArmor>
                        <IgnoreStats>false</IgnoreStats>
                        <ShowFloatingText>true</ShowFloatingText>
                        <WaitForFloatingText>true</WaitForFloatingText>
                        <FloatingTextTime>2</FloatingTextTime>
                    </CutsceneCommand>
                    <CutsceneCommand xsi:type="MoveBoardPieceCutsceneLoader">
                        <Conditions>
                            <Condition>toHit</Condition>
                        </Conditions>
                        <TargetingMethod>TargetProvider</TargetingMethod>
                        <ActorName>target</ActorName>
                        <DestinationProviderName>knockbackDestination</DestinationProviderName>
                    </CutsceneCommand>
    
                    <CutsceneCommand xsi:type="MoveAlongPathCutsceneLoader">
                        <Conditions>
                            <Condition>toHit</Condition>
                        </Conditions>
                        <TargetingMethod>TargetProvider</TargetingMethod>
                        <ActorName>target</ActorName>
                        <DestinationProviderName>knockbackDestination</DestinationProviderName>
                    </CutsceneCommand>
                </CutsceneCommands>
                
            </BattleAction>
            
        </BattleActions>
    </BattleActionCollection>
    

    templewulf
  • rembrandtqeinsteinrembrandtqeinstein Registered User regular
    edited September 2018
    Garthor wrote: »
    Okay, I think this is the simplest way to do what you're looking for, full script, C#:
    using UnityEngine;
    
    [ExecuteInEditMode]
    public class orientCar : MonoBehaviour {
        // Update is called when something in the scene changes
        void Update () {
            // Rotate the car to point its Y axis towards the ray (0,0,1) through (0,0,0)
            // First get the target up vector, which is just the inverse of the position with the Z component zeroed out
            Vector3 newUp = new Vector3(-transform.position.x, -transform.position.y, 0);
    
            // Now, construct a rotation that will take us from our current orientation to our desired one
            Quaternion rot = new Quaternion();
            rot.SetFromToRotation(transform.up, newUp);
    
            // Apply the rotation.  Note that quaternion multiplication is not commutative, it must be done in this order
            transform.rotation = rot * transform.rotation;
        }
    }
    

    This executes in the editor so you can just slap it on something and see it working. It isn't 100% perfect (and it kind of fights the editor for control over the object... don't worry about it) but it should be a passable basis for what you're doing. Also I think you mentioned you wanted the Z axis fixed not the Y axis but I already made my little capsule car so that ship has sailed.

    The rotation appears to work, thank you very much. Lots of other stuff to do but at least im not stuck on this one thing. Let me know how you want your name to appear in the credits. What do you think of "Consulting Developer" as a title?

    rembrandtqeinstein on
  • templewulftemplewulf The Team Chump USARegistered User regular
    Rend wrote: »
    @templewulf
    Here you go! Again please excuse the awfulness of my consistency.
    <?xml version="1.0" encoding="utf-8" ?>
    <BattleActionCollection xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <BattleActions>
            <BattleAction>
                <name>Advancing Strike</name>
                <fighterClass>Soldier</fighterClass>
                <isStandardAction>true</isStandardAction> <!-- True if this should eat the standard action slot, as opposed to the move slot. -->
                <tooltip>Move one space and then attack with your weapon</tooltip>
    
                <TargetRequests>
                    <TargetRequest>
                        <targetLabel>destination</targetLabel>          <!-- Used as a dictionary key -->
                        <canTargetGround>true</canTargetGround>         <!-- True if a blank space is valid target -->
                        <canTargetAllies>false</canTargetAllies>        <!-- True if allies are valid target -->
                        <canTargetEnemies>false</canTargetEnemies>      <!-- True if enemies are valid target -->
                        <canTargetSelf>false</canTargetSelf>            <!-- True if the user is valid target -->
                        <canTargetOrigin>false</canTargetOrigin>        <!-- True if the space this target originates from is valid target -->
    
                        <usaActorWeaponRange>false</usaActorWeaponRange> <!-- True if the range of this target depends on actor weapon -->
                        <useActorStatRange>false</useActorStatRange>    <!-- True if the range of this target depends on actor attribute (move speed, etc) -->
                        <range>1</range>                                <!-- Default range -->
                        <minimumRange>1</minimumRange>                  <!-- Default minimum range -->
                        <isRangeWalkable>true</isRangeWalkable>         <!-- True if this target should use pathfinding for range testing, false for line of sight -->
                        <targetOriginLabel></targetOriginLabel>         <!-- Label of the target request this target originates from -->
                    </TargetRequest>
    
                    <TargetRequest>
                        <targetLabel>target</targetLabel>
                        <canTargetGround>false</canTargetGround>
                        <canTargetAllies>true</canTargetAllies>
                        <canTargetEnemies>true</canTargetEnemies>
                        <canTargetSelf>false</canTargetSelf>
                        <canTargetOrigin>false</canTargetOrigin>
    
                        <useActorWeaponRange>true</useActorWeaponRange>
                        <useActorStatRange>false</useActorStatRange>
                        <range>0</range>
                        <minimumRange>0</minimumRange>
    
                        <targetOriginLabel>destination</targetOriginLabel>
                    </TargetRequest>
                </TargetRequests>
    
                <!-- 2 providers are added to the collection prior to any processing -->
                <!--   -A target provider which returns the actor, ie: the piece using this action -->
                <!--   -A value provider which returns whether or not the actor's current tension is above a given threshold -->
    
                <ValuesBeforeTargeting>                                 <!-- Values which can or should be calculated prior to targeting -->
                    <Value xsi:type="EquipmentValueProvider">
                        <Name>MinDamage</Name>
                        <targetName>actor</targetName>
                        <equipmentType>MainHand</equipmentType>
                        <valueType>MinDamage</valueType>
                    </Value>
                    <Value xsi:type="EquipmentValueProvider">
                        <Name>MaxDamage</Name>
                        <targetName>actor</targetName>
                        <equipmentType>MainHand</equipmentType>
                        <valueType>MaxDamage</valueType>
                    </Value>
    
                    <Value xsi:type="EquipmentValueProvider">
                        <Name>TensionFactor</Name>
                        <targetName>actor</targetName>
                        <equipmentType>MainHand</equipmentType>
                        <valueType>TensionFactor</valueType>
                    </Value>
    
                    <Value xsi:type="ArithmeticValueProvider">
                        <Name>MinDamage</Name>
                        <InitialValue>%MinDamage</InitialValue>                 <!-- % indicates this value should be provided from the dictionary -->
                        <IsInt>true</IsInt>                                     <!-- True if floats should be truncated to ints -->
                        <Conditions>                                            <!-- Checks value dictionary for each key, only processes if all are 'true' -->
                            <Condition>overThreshold</Condition>                <!-- This Arithmetic will only process if the actor's tension is over the threshold -->
                        </Conditions>
                        <Expressions>
                            <Expression>Multiply %TensionFactor</Expression>
                        </Expressions>
                    </Value>
                    <Value xsi:type="ArithmeticValueProvider">
                        <Name>MaxDamage</Name>
                        <InitialValue>%MaxDamage</InitialValue>
                        <IsInt>true</IsInt>
                        <Conditions>
                            <Condition>overThreshold</Condition>
                        </Conditions>
                        <Expressions>
                            <Expression>Multiply %TensionFactor</Expression>
                        </Expressions>
                    </Value>
    
    
                    <Value xsi:type="EquipmentValueProvider">
                        <Name>AttackAttribute</Name>
                        <targetName>actor</targetName>
                        <equipmentType>MainHand</equipmentType>
                        <valueType>AttackAttribute</valueType>          <!-- The attribute the actor will use to deal damage -->
                    </Value>
                    <Value xsi:type="EquipmentValueProvider">
                        <Name>DefenseAttribute</Name>
                        <targetName>actor</targetName>
                        <equipmentType>MainHand</equipmentType>
                        <valueType>DefenseAttribute</valueType>         <!-- The attribute the target will use to mitigate damage -->
                    </Value>
                    <Value xsi:type="EquipmentValueProvider">
                        <Name>WeaponAccuracy</Name>
                        <targetName>actor</targetName>
                        <equipmentType>MainHand</equipmentType>
                        <valueType>Accuracy</valueType>
                    </Value>
                </ValuesBeforeTargeting>
    
                <ValuesAfterTargeting>
                    <Value xsi:type="RollToHitValueProvider">           <!-- Special single purpose value provider which will account for -->
                        <Name>toHit</Name>                              <!--   all accuracy related contingencies. -->
                        <ActorName>actor</ActorName>
                        <TargetName>target</TargetName>
                        <AccuracyModifier>%WeaponAccuracy</AccuracyModifier>
                    </Value>
                </ValuesAfterTargeting>
    
                <CutsceneCommands>
    
                    <CutsceneCommand xsi:type="CenterCameraBetweenCutsceneLoader">      <!-- Centers camera between two targets -->
                        <TargetingMethod>TargetProvider</TargetingMethod>
                        <FirstTargetName>actor</FirstTargetName>
                        <SecondTargetName>destination</SecondTargetName>
                        <Time>0.5</Time>
                    </CutsceneCommand>
    
                    <CutsceneCommand xsi:type="CutsceneWaitLoader">
                        <Time>0.25</Time>
                    </CutsceneCommand>
    
                    <CutsceneCommand xsi:type="MoveBoardPieceCutsceneLoader">           <!-- Moves a piece on the board logically -->
                        <TargetingMethod>TargetProvider</TargetingMethod>
                        <ActorName>actor</ActorName>
                        <DestinationProviderName>destination</DestinationProviderName>
                    </CutsceneCommand>
    
                    <CutsceneCommand xsi:type="MoveAlongPathCutsceneLoader">            <!-- Animates a piece moving in world space -->
                        <TargetingMethod>TargetProvider</TargetingMethod>
                        <ActorName>actor</ActorName>
                        <DestinationProviderName>destination</DestinationProviderName>
                    </CutsceneCommand>
    
                    <CutsceneCommand xsi:type="CenterCameraBetweenCutsceneLoader">
                        <TargetingMethod>TargetProvider</TargetingMethod>
                        <FirstTargetName>actor</FirstTargetName>
                        <SecondTargetName>target</SecondTargetName>
                        <Time>0.5</Time>
                    </CutsceneCommand>
    
                    <CutsceneCommand xsi:type="CutsceneWaitLoader">
                        <Time>0.25</Time>
                    </CutsceneCommand>
    
                    <CutsceneCommand xsi:type="DealDamageCutsceneLoader">               <!-- Actually deals the damage -->
                        <Conditions>
                            <Condition>toHit</Condition>                                <!-- Only process if this move hit -->
                        </Conditions>
                        <TargetingMethod>TargetProvider</TargetingMethod>               <!-- For other cutscenes, such as pre-programmed ones, -->
                        <ActorName>actor</ActorName>                                    <!--  the targeting method might use a unit's name etc. -->
                        <TargetName>target</TargetName>
                        <MinDamage>%MinDamage</MinDamage>
                        <MaxDamage>%MaxDamage</MaxDamage>
                        <AttackAttribute>%AttackAttribute</AttackAttribute>
                        <DefenseAttribute>%DefenseAttribute</DefenseAttribute>
                        <IgnoreArmor>false</IgnoreArmor>                                <!-- True if armor should not mitigate this damage -->
                        <IgnoreStats>false</IgnoreStats>                                <!-- True if attributes should not mitigate this damage -->
                        <ShowFloatingText>true</ShowFloatingText>                       <!-- True if floating text should display the damage dealt -->
                        <WaitForFloatingText>true</WaitForFloatingText>                 <!-- True if the cutscene should wait for the floating text to fade -->
                        <FloatingTextTime>2</FloatingTextTime>
                    </CutsceneCommand>
    
                    <CutsceneCommand xsi:type="CutsceneWaitLoader">
                        <Time>0.25</Time>
                    </CutsceneCommand>
    
                    <CutsceneCommand xsi:type="MoveCameraCutsceneLoader">
                        <TargetingMethod>TargetProvider</TargetingMethod>
                        <TargetName>actor</TargetName>
                        <Time>0.5</Time>
                    </CutsceneCommand>
    
                </CutsceneCommands>
    
            </BattleAction>
    
            <BattleAction>
                <name>Attack Rush</name>
                <fighterClass>Soldier</fighterClass>
                <isStandardAction>true</isStandardAction>
                <tooltip>Damage an opponent and knock them back one space</tooltip>
    
                <TargetRequests>
                    <TargetRequest>
                        <targetLabel>target</targetLabel>
                        <canTargetAllies>true</canTargetAllies>
                        <canTargetEnemies>true</canTargetEnemies>
                        <useActorWeaponRange>true</useActorWeaponRange>
                    </TargetRequest>
                    <TargetRequest>
                        <targetLabel>knockbackDestination</targetLabel>
                        <canTargetGround>true</canTargetGround>
                        <range>1</range>
                        <minimumRange>1</minimumRange>
                        <targetOriginLabel>target</targetOriginLabel>
                        <targetEpicenterLabel>actor</targetEpicenterLabel> <!-- Per my post earlier, epicenter is used for knockback and pull effects -->
                        <mustBeAwayFromEpicenter>true</mustBeAwayFromEpicenter> <!-- Only spaces which are further from actor than the target's current location are valid -->
                    </TargetRequest>
                </TargetRequests>
    
                <ValuesBeforeTargeting>
                    <Value xsi:type="EquipmentValueProvider">
                        <Name>MinDamage</Name>
                        <targetName>actor</targetName>
                        <equipmentType>MainHand</equipmentType>
                        <valueType>MinDamage</valueType>
                    </Value>
                    <Value xsi:type="EquipmentValueProvider">
                        <Name>MaxDamage</Name>
                        <targetName>actor</targetName>
                        <equipmentType>MainHand</equipmentType>
                        <valueType>MaxDamage</valueType>
                    </Value>
    
                    <Value xsi:type="EquipmentValueProvider">
                        <Name>TensionFactor</Name>
                        <targetName>actor</targetName>
                        <equipmentType>MainHand</equipmentType>
                        <valueType>TensionFactor</valueType>
                        <OnlyOverThreshold>true</OnlyOverThreshold>
                    </Value>
    
                    <Value xsi:type="ArithmeticValueProvider">
                        <Name>MinDamage</Name>
                        <InitialValue>%MinDamage</InitialValue>
                        <IsInt>true</IsInt>
                        <Conditions>
                            <Condition>overThreshold</Condition>
                        </Conditions>
                        <Expressions>
                            <Expression>Multiply %TensionFactor</Expression>
                        </Expressions>
                    </Value>
                    <Value xsi:type="ArithmeticValueProvider">
                        <Name>MaxDamage</Name>
                        <InitialValue>%MaxDamage</InitialValue>
                        <IsInt>true</IsInt>
                        <Conditions>
                            <Condition>overThreshold</Condition>
                        </Conditions>
                        <Expressions>
                            <Expression>Multiply %TensionFactor</Expression>
                        </Expressions>
                    </Value>
    
    
                    <Value xsi:type="EquipmentValueProvider">
                        <Name>AttackAttribute</Name>
                        <targetName>actor</targetName>
                        <equipmentType>MainHand</equipmentType>
                        <valueType>AttackAttribute</valueType>
                    </Value>
                    <Value xsi:type="EquipmentValueProvider">
                        <Name>DefenseAttribute</Name>
                        <targetName>actor</targetName>
                        <equipmentType>MainHand</equipmentType>
                        <valueType>DefenseAttribute</valueType>
                    </Value>
                    <Value xsi:type="EquipmentValueProvider">
                        <Name>WeaponAccuracy</Name>
                        <targetName>actor</targetName>
                        <equipmentType>MainHand</equipmentType>
                        <valueType>Accuracy</valueType>
                    </Value>
                </ValuesBeforeTargeting>
    
                <ValuesAfterTargeting>
                    <Value xsi:type="RollToHitValueProvider">
                        <Name>toHit</Name>
                        <ActorName>actor</ActorName>
                        <TargetName>target</TargetName>
                        <AccuracyModifier>%WeaponAccuracy</AccuracyModifier>
                    </Value>
                </ValuesAfterTargeting>
    
    
                <CutsceneCommands>
                    <CutsceneCommand xsi:type="CenterCameraBetweenCutsceneLoader">
                        <TargetingMethod>TargetProvider</TargetingMethod>
                        <FirstTargetName>actor</FirstTargetName>
                        <SecondTargetName>target</SecondTargetName>
                        <Time>0.5</Time>
                    </CutsceneCommand>
                    <CutsceneCommand xsi:type="CutsceneWaitLoader">
                        <Time>0.25</Time>
                    </CutsceneCommand>
                    <CutsceneCommand xsi:type="DealDamageCutsceneLoader">
                        <Conditions>
                            <Condition>toHit</Condition>
                        </Conditions>
                        <TargetingMethod>TargetProvider</TargetingMethod>
                        <ActorName>actor</ActorName>
                        <TargetName>target</TargetName>
                        <MinDamage>%MinDamage</MinDamage>
                        <MaxDamage>%MaxDamage</MaxDamage>
                        <AttackAttribute>%AttackAttribute</AttackAttribute>
                        <DefenseAttribute>%DefenseAttribute</DefenseAttribute>
                        <DealDamageAsTension>false</DealDamageAsTension>
                        <IgnoreArmor>false</IgnoreArmor>
                        <IgnoreStats>false</IgnoreStats>
                        <ShowFloatingText>true</ShowFloatingText>
                        <WaitForFloatingText>true</WaitForFloatingText>
                        <FloatingTextTime>2</FloatingTextTime>
                    </CutsceneCommand>
                    <CutsceneCommand xsi:type="MoveBoardPieceCutsceneLoader">
                        <Conditions>
                            <Condition>toHit</Condition>
                        </Conditions>
                        <TargetingMethod>TargetProvider</TargetingMethod>
                        <ActorName>target</ActorName>
                        <DestinationProviderName>knockbackDestination</DestinationProviderName>
                    </CutsceneCommand>
    
                    <CutsceneCommand xsi:type="MoveAlongPathCutsceneLoader">
                        <Conditions>
                            <Condition>toHit</Condition>
                        </Conditions>
                        <TargetingMethod>TargetProvider</TargetingMethod>
                        <ActorName>target</ActorName>
                        <DestinationProviderName>knockbackDestination</DestinationProviderName>
                    </CutsceneCommand>
                </CutsceneCommands>
                
            </BattleAction>
            
        </BattleActions>
    </BattleActionCollection>
    

    Wow, thanks for sharing!

    Did you build a separate tool to output these, or are you using some interface in Unity or GameMaker?

    Twitch.tv/FiercePunchStudios | PSN | Steam | Discord | SFV CFN: templewulf
  • RendRend Registered User regular
    For now they're handwritten, but one of the next things on the roadmap is a tool that will build and generate them for me.

    templewulf
  • bowenbowen How you doin'? Registered User regular
    edited September 2018
    Any reason for XML over JSON or YAML or something?

    You can serialize JSON directly into C# objects with newtonsoft's json stuff. Not sure if XML can do that (probably can).

    bowen on
    Ladies.
  • RendRend Registered User regular
    bowen wrote: »
    Any reason for XML over JSON or YAML or something?

    You can serialize JSON directly into C# objects with newtonsoft's json stuff. Not sure if XML can do that (probably can).

    The choice to go with xml over json is essentially 100% because I am very familiar with .NET's XML serialization and deserialization stuff. I actually prefer json as a human readable data format, but at least for now familiarity wins over for me. I can serialize and deserialize directly to and from c# objects, parse directly to enumerations, that kind of thing. There's basically nothing manual about my xml processing so it's pretty painless.

  • KupiKupi Registered User regular
    Never change a working system and all that, but I have to plug Newtonsoft.JSON again. It's one of the most painless serialization libraries I've ever used. And it's free!

    My favorite musical instrument is the air-raid siren.
    bowentemplewulfMadpoet
  • RendRend Registered User regular
    How's it do with enumerations? Auto parses names from and to strings etc?

  • KupiKupi Registered User regular
    By default, I think, it treats them as integers, but it's got all kinds of settings, and I know that one of them is "parse enums as strings". So, yes, it can map string names to enum values.

    My favorite musical instrument is the air-raid siren.
  • bowenbowen How you doin'? Registered User regular
    Yeah I'm pretty sure I've done all that at some point with it.

    Ladies.
  • KupiKupi Registered User regular
    I suppose it runs counter to my initial premise of "most painless serialization I've ever used", but while there are a few gotchas, they pretty much all emanate from forgetting to pass in your settings during de/serialization or not knowing the right attribute to stick on your classes/members. Nothing is without a learning curve. But "you need to annotate your code if you want a few more complicated behaviors" is a lower bar than some libraries I've seen.

    And, again, if the XML version is working as-is, keep it. XML minifies and compresses essentially as well as JSON.

    My favorite musical instrument is the air-raid siren.
    LD50
  • SurfpossumSurfpossum A nonentity trying to preserve the anonymity he so richly deserves.Registered User regular
    edited September 2018
    Khavall wrote: »


    Ok I've only been able to put some stolen hours every once in a while into this, but progress!


    It's super unbalanced right now, where I think sort of everything is overpowered? If you don't make mistakes, you win really easily, but if you do make mistakes, you lose really easily.

    I think the next step is adding an in-between bosses thing where you can actually tell what's happened after each boss, with progress pointed out, instead of the breakneck pace of just respawning immediately.
    @Khavall this idea seems really cool! You mentioned positioning in the first post, and I'm wondering: have you considered making things able to switch rows? I feel like it might be worth the added complexity since it would open up more things on the player side (eg DPS with an attack that can only hit adjacent, or moving the tank to the other side of the monster and taunting) and on the monster side (eg pulling characters to different rows, moving between them).
    Abilities could have specific ranges, like an AOE would be adjacent rows, ranged attacks would be a non-adjacent row, etc.

    That might all be along a completely different path from what you have in mind, but it's the first thing that my brain started churning upon seeing this.

    ...on a completely unrelated note, I tend to just get an idea for a thing and then puzzle at it for a few days to try and get it to work nicely. This is probably the first time where I've actually gotten the thing to work mostly like I imagined, so I've built and uploaded it. It's just a control test, and if you've got an XBox controller (which is what I've been designing for) the left and right sticks are two different modes.

    This little experiment was prompted by reading the dev log of Rain World and thinking about stuff crawling around a 2D surface. I didn't want to use Unity's built in physics stuff, so I started with checking for collisions and pretty quickly switched to raycasts. The raycasting was working all right up until I realized there were certain scenarios that would lead to some bad behavior (small gaps, spikes, etc.) unless I did a lot of looping through various sweeps checking for each situation. Because it amuses me, here are my notes from the situation:

    qtra042wcw8z.jpeg

    Then I decided to browse through the API and discovered CircleCast, which is exactly what I needed. So now it's much more well behaved, except if it's going fast enough it can "skip" over tight enough gaps instead of tracing the edges down (I haven't gotten around to tweaking this yet, but I think 1. it should be manageable and 2. maybe it's fine?).

    If I stick with this, I would eventually want to add the ability to "push" through the edges and switch to climbing along the front of the surfaces; the overarching idea being a squirrel based platformer.

    Anyway, there’s not really a point to this but I’m well chuffed and wanted to share.

    Surfpossum on
    icon.png facebookIcon.png tumblrIcon.png
    is this how nations are born
    Cornucopiistdipuc4life
  • CornucopiistCornucopiist Registered User regular
    Man, that CircleCast seems something I should've known about before a lot of wasted time...

    Surfpossum
  • SurfpossumSurfpossum A nonentity trying to preserve the anonymity he so richly deserves.Registered User regular
    It probably doesn't hurt to note that there is also BoxCast, SphereCast, CapsuleCast, etc.

    icon.png facebookIcon.png tumblrIcon.png
    is this how nations are born
    Cornucopiistdipuc4life
  • LD50LD50 Registered User regular
    BoxCast sounds like some sort of TV-streaming twitch competitor.

    ElvenshaeJacobydipuc4life
Sign In or Register to comment.