Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Convincingly simulating heartrate and respiration: coroutine?

Discussion in 'Scripting' started by Sendatsu_Yoshimitsu, Nov 5, 2014.

  1. Sendatsu_Yoshimitsu

    Sendatsu_Yoshimitsu

    Joined:
    May 19, 2014
    Posts:
    691
    For the medical component of my game, I'm working on a way to accurately model common vital tasks: making the heart beat, lungs breath, and so forth. I'm finding that a lot of organs have a very similar logic to their function: during normal exertion remain within a certain range, while under stress, slowly trend upwards to a maximum value, and when completely inactive, slowly trend downwards to a minimum value.

    Right now I'm trying to come up with a master function to handle this task for every organ, and the best solution I've come up with is to represent each vital statistic (heart bpm, blood O2, etc) as a float and use a coroutine that fires every tenth of a second or so, checks whether it should be trending up, trending down, or remaining consistent, and deducts a tiny amount from the statistic in question.

    However, this leaves me with two questions: first off, is this reasonable? I hate the idea of having a coroutine firing that often, even if it's only doing a few simple calculations.

    Second, for this to really feel realistic, the increase/decrease can't be smooth, it has to spike up and down: if I hold the sprint key for a second and then release it, heartrate should spike over the next 10-20 seconds, then settle down. Is there an obvious way to accomplish this? I have a vague notion of giving each organ an Exertion value, having any action that messages the organ to increase or decrease its output add to or subtract from that value, so every tick, if Exertion!=0, the organ transfers some of Exertion's value into the vital stat: negative exertion on the heart causes its bpm to fall, positive to rise, and when it hits 0 the organ slowly restores itself to its base rate. The problem there is that you could exploit the system unless there are tons of checks to keep you from hammering an action over and over to manipulate Exertion's value, and I'm not sure how to simply check against this without executing a tangled web of conditionals every tick.
     
  2. shaderop

    shaderop

    Joined:
    Nov 24, 2010
    Posts:
    942
    You could model an organ's activity as if it's the speed of a virtual object that only exists in your code. Exertion would correspond to a force applied to that object, mass would be how fast it responds to that stimulus, and the speed would be the activity level, e.g. the heat rate in the case of the heart. You can also add friction force to simulate the organ returning to idle activity levels.

    The heart rate (speed) would take a while to increase (accelerate) when it's under exertion (force). Once the activity ceases it would take a while for the object to return to normal level because the friction or drag force will take a while to decelerate it to zero.

    Though I must say that, unless you're making some hardcore medical simulation game, you're probably chasing the wrong kind of realism.

    HTH
     
  3. Sendatsu_Yoshimitsu

    Sendatsu_Yoshimitsu

    Joined:
    May 19, 2014
    Posts:
    691
    Holy cow, that sounds like an excellent idea- to be sure I understand, you're suggesting that I use speed as a sort of logical paradigm, correct? Not literally literally applying unity's physics to the class and translating the results from physics into the statistics my biology system understands? (Although that second thing sounds fairly neat if it worked.)

    My principal concern is, of course, fun, but a lot of my game involves fairly detailed manipulation of the human body, so the more detailed, predicable, and systematically consistent I can get my organ model, the more flexibility I have with how I sculpt gameplay as I go.
     
  4. shaderop

    shaderop

    Joined:
    Nov 24, 2010
    Posts:
    942
    Yes, that's exactly what I'm saying. The only Unity thing you would be using is Time.deltaTime. The rest is just variables and Newton's equations of motion.

    I guess you could use some kind of hidden or off-screen GameObjects along with Unity's built-in physics engine to simulate the thing, but that sounds like one giant overkill to me.
     
  5. Sendatsu_Yoshimitsu

    Sendatsu_Yoshimitsu

    Joined:
    May 19, 2014
    Posts:
    691
    Sorry for being dense, but my physics are pretty out of date, and wikipedia's article on newtonian mechanics is flying right over my head- is there a simple equation or two that I'm missing, or is this a matter of doing my homework and actually making a simple but complete virtual physics system?
     
  6. shaderop

    shaderop

    Joined:
    Nov 24, 2010
    Posts:
    942
    It's no where near a full physics system, but not quite a simple equation.

    You'll have to start with this:

    F = m * a

    Where F is force, m is mass, a is acceleration. You have two forces that can affect the body in you scenario, the force representing exertion (Fe) and the the force representing drag (Fd). So

    Fe + Fd = m * a

    Buy Fd itself is (approximately) a linear function of speed:

    Fe + k * s = m * a --- Equation 1

    Where s is speed and k is the friction constant.

    The other equation you need is the change of speed over time:

    s = s0 + dt * a --- Equation 2

    Where s0 is the speed at the previous frame (or at the last time you calculated the speed) and dt is the elapsed time since the last frame (or the last time you calculated the speed).

    One can use Equation 1 to calculate a in Equation 2, which would yield:

    s = s0 + dt * (Fe + k * s0) / m

    s0, dt, Fe, k, and m are all known. s0 was calculated from the previous frame, Fe should increase linearly with exertion, dt is given to you, and the rest are constants that you'll have to fiddle with until you're happy with the effect.

    That should do it. I should warn you that my hourly rate kicks in after after this reply :)

    Good luck.
     
    roojerry likes this.
  7. Sendatsu_Yoshimitsu

    Sendatsu_Yoshimitsu

    Joined:
    May 19, 2014
    Posts:
    691
    With the level of detail and patience you've shown, I'm amazed your hourly rate hasn't already kicked in- you've helped me solve something that's been plaguing me for a good month of development, and been kind enough to walk me through the math as well- thank you very much for the time :)
     
  8. Sendatsu_Yoshimitsu

    Sendatsu_Yoshimitsu

    Joined:
    May 19, 2014
    Posts:
    691
    Hmm, this might be an obvious question, but I should be assigning s0 to s immediately before or after I run the calculation, right? Because I'm executing the formula, then setting s0 to s's old value, but this results in the calculated speed climbing exponentially until it's too large to display.